Communicating `event.session.id` outside `webSocketEvent()`

EDIT: A solution has been found for this problem, and the finished project can be found here.

Enonic version: 7.5.0
OS: Ubuntu

Hi guys,

I’m building something really cool for Enonic Market, so please help me!

I’m doing a serverside XP-library that integrates with Turbo Streams (for more checkout this Full Stack Radio episode).


If I can get it working, we can do the following code serverside (e.g in a service triggered by AJAX):

turboLib.append({
  target: 'my-alert-wrapper-id', 
  content: '<div role="alert">Something went wrong</div>'
});

And a websocket will be used to send the markup to the fontend, and append it to the element with #my-alert-wrapper-id, and there is no need for any frontend JS-code!

This approach can potentially replace much frontend JS-code. Or just be a way to do websockets, without having to write any frontend JS-code.


Problem:

When I’m in a service (called by AJAX), how do I know which websocket (socketId) is connected to which users client webpage?

This is my code so far:

  1. Library code
  2. Default webservice

Here is what I have tried:

  1. In webSocketEvent() on type = open, store the socketId on the users session using lib-xp-session. The session is not available inside the websocket, so this is currently not possible.
  2. Use a shared object to create a map from sessionId to socketId. The sessionId can be passed in to webSocketEvent() trough event.data.
    Unfortionatly webSocketEvent() doesn’t share memory with http-services, so this map is not accessible outside webSocketEvent().

So how can I easily communicate the id of a socket belonging to a user outside webSocketEvent()?

1 Like

I might have found a workaround, by creating a group named the sessionId. That way I have a “handle” to every webpage the user has open, that has connected on this websocket-service-endpoint.

export function webSocketEvent(event: WebSocketEvent<WithSessionId>): void {
  if (event.type == 'open') {
    addToGroup(event.data.sessionId, event.session.id);
    addToGroup(DEFAULT_GROUP_ID, event.session.id);
  } else if (event.type == 'close') {
    removeFromGroup(event.data.sessionId, event.session.id);
    removeFromGroup(DEFAULT_GROUP_ID, event.session.id);
  }
}
1 Like

I got it working with the workaround above!

Great that you found a solution!

I don’t think you need to remove a closing session from a group, though. It is done for you automagically.

1 Like

Do you know if empty groups are removed “automagically” too? Because my new library creates a “short lived” group for every user that visits the page.

Yes that’s how it is implemented.