Add identifier to websocket

226 views Asked by At

I am using the Node.js ws library, to listen to events in user accounts on a 3rd party API. For each user, I open a websocket to listen to the events in the user's account.

Turns out, the 3rd-party API doesn't provide a userID for each event, so if I have 10 websocket connections to user-accounts, I cannot determine which account an event came from.

I have access to a unique userId prior to starting each of my connections.

Is there a way to append or wrap the websocket connection with the userId identifier, to each connection I make, such that when I receive an event, I can access the custom identifier, and subsequently know which user's account the event came from?

The code below is a mix of real code, and pseudocode (i.e customSocket)

const ws = new WebSocket('wss://thirdparty-api.com/accounts', {
  port: 8080,
});

ws.send(
    JSON.stringify({
      action: 'authenticate',
      data: {
        oauth_token: access_token,
      },
    })
  );
  // wrap and attach data here (pseudocode at top-level)
  customSocket.add({userId,
    ws.send(
      JSON.stringify({
        action: 'listen',
        data: {
          streams: ['action_updates'],
        },
      })
    )
  })

// listen for wrapper data here, pseudocode at top level
customSocket.emit((customData) {
  ws.on('message', function incoming(data) {
    console.log('incoming -> data', data.toString());
  })
    console.log('emit -> customData', customData);
})

Looking at the socket.io library, the namespace feature may solve for this, but I can't determine if that's true or not. Below is an example in their documentation:

// your application has multiple tenants so you want to dynamically create one namespace per tenant

const workspaces = io.of(/^\/\w+$/);

workspaces.on('connection', socket => {
  const workspace = socket.nsp;

  workspace.emit('hello');
});

// this middleware will be assigned to each namespace
workspaces.use((socket, next) => {
  // ensure the user has access to the workspace
  next();
});
1

There are 1 answers

0
SamYoungNY On

I found a solution to this which is fairly simple. First create a message handler function:

const eventHandler = (uid, msg) => {
  console.log(`${uid} did ${msg}`);
};

Then, when you create the websocket for the given user, wrap the .on event with the handler:

const createSocketForUser = (uid, eventHandler) => {
  const socket = new WebSocket(/* ... */);
  socket.onmessage = (msg) => {
    eventHandler(uid, msg)
  };
  return socket;
}