Chapter 6. Endpoint Lifecycle, Sessions, Sending Messages

6.1. Endpoint Lifecycle

As mentioned before, the endpoint in Java API for WebSocket is represented either by instance of javax.websocket.Endpoint, or by class annotated with either javax.websocket.server.ServerEndpoint or javax.websocket.ClientEndpoint. Unless otherwise defined by developer provided configurator (defined in instance of javax.websocket.server.ServerEndpointConfig or javax.websocket.ClientEndpointConfig, Tyrus uses one endpoint instance per VM per connected peer. Therefore one endpoint instance typically handles connections from one peer.

6.2. javax.websocket.Session

The sequence of interactions between an endpoint instance and remote peer is in Java API for WebSocket modelled by javax.websocket.Session instance. This interaction starts by mandatory open notification, continues by 0 - n websocket messages and is finished by mandatory closing notification.

The javax.websocket.Session instance is passed by Tyrus to the user in the following methods for programmatic endpoints:

  • public void onOpen(Session session, EndpointConfig config)

  • public void onClose(Session session, CloseReason closeReason)

  • public void onError(Session session, Throwable thr)

The javax.websocket.Session instance is passed by Tyrus to the user in the methods annotated by following annotations for annotated endpoints:

  • method annotated with javax.websocket.OnOpen

  • method annotated with javax.websocket.OnMessage

  • method annotated with javax.websocket.OnClose

  • method annotated with javax.websocket.OnError

In each of the methods annotated with the preceeding annotations the user may use parameter of type javax.websocket.Session. In the following example the developer wants to send a message in the method annotated with javax.websocket.OnOpen. As we will demonstrate later, the developer needs the session instance to do so. According to Java API for WebSocket Session is one of the allowed parameters in methods annotated with javax.websocket.OnOpen. Once the annotated method gets called, Tyrus passes in the correct instance of javax.websocket.Session.

Example 6.1. Lifecycle echo sample

@ServerEndpoint("/echo")
public class EchoEndpoint {

    @OnOpen
    public void onOpen(Session session) throws IOException {
        session.getBasicRemote().sendText("onOpen");
    }

    @OnMessage
    public String echo(String message) {
        return message;
    }

    @OnError
    public void onError(Throwable t) {
        t.printStackTrace();
    }
}


6.3. Sending Messages

Generally there are two ways how to send message to the peer endpoint. First one is usable for annotated endpoints only. The user may send the message by returning the message content from the method annotated with javax.websocket.OnMessage. In the following example the message m is sent back to the remote endpoint.

Example 6.2. Sending message in @OnMessage

@OnMessage
public String echo(String m) {
    return m;                                                                                                                               
}


The other option how to send a message is to obtain the javax.websocket.RemoteEndpoint instance via the javax.websocket.Session instance. See the following example:

Example 6.3. Sending message via RemoteEndpoint.Basic instance

@OnMessage
public void echo(String message, Session session) {
    session.getBasicRemote().sendText(message);
}


6.4. RemoteEndpoint

The interface javax.websocket.RemoteEndpoint, part of Java API for WebSocket, is designed to represent the other end of the communication (related to the endpoint), so the developer uses it to send the message. There are two basic interfaces the user may use - javax.websocket.RemoteEndpoint$Basic and javax.websocket.RemoteEndpoint$Async.

6.4.1. javax.websocket.RemoteEndpoint.Basic

This representation of the peer of a web socket conversation is used to send synchronous messages. The point of completion of the send is defined when all the supplied data has been written to the underlying connection. The methods for sending messages on the javax.websocket.RemoteEndpoint$Basic block until this point of completion is reached, except for javax.websocket.RemoteEndpoint$Basic#getSendStream() and javax.websocket.RemoteEndpoint$Basic#getSendWriter() which present traditional blocking I/O streams to write messages. See the example "Sending message via RemoteEndpoint.Basic instance" to see how the whole text message is send. The following example demonstrates a method which sends the partial text method to the peer:

Example 6.4. Method for sending partial text message

public void sendPartialTextMessage(String message, Boolean isLast, Session session){
    try {
        session.getBasicRemote().sendText(message, isLast);
    } catch (IOException e) {
        e.printStackTrace();
    }
}


6.4.2. javax.websocket.RemoteEndpoint.Async

This representation of the peer of a web socket conversation has the ability to send messages asynchronously. The point of completion of the send is defined when all the supplied data has been written to the underlying connection. The completion handlers for the asynchronous methods are always called with a different thread from that which initiated the send.

Example 6.5. Sending mesage the async way using Future

public void sendWholeAsyncMessage(String message, Session session){
    Future<Void> future = session.getAsyncRemote().sendText(message);
}