View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package com.acme;
20  
21  import java.io.IOException;
22  import java.util.List;
23  import java.util.ListIterator;
24  import java.util.concurrent.CopyOnWriteArrayList;
25  
26  import javax.servlet.ServletException;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpServletResponse;
29  
30  import org.eclipse.jetty.websocket.api.RemoteEndpoint;
31  import org.eclipse.jetty.websocket.api.Session;
32  import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
33  import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
34  import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
35  import org.eclipse.jetty.websocket.api.annotations.WebSocket;
36  import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
37  import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
38  import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
39  import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
40  import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
41  
42  @SuppressWarnings("serial")
43  public class WebSocketChatServlet extends WebSocketServlet implements WebSocketCreator
44  {
45      /** Holds active sockets to other members of the chat */
46      private final List<ChatWebSocket> members = new CopyOnWriteArrayList<ChatWebSocket>();
47  
48      @Override
49      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
50      {
51          getServletContext().getNamedDispatcher("default").forward(request,response);
52      }
53  
54      @Override
55      public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
56      {
57          if (req.hasSubProtocol("chat"))
58          {
59              resp.setAcceptedSubProtocol("chat");
60              return new ChatWebSocket();
61          }
62          return null;
63      }
64  
65      @Override
66      public void configure(WebSocketServletFactory factory)
67      {
68          factory.register(ChatWebSocket.class);
69          factory.setCreator(this);
70      }
71  
72      /* ------------------------------------------------------------ */
73      /**
74       * Create a WebSocket that echo's back the message to all other members of the servlet.
75       */
76      @WebSocket
77      public class ChatWebSocket
78      {
79          volatile Session session;
80          volatile RemoteEndpoint remote;
81  
82          @OnWebSocketConnect
83          public void onOpen(Session sess)
84          {
85              this.session = sess;
86              this.remote = sess.getRemote();
87              members.add(this);
88          }
89  
90          @OnWebSocketMessage
91          public void onMessage(String data)
92          {
93              if (data.contains("disconnect"))
94              {
95                  session.close();
96                  return;
97              }
98  
99              ListIterator<ChatWebSocket> iter = members.listIterator();
100             while (iter.hasNext())
101             {
102                 ChatWebSocket member = iter.next();
103 
104                 // Test if member is now disconnected
105                 if (!member.session.isOpen())
106                 {
107                     iter.remove();
108                     continue;
109                 }
110 
111                 // Async write the message back.
112                 member.remote.sendString(data,null);
113             }
114         }
115 
116         @OnWebSocketClose
117         public void onClose(int code, String message)
118         {
119             members.remove(this);
120         }
121     }
122 }