Skip to content

Commit 93fb5cc

Browse files
authored
fix: handle subscribed called multiple times; remove redundant line (#489)
on multiple subscribe calls, we ignore if we do not need to act instead of raising an exception it also removes a line of code that was creating issues on channel removal: #488
1 parent 6a23986 commit 93fb5cc

File tree

4 files changed

+37
-10
lines changed

4 files changed

+37
-10
lines changed

src/RealtimeChannel.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ export default class RealtimeChannel {
134134
}[]
135135
} = {}
136136
timeout: number
137-
state = CHANNEL_STATES.closed
137+
state: CHANNEL_STATES = CHANNEL_STATES.closed
138138
joinedOnce = false
139139
joinPush: Push
140140
rejoinTimer: Timer
@@ -217,9 +217,7 @@ export default class RealtimeChannel {
217217
if (!this.socket.isConnected()) {
218218
this.socket.connect()
219219
}
220-
if (this.joinedOnce) {
221-
throw `tried to subscribe multiple times. 'subscribe' can only be called a single time per channel instance`
222-
} else {
220+
if (this.state == CHANNEL_STATES.closed) {
223221
const {
224222
config: { broadcast, presence, private: isPrivate },
225223
} = this.params

src/RealtimeClient.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@ export default class RealtimeClient {
282282
channel: RealtimeChannel
283283
): Promise<RealtimeRemoveChannelResponse> {
284284
const status = await channel.unsubscribe()
285-
this.channels = this.channels.filter((c) => c._joinRef !== channel._joinRef)
286285

287286
if (this.channels.length === 0) {
288287
this.disconnect()

test/channel.test.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,27 @@ describe('subscribe', () => {
138138
assert.ok(channel.joinedOnce)
139139
})
140140

141-
test('throws if attempting to join multiple times', () => {
141+
test('if attempting to join multiple times, ignores calls', () => {
142142
channel.subscribe()
143+
while (channel.state == CHANNEL_STATES.closed) clock.tick(100)
144+
const state = channel.state
143145

144-
assert.throws(
145-
() => channel.subscribe(),
146-
/tried to subscribe multiple times/
147-
)
146+
for (let i = 0; i < 10; i++) channel.subscribe()
147+
148+
assert.equal(channel.state, state)
148149
})
150+
test('if subscription closed and then subscribe, it will rejoin', () => {
151+
channel.subscribe()
152+
while (channel.state == CHANNEL_STATES.closed) clock.tick(100)
153+
154+
channel.unsubscribe()
155+
while ((channel.state as CHANNEL_STATES) !== CHANNEL_STATES.closed) {
156+
clock.tick(100)
157+
}
158+
channel.subscribe()
149159

160+
assert.equal(channel.state, CHANNEL_STATES.joining)
161+
})
150162
test('updates join push payload access token', () => {
151163
socket.accessTokenValue = 'token123'
152164

test/client.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,24 @@ describe('channel', () => {
283283
assert.ok(disconnectStub.called)
284284
})
285285

286+
test('does not remove other channels when removing one', async () => {
287+
const connectStub = sinon.stub(socket, 'connect')
288+
const disconnectStub = sinon.stub(socket, 'disconnect')
289+
const channel1 = socket.channel('chan1').subscribe()
290+
const channel2 = socket.channel('chan2').subscribe()
291+
292+
channel1.subscribe()
293+
channel2.subscribe()
294+
assert.equal(socket.getChannels().length, 2)
295+
assert.ok(connectStub.called)
296+
297+
await socket.removeChannel(channel1)
298+
299+
assert.equal(socket.getChannels().length, 1)
300+
assert.ok(!disconnectStub.called)
301+
assert.deepStrictEqual(socket.getChannels()[0], channel2)
302+
})
303+
286304
test('removes all channels', async () => {
287305
const disconnectStub = sinon.stub(socket, 'disconnect')
288306

0 commit comments

Comments
 (0)