问题
I am working on an online multiplayer cards against humanity game (React on the front, React router for redirecting, and Node in the back) I am trying to redirect all clients in a "lobby", or room, when one user in the lobby clicks "start", but right now only the user that clicks start is redirected.
The idea is somebody will set up a new game, which will have a unique pin, where after you create the game and select your avatar, others can use that pin the join the lobby (this part is working fine, the users in the lobby are updated in real time for all users), and only the person who created the game will get a "start" button to click to start the game once all the users have joined, which should redirect all the users in the lobby.
On the client side, in the Lobby component's constructor, I have
socket.on("start game", () => {
this.props.history.push(`/${this.props.match.params.pin}`);
});
And for the one user who has access to the start button, the following is triggered when it is clicked
socket.emit("start");
Which then goes to the backend
socket.on('start', () => {
socket.emit('start game');
})
But only the user who clicked start is being redirected, and I cant seem to figure this out.
This is my first time trying to implement sockets and I'm not so sure what I can be missing here
回答1:
All that's left for it to work is to broadcast this event to all sockets in the given namespace or room. Currently you're sending it only to the socket that emitted the "start" event. Here's one way to do it:
Client side:
const socket = io("lobby", { //Connecting to a namespace called "lobby"
transports: ["websocket"]
});
socket.on("start game", () => {
this.props.history.push(`/${this.props.match.params.pin}`);
});
//...
socket.emit("start");
Server side:
io.of("/lobby").on("connection", (socket) => {
socket.on("start", () => {
io.of("/lobby").emit("start game");
});
});
回答2:
The server needs to send a socket.io message to each user that you want to be redirected with the URL that they should be redirected to. Each client should have a listener for that socket.io message and when they get it, they set window.location
to that new URL to cause the redirect.
So, the server would send something like this to each client that should redirect:
socket.emit('redirectToNewGame', newGameURL);
where socket is the socket of each user that should redirect.
Then, each client would have code like this:
socket.on('redirectToNewGame', newGameURL => {
// redirect to new URL
window.location = newGameURL;
});
If the whole process is started by a user clicking a button in their own window, then that user sends a message to the server to initiate the whole process. When the server receives that message, it notifies the specific set of clients that should follow that redirect by sending a socket.io message to each of them.
How exactly your server keeps track of which clients are supposed to redirect to that URL is up to your design. On the server-side of socket.io, it is common to use rooms for that, but it can be done in your own code too. That's just part of your app design and how users rendezvous before this whole process.
回答3:
A few of the people who replied recommended that I use namespaces, which makes a ton of sense, and is what worked.
io.in(pin).emit("start game");
instead of simply
socket.emit('start game');
got it to work
来源:https://stackoverflow.com/questions/56672050/how-can-i-redirect-all-clients-to-another-page-with-socket-io