Interface WebSocket
What an application implements to serve a websocket route.
One instance per ROUTE, not per connection -- the same shape a @RestController
has. Everything that belongs to one client lives on the WebSocketSession
handed to each callback, so an endpoint can be stateless and a stateful one puts
its state in WebSocketSession.setAttachment(Object).
`@WebSocketMapping("/echo")`
public class Echo implements WebSocket {
public void onOpen(WebSocketSession session) { }
public void onText(WebSocketSession session, String message) throws Exception {
session.sendText(message);
}
public void onBinary(WebSocketSession session, byte\[\] message, int offset, int length)
throws Exception {
session.sendBinary(message, offset, length);
}
}
The build finds that and registers it. A server assembled by hand gets the same
thing through a callback rather than a setter -- see
Backend.WebSocketEndpoints -- because this runtime is asked for its
configuration while it starts and never reconfigured once it is running.
Threading is the part worth reading twice. A callback runs on the thread that
owns the connection -- a virtual thread where the server has them, a pool worker
otherwise -- and the server reads nothing more from that connection until the
callback returns. So an endpoint may block, and a slow endpoint slows down its
own client and nobody else's. What it must not do is assume it is alone: a
session may be sent to from another thread entirely (that is what makes
broadcast possible), and WebSocketSession is written to allow it.
The optional callbacks have empty defaults, so an endpoint overrides only what
it cares about. PING is answered automatically before onPing(WebSocketSession, byte[], int, int) is called;
an endpoint never has to write the PONG itself.
-
Method Summary
Modifier and TypeMethodDescriptiondefault String[]The subprotocols this endpoint speaks, best first, or null for none.voidonBinary(WebSocketSession session, byte[] message, int offset, int length) A whole binary message.default voidonClose(WebSocketSession session, int code, String reason) The connection is finished, for any reason, exactly once per session.default voidonError(WebSocketSession session, Exception error) Something went wrong: a protocol violation by the peer, an I/O failure, or an exception thrown by one of the callbacks above.voidonOpen(WebSocketSession session) The handshake is done and the 101 is on the wire.default voidonPing(WebSocketSession session, byte[] payload, int offset, int length) A PING arrived.default voidonPong(WebSocketSession session, byte[] payload, int offset, int length) A PONG arrived, answering aWebSocketSession.sendPing(byte[], int, int).voidonText(WebSocketSession session, String message) A whole text message, reassembled from however many frames carried it, and already validated as UTF-8.
-
Method Details
-
onOpen
The handshake is done and the 101 is on the wire. Sending here is allowed and reaches the client after the handshake, which is the earliest anything can.- Throws:
Exception
-
onText
A whole text message, reassembled from however many frames carried it, and already validated as UTF-8.- Throws:
Exception
-
onBinary
A whole binary message.
The array is the session's own reassembly buffer and is valid only until this call returns -- the same contract
HttpServer.Requestcarries, and for the same reason: it is what lets a 10MB message arrive without a copy. An endpoint that needs to keep the bytes copies the range it wants.- Throws:
Exception
-
onPing
default void onPing(WebSocketSession session, byte[] payload, int offset, int length) throws Exception A PING arrived. The PONG has already been sent. The payload is borrowed.- Throws:
Exception
-
onPong
default void onPong(WebSocketSession session, byte[] payload, int offset, int length) throws Exception A PONG arrived, answering aWebSocketSession.sendPing(byte[], int, int). Borrowed.- Throws:
Exception
-
onClose
The connection is finished, for any reason, exactly once per session.
codeis the close code, or 1006 when the connection dropped without one -- which is normal, not exceptional: a process killed mid-suite, a network that went away, a browser tab closed.reasonmay be empty and is never null. Sending from here does nothing; the socket is already going.- Throws:
Exception
-
onError
Something went wrong: a protocol violation by the peer, an I/O failure, or an exception thrown by one of the callbacks above.
Reported rather than thrown, because by the time a websocket fails there is nobody left to throw to -- the request that started it returned long ago.
onClose(WebSocketSession, int, String)still follows. -
getSubprotocols
The subprotocols this endpoint speaks, best first, or null for none.
The SERVER's order decides, not the client's. RFC 6455 leaves the choice open, and honouring the client's order would let a peer select a deprecated protocol over a current one simply by listing it first.
-