1

I am using websockets to pass information about a resource from the server to the client. The websocket Endpoint uses a pathparam to identify the specific resource. For example:

@ServerEndpoint("/resources/{resource-id}/updates")

The Endpoint class has the following logic in its onOpen method:

@OnOpen
public void onOpen(@PathParam("resource-id")int resourceId, Session session) throws IOException {
     boolean resourceExists = checkIfResourceExists(resourceId);
     if (!resourceExists) {
         // what should I do here?
     }
}

When using AJAX long-polling, I'd send a 404 response if the resource doesn't exist. The client would then know not to try again. Is there an equivalent technique to use for websockets? My two thoughts are:

  1. Use the following code in the if (!resourceExists) block, above:

    session.close(new CloseReason(CUSTOM_NOT_FOUND_CODE, "Resource ID not found")); return;

    Where CUSTOM_NOT_FOUND_CODE is a CloseCode in the 4000-4999 range.

  2. Perform this logic somewhere in the ServerEndpointConfig.Configurator implementation for this Endpoint and return a 404 there before the connection upgrade occurs. This sounds like the best approach to me, but there doesn't appear to be any way to send a standard HTTP error response from the modifyHandshake method.

  3. Perform this logic in a Filter. The problem here, though, is if I load the resource in the filter, how do I pass it to the Endpoint? With an HTTP request, I can add a request attribute in a filter which is then available in the servlet. But there doesn't seem to be an easy way to achieve the same thing with websockets. I could, of course, load the resource again in the Endpoint class, but that's duplication of work.

I'm sure this must be a common scenario, so is there an accepted best-practice approach here?

daiscog
  • 11,441
  • 6
  • 50
  • 62
  • A WebSocket connection starts out as a regular HTTP request and gets upgraded to WebSocket if the server agrees to it. So, if a WebSocket tries to connect to a URL that does not exist, the correct solution would be to send a standard HTTP 404 response to fail the upgrade handshake. Or am I missing something? Is your WebSocket already connected and you are sending a command that the server would send a reply to? If that is the case, then you are implementing a custom protocol on top of WebSocket, so just send an error reply in your own format and leave the WebSocket connected for more commands. – Remy Lebeau Jun 02 '16 at 00:06
  • @RemyLebeau Yes, you are right: I want to be able to send a standard 404 *before* the upgrade request is completed. But there doesn't seem to be a way to do that using Java's websocket implementation as there's no way to hook into the request before it gets upgraded to a websocket without using a filter, but that has limitations, too (I'll update the question with the limitations of that approach). – daiscog Jun 02 '16 at 10:40

0 Answers0