2016-08-16 10 views
0

私は数日間socket.ioを試していましたが、この問題に遭遇しました。 server.jsのcurrentRoom変数を更新した後も、ソケットは最初のルームセットを参照しています。この場合、デフォルトルームは "General"です。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> 
    ) 
    } 
} 

を、現在の部屋に更新され、ソケットは新しい部屋に参加しているようです。ソケットが 'message'イベントを使用して現在のルームにメッセージを送信すると、ソケットのメッセージがデフォルトルーム 'General'に送信されます。なぜこれが起こるのですか?私は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 

これらの端末のメッセージが来て、新しい部屋を作成して参加した後にメッセージを送信しようとしました。ご覧のように、私は "new"と呼ばれる新しい部屋を作成して参加しましたが、現在currentRoomにメッセージを送信しようとすると、メッセージは代わりに "General"ルームに送られます。

編集#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 

作成される2つのソケットがあることに注意してください。しかし、私は一度に1つのブラウザでアプリケーションを開いただけです。私はこれが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 
+0

なぜそれが「一般」の部屋に送られると思いますか?あなたはその証拠がありますか?一度にたくさんの部屋にソケットをつなぐことができますので、最初に「一般」に参加してから新しい部屋に入ると、ソケットはまだ「一般」の部屋にあります。あなたはその部屋を「放置していない」ので、まだその部屋にいます。 – jfriend00

+0

@ jfriend00 - サーバファイルから取得したログを表示するようにコードを更新しました。また、新しい部屋を作成するときに現在の部屋から離れるようにソケットを設定しました。私は信じていますが、間違っている可能性があります。**メッセージ**イベントでは、メッセージが送信された時点でcurrentRoomの名前を私に伝えるログを送信するので、メッセージはGeneralルームに送信されます。新しいルームイベントでcurrentRoomが変更されると、メッセージイベントは引き続きソケットの接続時に設定されるデフォルトのGeneralルームを使用します。 –

+0

あなたのコードの 'currentRoom'はすべての単一ソケットで一意であることに気付いていますか?あなたのサーバ上には 'currentRoom'が1つだけではありませんが、すべての単一ソケットには独自の' currentRoom'変数があります。したがって、他のソケットが 'new room'を送信すると、その特定のソケットの' currentRoom'だけが変更されます。あなたは論理的に、それが 'socket.currentRoom'であるかのように、サーバ側のソケットオブジェクトのプロパティと考えることができます。したがって、ソケットが 'message'を送信すると、そのメッセージは送信ソケットの' currentRoom'に送られ、他のソケットセットが最後に 'currentRoom'に送られることはありません。 – jfriend00

答えて

1

作成時に二つのソケットがあった実現した後、私は私の問題は、コードのそのビットのどこかに座って実現。私の反応プロジェクトではSocket.IOを正しく入れ子にしていなかったことが分かります。私は、コンポーネントがクライアント上でsocket.ioをインポートしていた複数のインスタンスを持っていました。

(私は複数のコンポーネントでこのラインを持っていた):

import io from 'socket.io-client'; 

は、それがかつてのプロジェクトでより多く使用されている場合は、このインポートは複数のソケットを作成します使用してオンにします。 (それは理にかなっていて、私の間違いを捉えるにはとても時間がかかりました)。

Reactフレームワークを使用しているときに誰かが複数のソケットを作成するのに問題がある場合、そのソリューションは簡単に実装できます。まず、コンポーネントのsocket.ioインポートを削除し、ステートメントを親コンポーネントに移動します。私の場合、これは私のレイアウトコンポーネントでした。

Layout.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> 
    ) 
    } 
} 

今import文は、親コンポーネントであること。ソケットを親コンポーネントから子コンポーネントのいずれかに渡すことができます。ご覧のとおり、私はソケットを2つのコンポーネントChatとInfoに渡します。

これらの子コンポーネントでは、Reactの他の種類の小道具のようにソケットを扱うことができます。私の例では、現在、socket変数(ソケットの小道具、)を(私のcomponentDidMount関数に見られるように)設定します。

Chat.js

import React from 'react'; 

import Message from './Message'; 
import MessageList from './MessageList'; 

export default class Chat extends React.Component { 
    constructor(){ 
    super(); 
    this.state = { messages: [] }; 
    } 

    componentDidMount(){ 
    const socket = this.props.socket; 
    socket.on('message', message => { 
     this.setState({ messages: [...this.state.messages, message] }); 
    }) 
    } 

    handleSubmit = event => { 
    const socket = this.props.socket; 
    const body = event.target.value 
    if(event.keyCode === 13 && body){ 
     const message = { 
     body, 
     from: 'Me' 
     } 
     this.setState({ messages: [...this.state.messages, message] }); 
     socket.emit('message', body) 
     event.target.value = ''; 
    } 
    } 

    render(){ 
    const messages = this.state.messages.map((message, index) => { 
     return <li key={index}>{message.from}: {message.body}</li> 
    }) 
    return(
     <div class="chat"> 
     <MessageList messages={messages}/> 
     <Message handleSubmit={this.handleSubmit}/> 
     </div> 
    ) 
    } 
} 

助けを@ jfriend00のおかげ。私はこれを読んでいる誰もが素敵な一日を持ち、Reactでソケットを適切に入れ子にすることを忘れないことを願っています。乾杯!

関連する問題