Documenting how to use WebSockets
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 12 Sep 2013 16:10:02 +0200
changeset 291d89de2d41d52
parent 290 9e183e36a0a7
child 292 3cf46366e418
Documenting how to use WebSockets
json/src/main/java/net/java/html/json/OnReceive.java
json/src/main/java/net/java/html/json/doc-files/websockets.html
     1.1 --- a/json/src/main/java/net/java/html/json/OnReceive.java	Thu Sep 12 14:40:29 2013 +0200
     1.2 +++ b/json/src/main/java/net/java/html/json/OnReceive.java	Thu Sep 12 16:10:02 2013 +0200
     1.3 @@ -67,9 +67,13 @@
     1.4   * </pre>
     1.5   * When the server returns <code>{ "firstName" : "John", "lastName" : "Smith" }</code>
     1.6   * the browser will show alert message <em>Adding John Smith!</em>.
     1.7 + * <p>
     1.8 + * One can use this method to communicate with the server
     1.9 + * via <a href="doc-files/websockets.html">WebSocket</a> protocol since version 0.6.
    1.10 + * Read the <a href="doc-files/websockets.html">tutorial</a> to see how.
    1.11   * 
    1.12   * @author Jaroslav Tulach <jtulach@netbeans.org>
    1.13 - * @since 0.6
    1.14 + * @since 0.5
    1.15   */
    1.16  @Retention(RetentionPolicy.SOURCE)
    1.17  @Target(ElementType.METHOD)
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/json/src/main/java/net/java/html/json/doc-files/websockets.html	Thu Sep 12 16:10:02 2013 +0200
     2.3 @@ -0,0 +1,141 @@
     2.4 +<!DOCTYPE html>
     2.5 +<html>
     2.6 +    <head>
     2.7 +        <title>WebSockets via @OnReceive</title>
     2.8 +        <meta charset="UTF-8">
     2.9 +        <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">
    2.10 +    </head>
    2.11 +    <body>
    2.12 +        <h1>Using <a href="../OnReceive.html">@OnReceive</a> to Communicate 
    2.13 +            via WebSockets Protocol</h1>
    2.14 +        
    2.15 +        There is a simple, yet flexible way to communicate with a server
    2.16 +        via <a href="http://www.w3.org/TR/websockets/">WebSockets protocol</a>.
    2.17 +        The support can transfer any classes generated by
    2.18 +        <a href="../Model.html">@Model</a> annotation and reuses already 
    2.19 +        existing <a href="../OnReceive.html">@OnReceive</a> infrastructure -
    2.20 +        just defines detailed special behavior, which is described here.
    2.21 +        
    2.22 +        <h3>Define JSON Class</h3>
    2.23 +        
    2.24 +        The first step in using <em>WebSockets</em> is to create a model classes
    2.25 +        to encapsulate communiation with the server. For example one for
    2.26 +        sending requests and one for receiving replies:
    2.27 +    <pre>
    2.28 +    <a href="../Model.html">@Model</a>(className = "Comm", properties={})
    2.29 +    <b>final class</b> Communication {
    2.30 +        <a href="../Model.html">@Model</a>(className = "Request", properties = {
    2.31 +            <a href="../Property.html">@Property</a>(name = "msg", type = MsgType<b>.class</b>),
    2.32 +            <a href="../Property.html">@Property</a>(name = "username", type = String<b>.class</b>),
    2.33 +            <a href="../Property.html">@Property</a>(name = "password", type = String<b>.class</b>),
    2.34 +            <a href="../Property.html">@Property</a>(name = "gameId", type = String<b>.class</b>),
    2.35 +            <a href="../Property.html">@Property</a>(name = "color", type = Color<b>.class</b>),
    2.36 +            <a href="../Property.html">@Property</a>(name = "from", type = String<b>.class</b>),
    2.37 +            <a href="../Property.html">@Property</a>(name = "to", type = String<b>.class</b>),
    2.38 +            <a href="../Property.html">@Property</a>(name = "observer", type = boolean<b>.class</b>),
    2.39 +        })
    2.40 +        <b>static class</b> <em>RequestModel</em> {
    2.41 +        }
    2.42 +
    2.43 +        <a href="../Model.html">@Model</a>(className = "Response", properties = {
    2.44 +            <a href="../Property.html">@Property</a>(name = "msg", type = MsgType<b>.class</b>),
    2.45 +            <a href="../Property.html">@Property</a>(name = "turn", type = Color<b>.class</b>),
    2.46 +            <a href="../Property.html">@Property</a>(name = "color", type = Color<b>.class</b>),
    2.47 +            <a href="../Property.html">@Property</a>(name = "gameId", type = String<b>.class</b>),
    2.48 +            <a href="../Property.html">@Property</a>(name = "status", type = String<b>.class</b>),
    2.49 +            <a href="../Property.html">@Property</a>(name = "moves", type = String<b>.class</b>, array = <b>true</b>),
    2.50 +            <a href="../Property.html">@Property</a>(name = "from", type = String<b>.class</b>),
    2.51 +            <a href="../Property.html">@Property</a>(name = "to", type = String<b>.class</b>),
    2.52 +        })
    2.53 +        <b>static class</b> <em>ResponseModel</em> {
    2.54 +        }
    2.55 +
    2.56 +        <b>enum</b> <em>MsgType</em> {
    2.57 +            CreateGame, QueryGames, SendMove, JoinGame, UpdateGame;
    2.58 +        }
    2.59 +        <b>enum</b> <em>Color</em> {
    2.60 +            W, B;
    2.61 +        }
    2.62 +    }            
    2.63 +    </pre>
    2.64 +And then it is just a matter of creating the communication end point. As
    2.65 +usual with <a href="../OnReceive.html">@OnReceive</a> annotation one starts
    2.66 +with defining the response handler:
    2.67 +    <pre>
    2.68 +    <a href="../OnReceive.html">@OnReceive</a>(
    2.69 +        data = <em>Request</em>.<b>class</b>, 
    2.70 +        url = "{url}", 
    2.71 +        method = <em>"WebSocket"</em>, 
    2.72 +        onError = "anErrorHappened"
    2.73 +    ) 
    2.74 +    <b>static void</b> queryServer(Comm c, Response r) {
    2.75 +        <b>if</b> (r == null) {
    2.76 +            // <em>connection stablished!</em>
    2.77 +            <b>return</b>;
    2.78 +        }
    2.79 +        // <em>message arrived!</em>
    2.80 +        <b>switch</b> (r.getMsg()) {
    2.81 +            <b>case</b> CreateGame: /* do something */ <b>break</b>;
    2.82 +            <b>case</b> QueryGames: /* do something */ <b>break</b>;
    2.83 +            <b>case</b> SendMove: /* do something */ <b>break</b>;
    2.84 +            <b>case</b> JoinGame: /* do something */ <b>break</b>;
    2.85 +            <b>case</b> UpdateGame: /* do something */ <b>break</b>;
    2.86 +        }
    2.87 +    }
    2.88 +    <b>static void</b> anErrorHappened(Comm c, Exception t) {
    2.89 +        if (t == null) {
    2.90 +            // <em>OK, connection has been closed</em>
    2.91 +        } else {
    2.92 +            // <em>handle the error t somehow</em>
    2.93 +        }
    2.94 +    }
    2.95 +    </pre>
    2.96 +    The <a href="http://www.w3.org/TR/websockets/">WebSockets</a> specification
    2.97 +    usually defines what should happen <em>onopen, onmessage, onclose and onerror</em>.
    2.98 +    All these messages are supported in the previous example as well:
    2.99 +    <ul>
   2.100 +        <li><b>onopen</b> - the <em>queryServer</em> method is called with 
   2.101 +            <code>null</code> message
   2.102 +        </li>
   2.103 +        <li><b>onmessage</b> - the <em>queryServer</em> method is called with 
   2.104 +            non-null message
   2.105 +        </li>
   2.106 +        <li><b>onclose</b> - the <em>anErrorHappened</em> method is called with
   2.107 +            <code>null</code> exception
   2.108 +        </li>
   2.109 +        <li><b>onerror</b> - the <em>anErrorHappened</em> method is called with
   2.110 +            non-null exception
   2.111 +        </li>
   2.112 +    </ul>
   2.113 +    Using the <a href="../OnReceive.html">@OnReceive</a> annotation instructs
   2.114 +    its associated annotation processor to add appropriate send method
   2.115 +    into the generated <code>Comm</code> class. One can use it to establish communication,
   2.116 +    send messages and close the communication channel. Here are three methods
   2.117 +    showing how to do it:
   2.118 +    <pre>
   2.119 +    <b>static void </b>connect(Comm c) {
   2.120 +      // open a websocket channel:
   2.121 +      c.queryServer("ws://server/path", <b>null</b>);
   2.122 +      // the method returns immediately and starts establishing the connection
   2.123 +      // once that is finished either <b>onopen</b> or <b>onerror</b> type of
   2.124 +      // message is delivered
   2.125 +    }
   2.126 +
   2.127 +    <b>static void </b>sendMessage(Comm c, Request r) {
   2.128 +      // sends the message to already openned websocket channel:
   2.129 +      c.queryServer("ws://server/path", r);
   2.130 +    }
   2.131 +
   2.132 +    <b>static void </b>disconnect(Comm c) {
   2.133 +      // sending <code>null</code> again, closes the connection
   2.134 +      c.queryServer("ws://server/path", <b>null</b>);
   2.135 +    }
   2.136 +    </pre>
   2.137 +    One cannot change the URL while a connection is open otherwise one
   2.138 +    risks <code>IllegalStateException</code> runtime exceptions. To connect
   2.139 +    to different web socket server, one needs to close the connection first and
   2.140 +    only later open new one with different URL.
   2.141 +    <p>
   2.142 +    Enjoy <em>WebSocket</em>s via <a href="../OnReceive.html">@OnReceive</a>!
   2.143 +    </body>
   2.144 +</html>