为什么我不能在Socket.IO中保留当前房间?

时间:2016-08-16 16:57:45

标签: javascript node.js sockets express socket.io

我一直在使用socket.io几天,并遇到了这个问题。在我更新server.js中的currentRoom变量之后,套接字仍然引用第一个房间集,在这种情况下,默认房间是"一般。"

当套接字离开旧房间加入新房间时,发送的消息不会按预期发送到新房间,而是发送到旧房间,即使当前房间存储在变量中并且是用作定位插座房间的一种方法。

我的server.js:

const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const socketIo = require('socket.io');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackConfig = require('./webpack.config');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

app.use(express.static(__dirname + '/public'));
app.use(webpackDevMiddleware(webpack(webpackConfig)));
app.use(bodyParser.urlencoded({ extended: false }));

io.on('connection', socket => {
  var rooms = ['General'];
  var currentRoom;
  const defaultRoom = 'General';

  socket.join('General');
  currentRoom = "General";

  //socket.emit('setup', { rooms:rooms, currentRoom: currentRoom });

  socket.on('new room', room => {
    socket.leave(currentRoom)
    currentRoom = room;
    socket.join(currentRoom);
    socket.emit('new room', room);
    console.log("New room has been created called: " + currentRoom);
  })

  socket.on('message', body => {
    console.log("Sending message to current room: " + currentRoom);
    socket.to(currentRoom).emit('message', {
      body,
      from: socket.id.slice(8)
    })
  })
})

server.listen(3000);

在前端,我有这个反应组件 info.js

import React from 'react';
import io from 'socket.io-client';

import Room from './Room';
import RoomList from './RoomList';
import User from './User';
import UserList from './UserList';

export default class Info extends React.Component {
  constructor(){
    super();
    this.state = {
      users: [],
      rooms: [],
      currentRoom: ''
    }
  }

  componentDidMount(){
    this.socket = io('/');
    //set defaults for room list
    this.socket.on('setup', data => {
      this.setState({ rooms: [...this.state.rooms, data.rooms] });
      this.setState({ currentRoom: data.currentRoom });
    })
    this.socket.on('new room', room => {
      this.setState({ currentRoom: room });
    })
  }

  userSubmit = event => {
    const username = event.target.value
    if(event.keyCode === 13  && username){
      this.setState({ users: [...this.state.users, username] });
      this.socket.emit('new user', username)
      event.target.value = '';
    }
  }

  roomSubmit = event => {
    const room = event.target.value
    if(event.keyCode === 13  && room){
      this.setState({ rooms: [...this.state.rooms, room] });
      this.socket.emit('new room', room)
      event.target.value = '';
    }
  }

  render(){
    const rooms = this.state.rooms.map((room, index) => {
      return <li key={index}>{room}</li>
    })

    const users = this.state.users.map((user, index) => {
      return <li key={index}>{user}</li>
    })
    return(
      <div class="chat-info">
        <RoomList rooms={rooms}/>
        <Room roomSubmit={this.roomSubmit}/>

        <UserList users={users}/>
        <User userSubmit={this.userSubmit}/>
        <p>Current Room: {this.state.currentRoom}</p>
      </div>
    )
  }
}

当我通过“新房间”换房间时。事件,当前房间 更新,套接字似乎加入新房间;然而,当套接字然后使用&#39;消息&#39;要将消息发送到当前房间的事件,套接字的消息将被发送到默认房间&#39; General&#39;。为什么会这样?我是Socket.IO的新手,所以可能有一些显而易见的东西我没有看到。任何帮助,将不胜感激。干杯!

编辑:来自新房间和消息事件的服务器js中的console.log,我进入我的终端:

New room has been created called: new //new refers to the value of currentRoom
Sending message to current room: General //General refers to the value of currentRoom

这些终端消息是在我在客户端上创建了一个新房间并尝试在创建和加入新房间后发送消息之后发出的。正如你所看到的,我创建并加入了一个名为&#34; new&#34;的新房间,但是当我尝试向currentRoom发送消息时,该消息将被发送到&#34; General&# 34;室。

编辑#2:以下是我在server.js文件上运行的调试的日志。

      express:router dispatching GET /bundle.js +56ms
      express:router query  : /bundle.js +0ms
      express:router expressInit  : /bundle.js +1ms
      express:router serveStatic  : /bundle.js +0ms
      send stat "/Users/alexwerner/Desktop/development/Web Development/rooms.io/public/bundle.js" +0ms
      express:router webpackDevMiddleware  : /bundle.js +1ms
      engine intercepting request for path "/socket.io/" +149ms
      engine handling "GET" http request "/socket.io/?EIO=3&transport=polling&t=LQMogAC" +0ms
      engine handshaking client "wlJpbWQIxMnTHrEYAAAA" +2ms
      engine:socket sending packet "open" ({"sid":"wlJpbWQIxMnTHrEYAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000})
+1ms
      engine:polling setting request +1ms
      engine:socket flushing buffer to transport +0ms
      engine:polling writing "      �0{"sid":"wlJpbWQIxMnTHrEYAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000}"
+3ms
      engine:socket executing batch send callback +1ms
      socket.io:server incoming connection with id wlJpbWQIxMnTHrEYAAAA +0ms
      socket.io:client connecting to namespace / +1ms
      socket.io:namespace adding socket to nsp / +0ms
      socket.io:socket socket connected - writing packet +1ms
      socket.io:socket joining room /#wlJpbWQIxMnTHrEYAAAA +0ms
      socket.io:client writing packet {"type":0,"nsp":"/"} +0ms
      socket.io-parser encoding packet {"type":0,"nsp":"/"} +1ms
      socket.io-parser encoded {"type":0,"nsp":"/"} as 0 +0ms
      engine:socket sending packet "message" (0) +0ms
      socket.io:socket joining room General +1ms
      socket.io:socket joined room /#wlJpbWQIxMnTHrEYAAAA +0ms
      socket.io:socket joined room General +0ms
      engine intercepting request for path "/socket.io/" +1ms
      engine handling "GET" http request "/socket.io/?EIO=3&transport=polling&t=LQMogAJ" +0ms
      engine handshaking client "Mh_obCHm_rGKbN2NAAAB" +1ms
      engine:socket sending packet "open" ({"sid":"Mh_obCHm_rGKbN2NAAAB","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000})
+0ms
      engine:polling setting request +0ms
      engine:socket flushing buffer to transport +0ms
      engine:polling writing "      �0{"sid":"Mh_obCHm_rGKbN2NAAAB","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":60000}"
+1ms
      engine:socket executing batch send callback +0ms
      socket.io:server incoming connection with id Mh_obCHm_rGKbN2NAAAB +0ms
      socket.io:client connecting to namespace / +1ms
      socket.io:namespace adding socket to nsp / +0ms
      socket.io:socket socket connected - writing packet +0ms
      socket.io:socket joining room /#Mh_obCHm_rGKbN2NAAAB +0ms
      socket.io:client writing packet {"type":0,"nsp":"/"} +0ms
      socket.io-parser encoding packet {"type":0,"nsp":"/"} +0ms
      socket.io-parser encoded {"type":0,"nsp":"/"} as 0 +0ms
      engine:socket sending packet "message" (0) +1ms
      socket.io:socket joining room General +0ms
      socket.io:socket joined room /#Mh_obCHm_rGKbN2NAAAB +0ms
      socket.io:socket joined room General +0ms
      engine upgrading existing transport +40ms
      engine:socket might upgrade socket transport from "polling" to "websocket" +1ms
      engine intercepting request for path "/socket.io/" +4ms
      engine handling "GET" http request "/socket.io/?EIO=3&transport=polling&t=LQMogB2&sid=wlJpbWQIxMnTHrEYAAAA"
+0ms
      engine setting new request for existing client +0ms
      engine:polling setting request +0ms
      engine:socket flushing buffer to transport +0ms
      engine:polling writing "�40" +1ms
      engine:socket executing batch send callback +0ms
      engine intercepting request for path "/socket.io/" +0ms
      engine handling "GET" http request "/socket.io/?EIO=3&transport=polling&t=LQMogB4&sid=Mh_obCHm_rGKbN2NAAAB"
+0ms
      engine setting new request for existing client +0ms
      engine:polling setting request +0ms
      engine:socket flushing buffer to transport +0ms

请注意,正在创建两个套接字;但是,我一次只在一个浏览器上打开了应用程序。我不确定这是否是socket.io的工作原理,或者这可能是我的问题。

事件日志:

socket.io-parser decoded 2["new room","New Room"] as {"type":2,"nsp":"/","data":["new room","New Room"]} +0ms
  socket.io:socket got packet {"type":2,"nsp":"/","data":["new room","New Room"]} +0ms
  socket.io:socket emitting event ["new room","New Room"] +0ms
  socket.io:socket leave room General +0ms
  socket.io:socket joining room New Room +0ms
  socket.io:client writing packet {"type":2,"data":["new room","New Room"],"nsp":"/"} +0ms
  socket.io-parser encoding packet {"type":2,"data":["new room","New Room"],"nsp":"/"} +0ms
  socket.io-parser encoded {"type":2,"data":["new room","New Room"],"nsp":"/"} as 2["new room","New Room"] +0ms
  engine:socket sending packet "message" (2["new room","New Room"]) +0ms
  engine:socket flushing buffer to transport +0ms
  engine:ws writing "42["new room","New Room"]" +1ms
New room has been created called: New Room
  socket.io:socket left room General +0ms
  socket.io:socket joined room New Room +0ms
  engine:ws received "42["message","Test Post"]" +11s
  engine:socket packet +1ms
  socket.io-parser decoded 2["message","Test Post"] as {"type":2,"nsp":"/","data":["message","Test Post"]} +0ms
  socket.io:socket got packet {"type":2,"nsp":"/","data":["message","Test Post"]} +0ms
  socket.io:socket emitting event ["message","Test Post"] +0ms
Sending message to current room: General
  socket.io-parser encoding packet {"type":2,"data":["message",{"body":"Test Post","from":"aDw0sZU_XZAAAE"}],"nsp":"/"} +14.8m
  socket.io-parser encoded {"type":2,"data":["message",{"body":"Test Post","from":"aDw0sZU_XZAAAE"}],"nsp":"/"} as 2["message",{"body":"Test Post","from":"aDw0sZU_XZAAAE"}] +0ms
  socket.io:client writing packet ["2[\"message\",{\"body\":\"Test Post\",\"from\":\"aDw0sZU_XZAAAE\"}]"] +0ms
  engine:socket sending packet "message" (2["message",{"body":"Test Post","from":"aDw0sZU_XZAAAE"}]) +0ms
  engine:socket flushing buffer to transport +0ms
  engine:ws writing "42["message",{"body":"Test Post","from":"aDw0sZU_XZAAAE"}]" +0ms
  socket.io:client writing packet ["2[\"message\",{\"body\":\"Test Post\",\"from\":\"aDw0sZU_XZAAAE\"}]"] +1ms
  engine:socket sending packet "message" (2["message",{"body":"Test Post","from":"aDw0sZU_XZAAAE"}]) +0ms
  engine:socket flushing buffer to transport +0ms
  engine:ws writing "42["message",{"body":"Test Post","from":"aDw0sZU_XZAAAE"}]" +0ms
  engine:ws received "2" +4s
  engine:socket packet +0ms
  engine:socket got ping +0ms
  engine:socket sending packet "pong" (undefined) +0ms
  engine:socket flushing buffer to transport +0ms
  engine:ws writing "3" +0ms
  engine:ws received "2" +0ms
  engine:socket packet +1ms
  engine:socket got ping +0ms
  engine:socket sending packet "pong" (undefined) +0ms
  engine:socket flushing buffer to transport +0ms
  engine:ws writing "3" +0ms
  engine:ws received "2" +3s
  engine:socket packet +0ms
  engine:socket got ping +0ms
  engine:socket sending packet "pong" (undefined) +0ms
  engine:socket flushing buffer to transport +0ms
  engine:ws writing "3" +0ms
  engine:ws received "2" +1ms
  engine:socket packet +0ms
  engine:socket got ping +0ms
  engine:socket sending packet "pong" (undefined) +0ms
  engine:socket flushing buffer to transport +0ms

1 个答案:

答案 0 :(得分:1)

在意识到创建后有两个套接字后,我意识到我的问题就在那段代码中。结果我没有在我的反应项目中正确嵌套Socket.IO。我有一个组件在客户端上导入socket.io的多个实例。

(我在多个组件中都有这一行):

library(ggplot2) # devtools::install_github("hadley/ggplot2")

# your original data
df <- data.frame(x=1:4, y=c(6, 4, -2, -3))
gg <- ggplot(df, aes(x, y))
gg <- gg + geom_col(width=0.5)
gg <- gg + theme_bw()
gg

# your modified data
df <- data.frame(x=1:4, y=c(10, 8, 2, 1))
gg <- ggplot(df, aes(x=x, xend=x, y=-4, yend=y-4))
gg <- gg + geom_segment(size=10)
gg <- gg + theme_bw()
gg

如果在项目中多次使用该导入,则使用此导入会创建多个套接字。 (这是有道理的,不幸的是我花了这么长时间来抓住我的错误)。

如果在使用React框架时出现多个套接字有问题,该解决方案很容易实现。首先,删除组件上的socket.io导入,然后将语句移动到父组件。就我而言,这是我的布局组件。

<强> Layout.js

import io from 'socket.io-client';

现在import语句位于父组件中。您可以将套接字从父组件传递到任何子组件。如您所见,我将套接字传递给两个组件Chat和Info。

在这些子组件中,您可以像使用React中的任何其他类型的prop一样处理套接字。在我的示例中,当前,我将套接字变量设置为等于套接字prop (如我的componentDidMount函数中所示)。

Chat.js

import React from 'react';
import io from 'socket.io-client';

import Chat from './Chat/Chat';
import Info from './Info/Info';

const socket = io();

export default class Layout extends React.Component {
  render(){
    return(
      <div class="wrapper">
        <h1>Rooms.io!</h1>
        <Chat socket={socket}/>
        <Info socket={socket}/>
      </div>
    )
  }
}

感谢@ jfriend00的帮助;我希望读到这篇文章的人有一个美好的一天,永远不会忘记在React中正确嵌套他们的套接字。干杯!