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