2017-07-25 60 views
0

我正在开发使用nodejs和socket.io的简单应用程序。 我创建了两个通道,并且我希望我的客户端在点击按钮时连接一个通道。问题是我不从服务器获取当点击按钮时,JS从客户端更改套接字名称空间

响应这是我的代码:

// SERVER端

var app = require('express')(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 

var nameSpaceWeek = io.of('/week'); 
var nameSpaceDay = io.of('/day'); 

app.get('/', function(req, res){ 
res.sendfile('MDC.html'); 
}); 

io.on('connection', function(socket){ 
    console.log("User = " + socket.id) 
}); 

nameSpaceDay.on('connection', function(socket){ 
    console.log('someone connected on namespace day'); 
    nameSpaceDay.emit('hiDay', 'Hello everyone on namespace day!'); 
}); 

nameSpaceWeek.on('connection', function(socket){ 
    console.log('someone connected on namespace week'); 
    nameSpaceDay.emit('hiWeek', 'Hello everyone on namespace week!'); 
}); 

http.listen(3000, function(){ 
    console.log('listening on localhost:3000'); 
}); 

//客户端

<!DOCTYPE html> 
<html> 
    <head><title>Hello world</title></head> 
    <script src="/socket.io/socket.io.js"></script> 
    <script> 
    var socket = io(); 

    function setDay(){ 
     console.log("setDay"); 
     socket = io.connect('/day'); 
     console.log(socket) 
    } 

socket.on('hiDay',function(data){ 
    console.log("hiDay") 
    console.log("data = ." + data + ".") 
    document.getElementById('message-container').innerHTML = 'Update day' 
    console.log("data = ." + data + ".") 
}); 

function setWeek(){ 
    console.log("setWeek"); 
    socket = io.connect('/week');   
    console.log(socket) 
} 

socket.on('hiWeek',function(data){ 
    console.log("hiWeek") 
    document.getElementById('message-container').innerHTML = 'Update Week' 
    //document.getElementById('message-container').innerHTML = data 
    console.log(data) 
}); 

</script> 
<body> 
    <div id="message-container"></div> 
    <div id="error-container"></div> 
    <button type="button" name="button" onclick="setWeek()">Week</button> 
    <button type="button" name="button" onclick="setDay()">Day</button> 
</body> 

在我的客户端中,我创建了两个按钮,当我点击一个按钮时,我想更改套接字名称空间

回答

1

当您拨打setDay()setWeek()时,您将创建一个全新的socket.io连接,从而覆盖您之前的socket变量。您拥有的socket.on( hiDay , ...)socket.on('hiWeek', ...)处理程序仅在您创建的第一个套接字上,而不在新创建的套接字上,因此您从不会看到这些消息。

要解决此问题,请在连接到该名称空间后,将这些消息处理程序仅添加到正确的套接字。

function setWeek() { 
    // close previous socket.io connection 
    socket.close(); 

    // make new connection to new namespace 
    console.log("setWeek"); 
    socket = io.connect('/week');   
    console.log(socket) 

    // add event handler for new socket 
    socket.on('hiWeek',function(data){ 
     console.log("hiWeek") 
     document.getElementById('message-container').innerHTML = 'Update Week' 
     console.log(data) 
    }); 
} 

然后,对setDay()函数做同样的事情。

而且,如此处所示,您可能希望在更改名称空间时断开上一个连接,因此您不必留下您不再使用的连接。


仅供参考,你也有一个错字,其中这样的:

nameSpaceDay.emit('hiWeek', 'Hello everyone on namespace week!'); 

应该是这样的:

nameSpaceWeek.emit('hiWeek', 'Hello everyone on namespace week!'); 

最后,测试和运行的代码是这样的:

<!DOCTYPE html> 
<html> 
    <head><title>Hello world</title></head> 
    <script src="/socket.io/socket.io.js"></script> 
    <script> 
    var socket = io(); 

    function setDay(){ 
     socket.close(); 

     console.log("setDay"); 
     socket = io.connect('/day'); 

     socket.on('hiDay',function(data){ 
      console.log("hiDay") 
      document.getElementById('message-container').innerHTML = 'Update day'; 
      console.log(data); 
     });  
    } 



    function setWeek() { 
     // close previous socket.io connection 
     socket.close(); 

     // make new connection to new namespace 
     console.log("setWeek"); 
     socket = io.connect('/week');   

     // add event handler for new socket 
     socket.on('hiWeek',function(data){ 
      console.log("hiWeek"); 
      document.getElementById('message-container').innerHTML = 'Update Week'; 
      console.log(data); 
     }); 
    } 

</script> 
<body> 
    <div id="message-container"></div> 
    <div id="error-container"></div> 
    <button type="button" name="button" onclick="setWeek()">Week</button> 
    <button type="button" name="button" onclick="setDay()">Day</button> 
</body> 

和服务器代码:

var app = require('express')(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 
var path = require('path'); 

var nameSpaceWeek = io.of('/week'); 
var nameSpaceDay = io.of('/day'); 

app.get('/', function(req, res){ 
    res.sendFile(path.join(__dirname, 'socket-io-namespace.html')); 
}); 

io.on('connection', function(socket){ 
    console.log("User = " + socket.id) 
}); 

nameSpaceDay.on('connection', function(socket){ 
    console.log('someone connected on namespace day'); 
    nameSpaceDay.emit('hiDay', 'Hello everyone on namespace day!'); 
}); 

nameSpaceWeek.on('connection', function(socket){ 
    console.log('someone connected on namespace week'); 
    nameSpaceWeek.emit('hiWeek', 'Hello everyone on namespace week!'); 
}); 

http.listen(3000, function(){ 
    console.log('listening on localhost:3000'); 
}); 
+0

我所做的更改,但它是相同的结果 –

+0

@baudic_j - 当我与所需的更改运行它,它只是对我很好。你显然没有正确地做出改变,或者我不清楚你应该做什么。 – jfriend00

+0

@baudic_j - 出于某种原因,'setDay()'方法工作正常,但'setWeek()'不是。我正在调查。 – jfriend00

0

如果创建connect(ns)函数,则可以在名称空间更改时重新构建套接字事件侦听器。下面应该工作:

 <script> 
      var connect = function (ns) { 
       return io.connect(ns, { 
        query: 'ns=' + ns, 
        resource: "socket.io" 
       }).on('hiWeek', function (data) { 
        console.log("hiWeek") 
        document.getElementById('message-container').innerHTML = 'Update Week' 
        //document.getElementById('message-container').innerHTML = data 
        console.log(data) 
       }).on('hiDay', function (data) { 
       console.log("hiDay") 
       console.log("data = ." + data + ".") 
       document.getElementById('message-container').innerHTML = 'Update day' 
       console.log("data = ." + data + ".") 
      }); 
      } 

      var socket = io(); 

      function setDay() { 
       console.log("setDay"); 
       socket = connect('/day'); 
       console.log(socket); 
      } 

      function setWeek() { 
       console.log("setWeek"); 
       socket = connect('/week');   
       console.log(socket); 
      } 


     </script> 
+0

在你的功能,套接字将自动连接'hiWeek'和'hiDay'? –

+0

虽然确实有'hiDay'和'hiWeek'的听众,它只会响应来自指定名称空间的事件。如果在服务器上存在像namespaceDay.emit('hiWeek',data)这样的不匹配项,它仍然会捕获事件 – Woodsy

+0

,但是如果将命名空间设置为/ week,则不会收到hiDay,因为它来自于其他命名空间服务器。 – Woodsy