0

I'm using ws webSocket (can't use socket.io) and I'm a bit new to it. I know how it works, but don't fully get a couple of things.

  1. How can I authenticate using jwt? The docs say that using the upgrade event is the correct way to go about it, but when the client connected, the code in the upgrade function didn't run.

  2. What's the correct way to add an event type? In socket.io, one can listen using client.on('eventType', function). What's the webSocket ws equivalent?

  3. When and why would one use paths in webSocket ws?

Update

The update event doesn't get fired on my end. Here's the code I have:

File 1

const server = require('http').createServer(app);
require('./socket/socket')(server);

File 2

module.exports = function(server) {
    const WebSocket = require('ws');

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

    server.on('upgrade', function(request, socket, head) {
        console.log('Upgraded');

        wss.handleUpgrade(request, socket, head, function(ws) {
            wss.emit('connection', ws, request);
        });
    });

    wss.on('connection', function connection(ws) {
        ws.on('message', function incoming(message) {
            console.log('received: %s', message);
        });
    });
};
Jessica
  • 9,379
  • 14
  • 65
  • 136
  • webSocket does not have it's own messaging system - that's a feature that socket.io adds on top of webSocket. You send data packets and data packets arrive at the other end. If you want different message types, you have to back that into the data you send (such as sending JSON with a `msg` property that contains a msg name). – jfriend00 Jan 19 '20 at 05:45
  • @jfriend00 Would paths solve that issue, or are paths used for something else? – Jessica Jan 19 '20 at 05:47
  • Paths with a webSocket request allow you to have different types of webSocket connections to the same host that are handled by different code on the server - much like you have different paths for http requests. There is ONLY a path for a webSocket connection on the first connection. There's no path with individual packets so it's not a substitute for a msg name. You can also pass a query string with the initial connection to pass some data with it. So, you could pass an auth token in the queryString. – jfriend00 Jan 19 '20 at 05:47
  • @jfriend00 What is a real life use case of the paths? Why would it make sense to open a new connection when all you have to do is send a stream with a msg property? Also, how can I get the data when the client initially connects? And is that the recommended way of doing it? – Jessica Jan 19 '20 at 06:23
  • You may have two completely separate parts of code that use a webSocket for different things that have nothing in common and reside in separate modules and it's just more straightforward for each to have its own webSocket connection. And, they may be used by two completely separate types of clients. – jfriend00 Jan 19 '20 at 06:42
  • 1
    How to access the orignal URL when a webSocket client connects to your server is shown [here](https://www.npmjs.com/package/ws#multiple-servers-sharing-a-single-https-server) on your server's `upgrade` event used with the `ws` library. – jfriend00 Jan 19 '20 at 06:45
  • @jfriend00 Thanks!! Really appreciate the help!! Can you make these comments into an answer so that I can accept it? – Jessica Jan 19 '20 at 07:23
  • OK, I put that content into an answer. – jfriend00 Jan 19 '20 at 07:35

2 Answers2

1

How can I authenticate using jwt? The docs say that using the upgrade event is the correct way to go about it, but when the client connected, the code in the upgrade function didn't run.

Well, there are lots of different choices. You could pass a token as a query parameter of a custom header when first making the connection. You could require that the first data sent over the webSocket is a token and disconnect if such a token does not arrive soon and first. If the client was already authenticated and there's an http cookie that indicates that, you could examine that cookie upon websocket connection.

What's the correct way to add an event type? In socket.io, one can listen using client.on('eventType', function). What's the webSocket ws equivalent?

The socket.io message types (or event types as you call them) are something that socket.io adds on top of webSocket. The webSocket protocol itself does not have such a thing. You send a data packet and that data packet arrives at the other end. All data packets are of the same webSocket "type". If you want to identify your data packets as being a certain type of message, then you have to invent a way of doing that inside your data back. For example, if your data was JSON formatted, you could add a type: "someType" property to event message and then examine that property upon receipt (this is essentially what socket.io does although it does it outside of the socket.io payload).

When and why would one use paths in webSocket ws?

You may have two completely separate parts of code that use a webSocket for different things that have nothing in common and reside in separate modules and it's just more straightforward for each to have its own webSocket connection. And, they may be used by two completely separate types of clients.

How to access the orignal URL when a webSocket client connects to your server is shown here on your server's upgrade event used with the ws library.

You will note in that example that the upgrade event occurs on the http server, not on the websocket server instance.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
0
  1. ws provide auth examples. These work when a HTTP server first handle the auth requests. Then pass a HTTP upgrade request to ws rather than ws itself listening on a port. Note the noServer: true option they include in the setup:

    const wss = new WebSocket.Server({ clientTracking: false, noServer: true });
    

    The jwt component will be easier using koa or express in HTTP first then doing the upgrade in this way. Otherwise you would need to write a ws message handler to look for some token data and verify it.

  2. The message is the event in ws. You get to write anything more specific on top of the message event, which is a big reason to use socket.io that has done all that for you (including client callback functions, which are super helpful).

  3. Using a URI path in the ws:// or http upgrade request would usually be to connect to a separate ws context on the server side. A simple way to namespace or separate connection into discreet groups.

Matt
  • 68,711
  • 7
  • 155
  • 158
  • Just updated the question with the my code. The issue is that the upgrade event isn't getting called, while the connection, and message event does get called – Jessica Jan 19 '20 at 06:34