Mahmud Adam
Mahmud Adam

Reputation: 3579

io.emit fails to emit to all clients

I am trying to implement a "leave game" feature in a simple socket.io game and I cannot figure out why io.emit notifies only the socket of the client leaving the game. Here is my socket.js code:

io.on("connection", sock => {

    sock.on('joinGame', name => {
       inc++
       if(name === 'guest') name = name + inc.toString()
       addToGame(inc, name) // adds player to a new Map()
       io.emit('joinedGame', name)   
    })

    sock.on('findPlayersInGame', () => {
       getAllPlayersInGame(io, threeOrMore)
     // check to see if the client is notified when a new user joins
       io.emit('newPlayerJoined', 'new player joined')
    })

    sock.on('leaveGame', name => {
       io.emit('leftGame', uniquePlayers)    
    })

On the client, I am handling the socket communication along with my state management in a MobX store. Here is my GameStore.js code:

export class GameStore {
constructor(aGame) {
    extendObservable(this, {
        players: [],
        game: aGame,
        menuVisibility: true,
        play: action((id, username) => {
            this.menuVisibility = false
            username === undefined ? this.game.setName("guest") : this.game.setName(username)

            // join game with given username
            sock.emit('joinGame', this.game.playerName)

            // after joining, if the username is 'guest' change name to unique guest name provided by server
            sock.on('joinedGame', name => {
                if(this.game.playerName === 'guest') this.game.setName(name)
                console.log(this.game.playerName + " joined the game")
            })
            // populate player list with all players in game room
            this.loadPlayers()
        }),
        quitGame: action(() => {
            //this.menuVisibility = true
            sock.emit('leaveGame', this.game.playerName)
            sock.on('leftGame', players => { // this should be logged to all clients
                console.log('updated player list', players)
                this.players = players
            })
        }),
        loadPlayers: action(() => {
            sock.emit('findPlayersInGame', this.game.playerName)
            sock.on('loadPlayers', players => {
                console.log('loading players...')
                this.players = players
            })
            sock.on('newPlayerJoined', player => {
                console.log(player)
            })
        })   
    })
  }
}

When I dispatch the quitGame action, the socket only emits to the client that is leaving the game. I need to update the player list in my store after someone leaves the game, but I cannot figure out why the other clients are not getting the message that someone left the game. io.emit seems to be working fine when a player joins a game.

Upvotes: 0

Views: 50

Answers (1)

jfriend00
jfriend00

Reputation: 707956

It looks like you don't register the leftGame message handler until this client leaves the game. Thus, none of the other clients who are still in the game yet have a handler for that message. They are probably receiving the message, but don't yet have a handler for it so you don't see it.

Move this code:

        sock.on('leftGame', players => { // this should be logged to all clients
            console.log('updated player list', players)
            this.players = players
        })

so that it registers the event handler when the client wants to start receiving these messages (likely at startup).

Upvotes: 1

Related Questions