admin管理员组

文章数量:1244383

I am creating a node.js app and running a WebSocket using both a server.js file and a routes.js file. I am trying to use the routes.js file to send a message within a certain page and eventually going to target the socket message to specific websocket clients. For now I am having trouble getting the on("message") function to work.

From the server.js file:

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 ining(message){
                console.log("Ining message: %s", message);
            })
            ws.on('close', () => console.log('Client disconnected'));
})
        ;

From the routes.js file:

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');    
});

When I send a message, I see "Printing within routes.js" in the log, but I don't see the "Ining message" part from the server.js part. Why not?

PS Here is the scripts.js file from the page I am running:

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");
      }
    } 

I am creating a node.js app and running a WebSocket using both a server.js file and a routes.js file. I am trying to use the routes.js file to send a message within a certain page and eventually going to target the socket message to specific websocket clients. For now I am having trouble getting the on("message") function to work.

From the server.js file:

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 ining(message){
                console.log("Ining message: %s", message);
            })
            ws.on('close', () => console.log('Client disconnected'));
})
        ;

From the routes.js file:

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');    
});

When I send a message, I see "Printing within routes.js" in the log, but I don't see the "Ining message" part from the server.js part. Why not?

PS Here is the scripts.js file from the page I am running:

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");
      }
    } 
Share Improve this question edited Jun 1, 2018 at 22:12 garson asked Jun 1, 2018 at 21:29 garsongarson 1,6174 gold badges27 silver badges62 bronze badges 9
  • It looks like you're trying to use a websocket from two server files. Web sockets are for talking from client to server and server to client. Meaning from browser to server and vice versa. – ChevCast Commented Jun 1, 2018 at 21:43
  • I am trying to use it to talk client-server and then analyze that message serverside to broadcast a message server-clients. I can't figure out why the ws.on() in the server.js file is not being triggered. – garson Commented Jun 1, 2018 at 21:46
  • You can use websockets between two different servers if you want but you need to write code to make the client library connect to the server endpoint. What you're doing there is putting an on listener on the same socket you're calling .send on. – ChevCast Commented Jun 1, 2018 at 21:48
  • I don't think I want to use them between two different servers - I want all the websockets to be municating along the same "socket" if that makes any sense. – garson Commented Jun 1, 2018 at 21:50
  • When you loop through all the clients like you are and then send something you’re sending a message that a connected client socket could listen for. When you attach an on event handler to that same socket you’re listening for messages from that connected client. That handler will not fire for messages you try to send on that same socket. Only from messages sent from the client end of that socket. – ChevCast Commented Jun 1, 2018 at 22:03
 |  Show 4 more ments

1 Answer 1

Reset to default 10

I don't know if this is the package you're using but whatever one you're using will be similar. In the readme it goes over two examples:

Server Example

In the server example they create a web socket server:

const WebSocket = require('ws');

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

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

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

What this does is creates the listening socket server. It adds an event listener for message so when a client connects to the server that client can then send messages and that event handler will fire.

After that event listener it sends the string 'hello from the server!'. That send call will NOT fire the above event handler because this send call is happening on the server side of the socket. It is sending a message to be received on the client end of that socket.

Client Example (usually in browser)

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

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

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

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

This is a client script that connects to the socket server in the first example. It connects up and the 'connection' event will be raised on the socket server above. The socket server then calls ws.send('hello from the server!'); and our client script here sets up a listener for 'message' so it would fire and print out 'hello from the server!' to the browser console.

This client script also sets up an 'open' event handler which fires after a successful connection to the socket server. So it will fire and send 'hello from the client!' to the server. The server's handler for 'message' will fire and in the server's terminal you will see 'hello from the client!' print out.


In your example you're doing this from the server (your server side routes.js file)

wss.clients.forEach(function each(client) {
  if (client.readyState === WebSocket.OPEN) {
    client.send(data);
  }
});

What you're doing there is iterating over all connected clients that have successfully connected to the socket server and you're sending out a message to each one individually. This will still not fire the server-side on event handler for 'message' you set up on each socket when each one first connected. It will fire the handler on the client-side in the browser.


Edit based on your last ment above:

To do what you want you'd want something like this on the client:

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

Then on the server in the connection handler you'd want to set up a message handler like this:

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

You can make message be an object instead of a string so you can perform different actions based on properties on that object but for the sake of simplicity I just made the server broadcast any message it receives to the rest of the server.

Notice the if statement checking to make sure we don't re-broadcast the message back to the same client who sent it.

本文标签: javascriptWebsocket on(quotmessagequot) not workingStack Overflow