After spending ~2h on this I need to brush up on my debugging skills. I currently resort to good-old printf debugging. This is complicated by the fact that JSON.stringify does not work on Maps/Sets directly, so I used flatted. However this is no plain JSON output anymore.
All that I got is that roomInfo still contains invalid/old socket ids, even after disconnect has deleted them. Don't know why this is happening.
Thanks for digging into this @Stefan-Hanke. Yeah, I noticed the stale socket ID's in roomInfo as well. I'm not sure why that's happening either.
Given that this only happens for the authenticated example, I'm inclined to believe that it's something that has to do with the way it creates / joins games as opposed to a socket.io quirk that we're not accounting for. Hopefully I'll get some time later this week to dig further.
I can't quite explain it, but it looks like this is a problem with the used gameIDs here.
gameID is passed to the _App_ element which connects to the server.The following printf-debug-output is created by inserting three console.log statements in _sync_, _update_, and _disconnect_ in server.js that just write the gameID:
sync tic-tac-toe:gameID
sync tic-tac-toe:gameID
sync tic-tac-toe:d09809f7-827f-4b39-b582-42a86439864a
sync tic-tac-toe:d09809f7-827f-4b39-b582-42a86439864a
disconnect tic-tac-toe:d09809f7-827f-4b39-b582-42a86439864a
disconnect tic-tac-toe:d09809f7-827f-4b39-b582-42a86439864a
sync tic-tac-toe:gameID
(node:5504) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'playerID' of undefined
at Object.send (D:\Git\Stefan-Hanke\boardgame.io\src\server\transport\socketio.js:28:16)
at GameMaster.onSync (D:\Git\Stefan-Hanke\boardgame.io\src\master\master.js:132:23)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:5504) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside
ion without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:5504) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections th
d will terminate the Node.js process with a non-zero exit code.
sync tic-tac-toe:gameID
(node:5504) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'playerID' of undefined
at Object.send (D:\Git\Stefan-Hanke\boardgame.io\src\server\transport\socketio.js:28:16)
at GameMaster.onSync (D:\Git\Stefan-Hanke\boardgame.io\src\master\master.js:132:23)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:5504) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside
ion without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
sync tic-tac-toe:c655c12f-018e-4ad2-b11f-db5f7ec26a68
sync tic-tac-toe:c655c12f-018e-4ad2-b11f-db5f7ec26a68
It looks odd that on a _sync_, a roomClients Set is just created. Maybe that code should check that a game with that ID whas actually created using the API server.
The problem is that the authenticated example joins a game tic-tac-toe:gameID first, then creates a game through the game creation API and joins that after. The sockets in the meantime just move from one game to the next (there is no disconnect). This causes roomInfo to contain entries for the sockets in both games (and, clientInfo points to the new game, so we've effectively lost the pointer to the old game instance).
When you hit refresh, the example again joins tic-tac-toe:gameID (this time with new sockets). So, roomInfo now contains four entires (two new sockets and two old). The old sockets don't have entries in clientInfo anymore, which causes the error.
The fix is easy: https://github.com/google/boardgame.io/commit/5d6e23d3f56a1fd9ebdc8278e22ef34aae43e36f
Most helpful comment
The problem is that the authenticated example joins a game
tic-tac-toe:gameIDfirst, then creates a game through the game creation API and joins that after. The sockets in the meantime just move from one game to the next (there is no disconnect). This causesroomInfoto contain entries for the sockets in both games (and,clientInfopoints to the new game, so we've effectively lost the pointer to the old game instance).When you hit refresh, the example again joins
tic-tac-toe:gameID(this time with new sockets). So,roomInfonow contains four entires (two new sockets and two old). The old sockets don't have entries inclientInfoanymore, which causes the error.The fix is easy: https://github.com/google/boardgame.io/commit/5d6e23d3f56a1fd9ebdc8278e22ef34aae43e36f