我一直在擺弄socket.io幾天,遇到了這個問題。在我更新server.js中的currentRoom變量後,套接字仍然指向第一個房間集,在這種情況下,默認房間是「常規」。爲什麼我不能將當前房間保存在Socket.IO中?
當套接字離開其舊房間加入新房間時,發送的消息不會按照預期發送到新房間,而是發送到舊房間,即使當前房間存儲在變量中並且被用作定位插座的房間的手段。
我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>
)
}
}
當我改變通過 '新房間' 活動室,當前房間確實得到更新,並且插座似乎加入新房間;然而,當套接字使用「消息」事件向當前房間發送消息時,套接字的消息被髮送到默認房間「常規」。爲什麼會發生?我是Socket.IO的新手,所以有可能是我看不到的東西。任何幫助,將不勝感激。乾杯!
編輯:從執行console.log在從新的房間和消息事件服務器JS,我得到了我的終端:
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
這些終端的消息來,我已經創建了客戶端上的新房間後試圖在創建並加入新房間後發送消息。正如你所看到的,我已經創建並加入了一個簡稱爲「新」的新房間,但是當我嘗試向當前房間發送消息時,消息被髮送到「常規」房間。
編輯#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
你爲什麼認爲它被髮送到'General'房間?你有什麼證據?你是否意識到一個套接字可以同時連接到多個房間,所以當你首先加入'General',然後到一個新房間時,套接字仍然在'General'房間裏。你沒有離開那個房間,所以它仍然在那個房間裏。 – jfriend00
@ jfriend00 - 我更新了代碼以顯示我從服務器文件獲取的日誌,並且我還將套接字設置爲在創建新房間時離開當前房間。我相信,但可能是錯誤的,因爲在**消息**事件中,我發送了一條日誌,我相信告訴我當前消息發送時當前房間的名稱。當新房間事件下當前房間發生變化時,消息事件仍然使用在套接字連接時設置的默認常規房間。 –
你是否意識到在你的代碼中'currentRoom'對每一個套接字都是唯一的?你的服務器上不只有一個'currentRoom',但每個套接字都有自己的'currentRoom'變量?所以,如果其他套接字發送「新房間」,那隻會爲該特定套接字更改「currentRoom」。您可以邏輯上認爲它是服務器端套接字對象的屬性,就好像它是'socket.currentRoom'一樣。所以,當套接字發送'message'時,該消息將被髮送到發送套接字的'currentRoom',而不是最後一個其他套接字設置的'currentRoom'。 – jfriend00