DEV Community

loading...

How to reply to an anonymous user over Websockets

alexandrum profile image Alexandru Muntean ・2 min read

Hello everyone!

This is my first post here on dev.to and I made myself some courage to write it because I always wanted to have a blog or somewhere to share the things I learn.

So here we go.

A couple of weeks ago, I started looking a bit more deeply into the Spring Websocket and STOMP because I had 2 applications, a Server and a Client, which had to communicate in a way that the Client requests some data and the Server replies to that request.

I know it sounds very basic, but the challenge I had to face was replying from the Server to a so called anonymous user because the Client application is not a user per se. Anonymous user

So looking here and there on several websites, I found that I can make this particular case to be somehow similar to the one when you are using the users of the main application.

The idea is to make the anonymous user to be visible and the key is to create a particular sessionId for him when the handshake between the 2 applications is made:

public class CustomHandshakeHandler extends DefaultHandshakeHandler {
  // Custom class for storing principal
  @Override
  protected Principal determineUser(ServerHttpRequest request,
                                    WebSocketHandler wsHandler,
                                    Map<String, Object> attributes) {
    // Generate principal with UUID as name
    return new StompPrincipal(UUID.randomUUID().toString());
  }
}
Enter fullscreen mode Exit fullscreen mode

And I also extended the main java.security.Principal class into a StompPrincipal in order to have something custom for my case:

public class StompPrincipal implements Principal {

  private String name;

  public StompPrincipal(String name) {
    this.name = name;
  }

  @Override
  public String getName() {
    return name;
  }
}
Enter fullscreen mode Exit fullscreen mode

And that's pretty much it, now listening on some path like /tutorial-request and having as parameter an object of SimpMessageHeaderAccessor, I can retrieve the session information and reply direct to user that made the request:

  @Autowired
  private SimpMessagingTemplate messagingTemplate;

  @MessageMapping("/tutorial-request")
  public void handleRequest(SimpleRequest request, SimpMessageHeaderAccessor headerAccessor) {
    String sessionId = headerAccessor.getSessionId();
    log.info("Handling session with id {} receiving message {} from {}", sessionId, request.getText(), request.getFrom());
    SimpleResponse response = new SimpleResponse("Hello!");
    messagingTemplate.convertAndSendToUser(headerAccessor.getUser().getName(), "/queue/tutorial-request", response);
    log.info("Replied to {} with message {}", sessionId, response);
  }
Enter fullscreen mode Exit fullscreen mode

I skipped adding the SimpleRequest and SimpleResponse because these are just simple objects that can be found on the repository together with the entire code from above:

GitHub logo alexandrumm / spring-tutorials

Resources for Spring tutorials

Feel free to tell me your thoughts in the comments, I know I have a lot to learn and to improve in writing posts, I hope this is just the beginning of it and I would appreciate any suggestions, so please do so.

Happy coding!

Discussion (0)

pic
Editor guide