【问题标题】:SocketIO Not Emitting an Action in ReactSocketIO 在 React 中没有发出动作
【发布时间】:2018-07-02 00:26:44
【问题描述】:

目标 我正在寻找大量用户登录游戏室,例如game/#####。当用户点击该 url 时,他们的用户对象被创建并共享到该房间中的任何其他用户查看的状态。

问题componentDidMount 中,我调用我的Socket api 函数并传入userObjroom 值。此信息会发送到 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 });
  }
...

回购 https://github.com/yuschick/horror-bingo

【问题讨论】:

    标签: javascript node.js reactjs socket.io


    【解决方案1】:

    我认为问题出在this.socket = io('http://localhost:8000');。这意味着您使用新套接字创建与服务器的另一个连接。因此,当您从服务器发出新事件时,组件中的套接字无法接收它,因为它具有不同的套接字。

    您可以export const socket = io.connect('http://localhost:8000');,将其导入您的组件并使用它socket.on ...

    如果您想向另一个连接的套接字发送事件,您可以使用socket.broadcast.emitio.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);
        });
    });
    

    【讨论】:

    • 这是有道理的,但似乎无法解决问题。在每个浏览器的状态下仍然只有一个用户。
    • @Yuschick 也许我还没有弄清楚你的问题。我试过了,前端可以接收服务器事件。当前端收到这些事件时,您可以尝试控制台记录一些东西吗?正如我提到的,在服务器中,如果您仍然使用socket.emit,则只有该套接字可以接收事件。所以如果一个玩家加入并且你想让其他玩家知道,你将不得不使用socket.broadcast.emit
    • @DarknessZX 嗨,你能看看我的问题吗?非常感谢任何可能的帮助。 stackoverflow.com/questions/65325432/…
    猜你喜欢
    • 2016-04-01
    • 1970-01-01
    • 2021-04-08
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2018-09-19
    • 2017-01-24
    相关资源
    最近更新 更多