Websocket on(“消息”)不起作用

gar*_*son 2 javascript websocket node.js

我正在创建一个 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'));
})
        ;
Run Code Online (Sandbox Code Playgroud)

从 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');    
});
Run Code Online (Sandbox Code Playgroud)

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

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");
      }
    } 
Run Code Online (Sandbox Code Playgroud)

Che*_*hev 5

我不知道是否是您正在使用的软件包,但无论您使用的是哪种软件包,都将是相似的。在自述文件中,它介绍了两个示例:

服务器示例

在服务器示例中,他们创建了一个 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!');
});
Run Code Online (Sandbox Code Playgroud)

这样做是创建侦听套接字服务器。它添加了一个事件侦听器,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);
});
Run Code Online (Sandbox Code Playgroud)

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

这个客户端脚本还设置了一个'open'事件处理程序,它在成功连接到套接字服务器后触发。所以它会触发并发'hello from the client!'送到服务器。服务器的处理程序 for'message'将触发并且在服务器的终端中您将看到'hello from the client!'打印输出。


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

wss.clients.forEach(function each(client) {
  if (client.readyState === WebSocket.OPEN) {
    client.send(data);
  }
});
Run Code Online (Sandbox Code Playgroud)

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


根据您上面的最后一条评论进行编辑:

要做你想做的事情,你会想要在客户端上做这样的事情:

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

然后在连接处理程序中的服务器上,您需要设置一个消息处理程序,如下所示:

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);
      }
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我的 `console.log("TEXT HERE")` 没有在 ws.on("message") 事件中被调用 (3认同)