chat/server/src/main/java/org/apidesign/demo/chat/server/ChatServerResource.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 22 Apr 2016 18:13:09 +0200
branchNewChat
changeset 242 58596208d06d
parent 241 6a59fdb91011
permissions -rw-r--r--
Exchanging messages over WebSockets in the default desktop client
     1 /**
     2  * The MIT License (MIT)
     3  *
     4  * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     5  *
     6  * Permission is hereby granted, free of charge, to any person obtaining a copy
     7  * of this software and associated documentation files (the "Software"), to deal
     8  * in the Software without restriction, including without limitation the rights
     9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    10  * copies of the Software, and to permit persons to whom the Software is
    11  * furnished to do so, subject to the following conditions:
    12  *
    13  * The above copyright notice and this permission notice shall be included in
    14  * all copies or substantial portions of the Software.
    15  *
    16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    22  * THE SOFTWARE.
    23  */
    24 package org.apidesign.demo.chat.server;
    25 
    26 import java.io.ByteArrayInputStream;
    27 import java.io.IOException;
    28 import java.util.ArrayList;
    29 import java.util.HashSet;
    30 import java.util.List;
    31 import java.util.Set;
    32 import java.util.logging.Logger;
    33 import net.java.html.BrwsrCtx;
    34 import net.java.html.json.Models;
    35 import org.apidesign.demo.chat.shared.Message;
    36 import org.apidesign.demo.chat.shared.Query;
    37 import org.apidesign.demo.chat.shared.Reply;
    38 import org.glassfish.grizzly.websockets.DataFrame;
    39 import org.glassfish.grizzly.websockets.WebSocket;
    40 import org.glassfish.grizzly.websockets.WebSocketApplication;
    41 
    42 /** Server side of the chat application.*/
    43 public final class ChatServerResource extends WebSocketApplication {
    44     private static final Logger LOG = Logger.getLogger(ChatServerResource.class.getName());
    45     private static final long started = System.currentTimeMillis() - 10;
    46     
    47     private List<Message> msgs = new ArrayList<>();
    48     {
    49         Message welcome = new Message();
    50         welcome.setUser("system");
    51         welcome.setComment("Welcome and enjoy!");
    52         welcome.setSince(10);
    53         msgs.add(welcome);
    54     }
    55 
    56 
    57     private final Set<WebSocket> connected = new HashSet<>();
    58 /*
    59     
    60     @Produces(MediaType.APPLICATION_JSON)
    61     @GET public synchronized void getResources(
    62         @QueryParam("since") @DefaultValue("0") long since,
    63         @Suspended AsyncResponse ar
    64     ) {
    65         Query q = new Query();
    66         for (Message m : msgs) {
    67             if (m.getSince()>= since) {
    68                 q.getMessages().add(m);
    69             }
    70         }
    71         if (!q.getMessages().isEmpty()) {
    72             ar.resume(q);
    73         } else {
    74             awaiting.put(ar, since);
    75         }
    76     }
    77     */
    78     private void handleAwaiting(Message msg) {
    79         assert Thread.holdsLock(this);
    80         Reply reply = new Reply();
    81         reply.getMessages().add(msg);
    82         String txt = reply.toString();
    83         for (WebSocket webSocket : connected) {
    84             webSocket.send(txt);
    85         }
    86     }
    87 
    88     private synchronized Message publish(Message msg) {
    89         msg.setSince(System.currentTimeMillis() - started);
    90         msgs.add(msg);
    91         handleAwaiting(msg);
    92         return msg;
    93     }
    94 
    95     @Override
    96     public void onConnect(WebSocket socket) {
    97         connected.add(socket);
    98     }
    99 
   100     @Override
   101     public void onClose(WebSocket socket, DataFrame frame) {
   102         connected.remove(socket);
   103     }
   104 
   105     @Override
   106     public void onMessage(WebSocket socket, String text) {
   107         try {
   108             ByteArrayInputStream is = new ByteArrayInputStream(text.getBytes("UTF-8"));
   109             Query q = Models.parse(BrwsrCtx.findDefault(ChatServerResource.class), Query.class, is);
   110             if (q.getPost() != null) {
   111                 publish(q.getPost());
   112             }
   113             if (q.isAll()) {
   114                 socket.send(new Reply(true, msgs.toArray(new Message[0])).toString());
   115             }
   116         } catch (IOException ex) {
   117             throw new IllegalStateException(ex);
   118         }
   119     }
   120 }