@Model(className = "Comm", properties={})
final class Communication {
@Model(className = "Request", properties = {
@Property(name = "msg", type = MsgType.class),
@Property(name = "username", type = String.class),
@Property(name = "password", type = String.class),
@Property(name = "gameId", type = String.class),
@Property(name = "color", type = Color.class),
@Property(name = "from", type = String.class),
@Property(name = "to", type = String.class),
@Property(name = "observer", type = boolean.class),
})
static class RequestModel {
}
@Model(className = "Response", properties = {
@Property(name = "msg", type = MsgType.class),
@Property(name = "turn", type = Color.class),
@Property(name = "color", type = Color.class),
@Property(name = "gameId", type = String.class),
@Property(name = "status", type = String.class),
@Property(name = "moves", type = String.class, array = true),
@Property(name = "from", type = String.class),
@Property(name = "to", type = String.class),
})
static class ResponseModel {
}
enum MsgType {
CreateGame, QueryGames, SendMove, JoinGame, UpdateGame;
}
enum Color {
W, B;
}
}
And then it is just a matter of creating the communication end point. As
usual with @OnReceive annotation one starts
with defining the response handler:
@OnReceive(
data = Request.class,
url = "{url}",
method = "WebSocket",
onError = "anErrorHappened"
)
static void queryServer(Comm c, Response r) {
if (r == null) {
// connection stablished!
return;
}
// message arrived!
switch (r.getMsg()) {
case CreateGame: /* do something */ break;
case QueryGames: /* do something */ break;
case SendMove: /* do something */ break;
case JoinGame: /* do something */ break;
case UpdateGame: /* do something */ break;
}
}
static void anErrorHappened(Comm c, Exception t) {
if (t == null) {
// OK, connection has been closed
} else {
// handle the error t somehow
}
}
The WebSockets specification
usually defines what should happen onopen, onmessage, onclose and onerror.
All these messages are supported in the previous example as well:
null message
null exception
Comm class. One can use it to establish communication,
send messages and close the communication channel. Here are three methods
showing how to do it:
static void connect(Comm c) {
// open a websocket channel:
c.queryServer("ws://server/path", null);
// the method returns immediately and starts establishing the connection
// once that is finished either onopen or onerror type of
// message is delivered
}
static void sendMessage(Comm c, Request r) {
// sends the message to already openned websocket channel:
c.queryServer("ws://server/path", r);
}
static void disconnect(Comm c) {
// sending null again, closes the connection
c.queryServer("ws://server/path", null);
}
One cannot change the URL while a connection is open otherwise one
risks IllegalStateException runtime exceptions. To connect
to different web socket server, one needs to close the connection first and
only later open new one with different URL.
Enjoy WebSockets via @OnReceive!