Backend API. Server-side code: this runs in a Codename One backend, not in the app on the device.
public 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.
`@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 is called;
an endpoint never has to write the PONG itself.
Methods
Method details
onOpen
public abstract void onOpen(WebSocketSession session)
throws ExceptionThrows
onText
public abstract void onText(WebSocketSession session, String message)
throws ExceptionThrows
onBinary
public abstract void onBinary(WebSocketSession session, byte[] message, int offset, int length)
throws ExceptionA whole binary message.
The array is the session’s own reassembly buffer and is valid only until
this call returns – the same contract HttpServer.Request carries, 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
onPing
public default void onPing(WebSocketSession session, byte[] payload, int offset, int length)
throws ExceptionThrows
onPong
public default void onPong(WebSocketSession session, byte[] payload, int offset, int length)
throws ExceptionWebSocketSession.sendPing. Borrowed.Throws
onClose
public default void onClose(WebSocketSession session, int code, String reason)
throws ExceptionThe connection is finished, for any reason, exactly once per session.
code is 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. reason may be empty and is never null.
Sending from here does nothing; the socket is already going.
Throws
onError
public default void onError(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.
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 still follows.
getSubprotocols
public default String[] 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.