Websocket on(“message”)无法正常工作

时间:2018-06-01 21:29:06

标签: javascript node.js websocket

我正在创建一个node.js应用程序并使用server.js文件和routes.js文件运行WebSocket。我试图使用routes.js文件在某个页面内发送消息,并最终将套接字消息定位到特定的websocket客户端。目前我无法使用on(“message”)功能。

来自server.js文件:

require('./app/routes.js')(app, passport, wss); // load our routes and pass in our app and fully configured passport

wss.on('connection', function connection(ws, req) {
            console.log('Client connected');
            ws.on('message', function incoming(message){
                console.log("Incoming message: %s", message);
            })
            ws.on('close', () => console.log('Client disconnected'));
})
        ;

来自routes.js文件:

app.post('/allbooks', function(

req,res)
{
    wss.clients.forEach((client) => {
    var arrayToSend = JSON.stringify([req.body.bookid, [], req.body.userSays]);
        console.log("Printing within routes.js");
        console.log(arrayToSend);
        client.send(arrayToSend);
    });
    res.redirect('/allbooks');    
});

当我发送消息时,我在日志中看到“在routes.js中打印”,但是我没有在server.js部分看到“Incoming message”部分。为什么不?

PS这是我正在运行的页面中的scripts.js文件:

var HOST = location.origin.replace(/^http/, 'ws')
  var ws = new WebSocket(HOST);
  ws.onmessage = function (event) {
    eventJSON = JSON.parse(event.data);
      if ($("#"+eventJSON[0]+"-request").length > 0){
        $("#"+eventJSON[0]+"-request").html("Message sent");
      }
    } 

1 个答案:

答案 0 :(得分:2)

我不知道this是否是您正在使用的软件包,但您使用的软件包类似。在自述文件中,它有两个例子:

服务器示例

在服务器示例中,他们创建了一个Web套接字服务器:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('hello from the server!');
});

这样做会创建侦听套接字服务器。它为message添加了一个事件监听器,因此当客户端连接到服务器时,客户端就可以发送消息,并且事件处理程序将触发。

在该事件监听器之后,它发送字符串'hello from the server!'。该发送调用不会触发上述事件处理程序,因为此发送调用发生在套接字的服务器端。它正在该套接字的客户端发送要接收的消息。

客户端示例(通常在浏览器中)

const WebSocket = require('ws'); // omit this line if including ws via <script> tag

const ws = new WebSocket('ws://www.host.com/path');

ws.on('open', function open() {
  ws.send('hello from the client!');
});

ws.on('message', function incoming(data) {
  console.log(data);
});

这是在第一个示例中连接到套接字服务器的客户端脚本。它连接起来,'connection'事件将在上面的套接字服务器上引发。套接字服务器然后调用ws.send('hello from the server!');,我们的客户端脚本在这里为'message'设置一个监听器,因此它将触发并打印出'hello from the server!'到浏览器控制台。

此客户端脚本还设置一个'open'事件处理程序,该事件处理程序在成功连接到套接字服务器后触发。因此它将触发并将'hello from the client!'发送到服务器。将激活'message'的服务器处理程序,在服务器的终端中,您将看到'hello from the client!'打印出来。

在您的示例中,您是从服务器(您的服务器端routes.js文件)

执行此操作
wss.clients.forEach(function each(client) {
  if (client.readyState === WebSocket.OPEN) {
    client.send(data);
  }
});

您正在做的是迭代已成功连接到套接字服务器的所有已连接客户端,并且您将单独向每个客​​户端发送一条消息。当每个套接字首次连接时,这仍将触发您在每个套接字上设置的on的服务器端'message'事件处理程序。它将在浏览器中触发客户端的处理程序。

根据您上次的评论编辑:

要做你想做的事,你需要在客户端上这样的东西:

myButton.onClick = function (e) {
  ws.send("Hey everyone! I'm Chev!");
};

然后在连接处理程序的服务器上,你想要设置一个这样的消息处理程序:

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    wss.clients.forEach(function each(client) {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(message);
      }
    });
  });
});

您可以将message作为对象而不是字符串,这样您就可以根据该对象的属性执行不同的操作,但为了简单起见,我只是让服务器广播它收到的任何消息给其余的服务器。

注意if语句检查以确保我们不会将消息重新广播回发送它的同一客户端。