diff --git a/packages/realtime_client/lib/src/realtime_client.dart b/packages/realtime_client/lib/src/realtime_client.dart index f2c1bfcf1..5df3fa8d3 100644 --- a/packages/realtime_client/lib/src/realtime_client.dart +++ b/packages/realtime_client/lib/src/realtime_client.dart @@ -459,9 +459,13 @@ class RealtimeClient { bool get isConnected => connectionState == SocketState.open; /// Removes a subscription from the socket. + /// + /// Matches on identity rather than on [RealtimeChannel.joinRef], which is + /// the empty string until a channel is subscribed and is therefore shared + /// by every channel that has not joined yet. @internal void remove(RealtimeChannel channel) { - channels = channels.where((c) => c.joinRef != channel.joinRef).toList(); + channels = channels.where((c) => !identical(c, channel)).toList(); if (channels.isEmpty) { log('transport', 'no channels remaining, scheduling disconnect'); _schedulePendingDisconnect(); diff --git a/packages/realtime_client/test/socket_test.dart b/packages/realtime_client/test/socket_test.dart index 29afc8b57..174711eb0 100644 --- a/packages/realtime_client/test/socket_test.dart +++ b/packages/realtime_client/test/socket_test.dart @@ -613,6 +613,32 @@ void main() { final foundChannel = mockedSocket.channels[0]; expect(foundChannel, channel2); }); + + test('keeps the other channels when none of them have joined', () { + // Channels that have never subscribed all share the empty join ref, so + // matching on it removed every one of them at once. + final socket = RealtimeClient(socketEndpoint); + final channel1 = socket.channel('topic-1'); + socket.channel('topic-2'); + socket.channel('topic-3'); + + socket.remove(channel1); + + expect( + socket.channels.map((channel) => channel.topic), + ['realtime:topic-2', 'realtime:topic-3'], + ); + }); + + test('removes only the given channel when topics are duplicated', () { + final socket = RealtimeClient(socketEndpoint); + final channel1 = socket.channel('topic'); + final channel2 = socket.channel('topic'); + + socket.remove(channel1); + + expect(socket.channels, [channel2]); + }); }); group('deferred disconnect', () {