简体   繁体   中英

Socket.io - Cannot emit to a specific room but can emit to everyone

I am using Socket.io 2.0.4 and React.js (CRA)

Background: In my server code (server.js) once someone sucessfully joins a room I want to emit an event that tells all clients in that room that someone joined.

Problem: I don't get an error but nothing get's transmitted to my client if I try to use .to(room) or .in(room) in conjuction with .emit ... but .emit will work on it's own.

What Works: I am successfully able to implement to the socket.join() code and in the callback I console.log the IDs of each person that's joined using the showClients function I created. I can see each person join one at a time via console.

Notes: I store the room name in the data variable and access it using data.room but I've also just wrote in the room name manually to no avail.

Client Code (abridged)

import React, {Component} from 'react';
import Card from '../card/card';
import './game.css';

const io = require('socket.io-client');
const socket = io()  

class Game extends Component {

    constructor(props){
        super();
    }

componentDidMount(){
        this.gameCode();
        this.cardSelected();

        socket.on("cardDiscarded", this.updateDiscard);

        socket.on("playerJoined", () => {
            alert("hi!");
            console.log("YAY!!!!!!!!!!!!!!!!!!!!");
        });
    }
   //....rest of my code....
}

Server Code (abridged)

Look at the joinRoom function to see the issue

const express = require('express');

const app = express();
const port = process.env.PORT || 5000;

const http = require("http").Server(app);
var io = require("socket.io")(http);

var bodyParser = require('body-parser');

console.log("Hello world!");

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));

io.on("connection", (socket) => {

    socket.on("createNewRoom", (name) =>{
        CreateNewRoom();
        console.log("NEW ROOM CREATED!");
    })

    socket.on("joinRoomRequest", (name, room) =>{
        // console.log(name, room);
        console.log("Request to join room");
        var data = {
            name: name,
            room: room
        };
        joinRoom(data);
    })


    function CreateNewRoom() {
        //Get unique room number
        var thisGameId = (Math.random() * 1000000 ) | 0;

        //Send the room number to the browser
        socket.emit('newRoomCreated', {roomID: thisGameId, mySocketID: socket.id});
        //Tell socket.io this user is joining this room
        socket.join(thisGameId.toString());
        console.log(thisGameId);
    };

    function joinRoom(data){
        console.log("trying to join room:" + data.room);
        data.socketID = socket.id;
        console.log(data);
        socket.join(data.room, () => {
            let rooms = Object.keys(socket.rooms);
            //Let the clients know a player has joined
            console.log(rooms);
            console.log(data.name + " JOINED room " + data.room);
            showClients(data.room);
            io.to(data.room).emit("playerJoined");  //<----- DOESN't WORK
        });
    }

    function showClients(room){
        var roomClients = io.of('/').in(room).clients((err, data)=>{
            if (err) throw err;
            console.log("The people in room ", room, " are: ", data);
        })
    }
})

I believe io.in(room).emit(data) is what you are looking for. I recently ran into this problem as well. According to the documentation, if you want to emit to everyone accept 'socket' (aka the user who joined) you use socket.to(room).emit . If you want to emit to everyone including the user, you use io.in(room).emit

I managed to solve it like this:

does not work:

socket.join (my_room)

work:

socket.join (my_room.toString ())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM