1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.acme;
20
21 import java.io.IOException;
22 import java.io.PrintWriter;
23 import java.util.HashMap;
24 import java.util.LinkedList;
25 import java.util.Map;
26 import java.util.Queue;
27
28 import javax.servlet.ServletException;
29 import javax.servlet.http.HttpServlet;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.eclipse.jetty.continuation.Continuation;
34 import org.eclipse.jetty.continuation.ContinuationSupport;
35
36
37
38
39
40 public class ChatServlet extends HttpServlet
41 {
42
43
44 class Member
45 {
46 String _name;
47 Continuation _continuation;
48 Queue<String> _queue = new LinkedList<String>();
49 }
50
51 Map<String,Map<String,Member>> _rooms = new HashMap<String,Map<String, Member>>();
52
53
54
55 @Override
56 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
57 {
58
59 String action = request.getParameter("action");
60 String message = request.getParameter("message");
61 String username = request.getParameter("user");
62
63 if (action.equals("join"))
64 join(request,response,username);
65 else if (action.equals("poll"))
66 poll(request,response,username);
67 else if (action.equals("chat"))
68 chat(request,response,username,message);
69 }
70
71 private synchronized void join(HttpServletRequest request,HttpServletResponse response,String username)
72 throws IOException
73 {
74 Member member = new Member();
75 member._name=username;
76 Map<String,Member> room=_rooms.get(request.getPathInfo());
77 if (room==null)
78 {
79 room=new HashMap<String,Member>();
80 _rooms.put(request.getPathInfo(),room);
81 }
82 room.put(username,member);
83 response.setContentType("text/json;charset=utf-8");
84 PrintWriter out=response.getWriter();
85 out.print("{action:\"join\"}");
86 }
87
88 private synchronized void poll(HttpServletRequest request,HttpServletResponse response,String username)
89 throws IOException
90 {
91 Map<String,Member> room=_rooms.get(request.getPathInfo());
92 if (room==null)
93 {
94 response.sendError(503);
95 return;
96 }
97 Member member = room.get(username);
98 if (member==null)
99 {
100 response.sendError(503);
101 return;
102 }
103
104 synchronized(member)
105 {
106 if (member._queue.size()>0)
107 {
108
109 response.setContentType("text/json;charset=utf-8");
110 StringBuilder buf=new StringBuilder();
111
112 buf.append("{\"action\":\"poll\",");
113 buf.append("\"from\":\"");
114 buf.append(member._queue.poll());
115 buf.append("\",");
116
117 String message = member._queue.poll();
118 int quote=message.indexOf('"');
119 while (quote>=0)
120 {
121 message=message.substring(0,quote)+'\\'+message.substring(quote);
122 quote=message.indexOf('"',quote+2);
123 }
124 buf.append("\"chat\":\"");
125 buf.append(message);
126 buf.append("\"}");
127 byte[] bytes = buf.toString().getBytes("utf-8");
128 response.setContentLength(bytes.length);
129 response.getOutputStream().write(bytes);
130 }
131 else
132 {
133 Continuation continuation = ContinuationSupport.getContinuation(request);
134 if (continuation.isInitial())
135 {
136
137 continuation.setTimeout(20000);
138 continuation.suspend();
139 member._continuation=continuation;
140 }
141 else
142 {
143
144 response.setContentType("text/json;charset=utf-8");
145 PrintWriter out=response.getWriter();
146 out.print("{action:\"poll\"}");
147 }
148 }
149 }
150 }
151
152 private synchronized void chat(HttpServletRequest request,HttpServletResponse response,String username,String message)
153 throws IOException
154 {
155 Map<String,Member> room=_rooms.get(request.getPathInfo());
156 if (room!=null)
157 {
158
159 for (Member m:room.values())
160 {
161 synchronized (m)
162 {
163 m._queue.add(username);
164 m._queue.add(message);
165
166
167 if (m._continuation!=null)
168 {
169 m._continuation.resume();
170 m._continuation=null;
171 }
172 }
173 }
174 }
175
176 response.setContentType("text/json;charset=utf-8");
177 PrintWriter out=response.getWriter();
178 out.print("{action:\"chat\"}");
179 }
180
181
182
183 @Override
184 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
185 {
186 if (request.getParameter("action")!=null)
187 doPost(request,response);
188 else
189 getServletContext().getNamedDispatcher("default").forward(request,response);
190 }
191
192 }