0

I am using Jetty's WebSocket API to stream data to a client. Once the client connects to the server, the server will send json data periodically to the client.

@WebSocket
public class WSHandler {

    // send data every 10 seconds
    public static final long PERIOD = 10000L;

    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {

    }

    @OnWebSocketError
    public void onError(Throwable t) {

    }

    @OnWebSocketConnect
    public void onConnect(Session session) {
        System.out.println("Connect: " + session.getRemoteAddress().getAddress());
        try {

            while(...) {

                session.getRemote().sendString(json);

                Thread.sleep(PERIOD);

            }


        } catch (IOException | InterruptedException e ) {
            e.printStackTrace();
        }
    }

    @OnWebSocketMessage
    public void onMessage(String message) {

    }
}

What I want to do is once the client decides to terminate the connection, the server would stop sending the json data (it does stop, but it looks like not gracefully, throwing EOFException, IOException or broken pipe or something on the server side).

I already did try using a global boolean variable that turns false in onClose and placing that on while loop, but that does not seem to work.

What should I put on onConnect method's while loop to terminate the sending of data without throwing Exceptions?

oikonomiyaki
  • 7,691
  • 15
  • 62
  • 101

1 Answers1

1

Your code never lets the main Parse / Event Handling thread process anything else.

You never return from onConnect, which is mandatory.

Spin off a new thread to send those messages. That will allow the subsequent incoming frames from the remote to be processed by the implementation.

The session will become invalid when the close is detected. Either from a valid close handshake, or from an abnormal close, or from a harsh close.

You can also use while(session.isOpen()) { } as an added guard, but keep in mind that it ALSO requires the ability to process more incoming frames.

Joakim Erdfelt
  • 46,896
  • 7
  • 86
  • 136
  • Thanks. I think I have option of going (1) multi-threaded or (2) Non-blocking. Can you give an example in both cases? – oikonomiyaki Sep 17 '15 at 02:46
  • The implementation is multi-threaded already. You just chose to never return the processing thread back to the implementation. Hence the implementation can't process anything anymore. The implementation does NOT dispatch to a new thread when calling normal events, it only dispatches for Streaming message events (part of the JSR356 implementation) – Joakim Erdfelt Sep 17 '15 at 03:06
  • Sorry, I don't understand if your stating what (wrong) I have done or what should I be doing (right). Can you please clarify what should be and what's not? – oikonomiyaki Sep 18 '15 at 03:13
  • Imagine this. The thread that reads from the network, and then parses the websocket frames, is the same one that called your endpoints `.onConnect()`, you never returned from it, you just went into an infinite loop in it. That loop prevented the reading of the network and parsing of frames. Don't do that. spawn/spin off a new thread to handle your write loop. – Joakim Erdfelt Sep 18 '15 at 03:58