目标
我正在寻找许多用户登录游戏室,例如game/#####
。当用户点击该URL时,会创建其用户对象并将其共享给该房间中任何其他用户查看的状态。
问题
在componentDidMount
中,我调用了我的Socket api函数并传入userObj
和room
值。此信息使其成为api函数,然后是服务器侦听器。但是,当服务器发出join room
事件时,前端似乎听不到它并通过用新用户更新state.game.users
对象来响应。
守则
server.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(8000);
io.on('connection', function (socket) {
socket.on('join room', (userObj, room) => {
socket.join(room).emit('join room', userObj);
});
socket.on('join chat', (msgObj, room) => {
socket.in(room).emit('join chat', msgObj);
});
socket.on('chat message', (msgObj, room) => {
socket.in(room).emit('chat message', msgObj);
});
});
api.js
import io from 'socket.io-client';
const socket = io.connect('http://localhost:8000');
export const joinRoom = (userObj, room) => {
socket.emit('join room', userObj, room);
}
export const joinChat = (msgObj, room) => {
socket.emit('join chat', msgObj, room);
}
export const chatMessage = (msgObj, room) => {
socket.emit('chat message', msgObj, room);
}
组件
import { joinRoom, joinChat, chatMessage } from './../../api';
class GameBoard extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
game: {
id: props.match.params.gameid,
users: {},
messages: []
}
};
this.socket = io('http://localhost:8000');
this.postUsername = this.postUsername.bind(this);
this.getBoardValues = this.getBoardValues.bind(this);
this.buildUserData = this.buildUserData.bind(this);
}
componentDidMount() {
this.socket.on('join room', (userObj) => {
this.postUser(userObj);
});
this.socket.on('join chat', (msgObj) => {
this.postMessage(msgObj);
});
this.socket.on('chat message', (msgObj) => {
this.postMessage(msgObj);
});
this.socket.on('connect', () => {
joinRoom(this.buildUserData(), this.state.game.id);
});
}
postUser(userObj) {
const game = this.state.game;
game.users[userObj.id] = userObj;
this.setState({ game });
}
...
答案 0 :(得分:0)
我认为问题出在this.socket = io('http://localhost:8000');
。这意味着您使用新套接字创建与服务器的另一个连接。因此,当您从服务器发出新事件时,组件中的套接字无法接收它,因为它具有不同的套接字。
您可以export const socket = io.connect('http://localhost:8000');
将其导入您的组件并使用socket.on ...
如果您想将事件发送到另一个连接的套接字,可以使用socket.broadcast.emit
或io.emit
。您可以在此处查看备忘单https://socket.io/docs/emit-cheatsheet/。例如:
io.on('connection', function (socket) {
socket.on('join room', (userObj, room) => {
socket.join(room).emit('join room', userObj); \\<-- this will only let the socket from front end which emit 'join room' receive event
socket.broadcast.to(room).emit(`join room', userObj); \\<-- this will let all socket from front end(in the same room) receive 'join room' event except the one which emit.
});
socket.on('join chat', (msgObj, room) => {
socket.in(room).emit('join chat', msgObj);
});
socket.on('chat message', (msgObj, room) => {
socket.in(room).emit('chat message', msgObj);
});
});