@@ -55,21 +55,32 @@ public function subscribe(ConnectionInterface $connection, stdClass $payload)
5555 ]));
5656 });
5757
58- $ memberAddedPayload = [
59- 'event ' => 'pusher_internal:member_added ' ,
60- 'channel ' => $ this ->getName (),
61- 'data ' => $ payload ->channel_data ,
62- ];
63-
64- $ this ->broadcastToEveryoneExcept (
65- (object ) $ memberAddedPayload , $ connection ->socketId ,
66- $ connection ->app ->id
67- );
58+ // The `pusher_internal:member_added` event is triggered when a user joins a channel.
59+ // It's quite possible that a user can have multiple connections to the same channel
60+ // (for example by having multiple browser tabs open)
61+ // and in this case the events will only be triggered when the first tab is opened.
62+ $ this ->channelManager
63+ ->getMemberSockets ($ user ->user_id , $ connection ->app ->id , $ this ->getName ())
64+ ->then (function ($ sockets ) use ($ payload , $ connection ) {
65+ if (count ($ sockets ) === 1 ) {
66+ $ memberAddedPayload = [
67+ 'event ' => 'pusher_internal:member_added ' ,
68+ 'channel ' => $ this ->getName (),
69+ 'data ' => $ payload ->channel_data ,
70+ ];
71+
72+ $ this ->broadcastToEveryoneExcept (
73+ (object ) $ memberAddedPayload , $ connection ->socketId ,
74+ $ connection ->app ->id
75+ );
76+ }
6877
69- DashboardLogger::log ($ connection ->app ->id , DashboardLogger::TYPE_SUBSCRIBED , [
70- 'socketId ' => $ connection ->socketId ,
71- 'channel ' => $ this ->getName (),
72- ]);
78+ DashboardLogger::log ($ connection ->app ->id , DashboardLogger::TYPE_SUBSCRIBED , [
79+ 'socketId ' => $ connection ->socketId ,
80+ 'channel ' => $ this ->getName (),
81+ 'duplicate-connection ' => count ($ sockets ) > 1 ,
82+ ]);
83+ });
7384 }
7485
7586 /**
@@ -95,18 +106,28 @@ public function unsubscribe(ConnectionInterface $connection)
95106 $ connection , $ user , $ this ->getName ()
96107 );
97108
98- $ memberRemovedPayload = [
99- 'event ' => 'pusher_internal:member_removed ' ,
100- 'channel ' => $ this ->getName (),
101- 'data ' => json_encode ([
102- 'user_id ' => $ user ->user_id ,
103- ]),
104- ];
105-
106- $ this ->broadcastToEveryoneExcept (
107- (object ) $ memberRemovedPayload , $ connection ->socketId ,
108- $ connection ->app ->id
109- );
109+ // The `pusher_internal:member_removed` is triggered when a user leaves a channel.
110+ // It's quite possible that a user can have multiple connections to the same channel
111+ // (for example by having multiple browser tabs open)
112+ // and in this case the events will only be triggered when the last one is closed.
113+ $ this ->channelManager
114+ ->getMemberSockets ($ user ->user_id , $ connection ->app ->id , $ this ->getName ())
115+ ->then (function ($ sockets ) use ($ connection , $ user ) {
116+ if (count ($ sockets ) === 0 ) {
117+ $ memberRemovedPayload = [
118+ 'event ' => 'pusher_internal:member_removed ' ,
119+ 'channel ' => $ this ->getName (),
120+ 'data ' => json_encode ([
121+ 'user_id ' => $ user ->user_id ,
122+ ]),
123+ ];
124+
125+ $ this ->broadcastToEveryoneExcept (
126+ (object ) $ memberRemovedPayload , $ connection ->socketId ,
127+ $ connection ->app ->id
128+ );
129+ }
130+ });
110131 });
111132 }
112133}
0 commit comments