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,response);
128 if (continuation.isInitial())
129 {
130
131 continuation.suspend();
132 member._continuation=continuation;
133 }
134 else
135 {
136
137 response.setContentType("text/json;charset=utf-8");
138 PrintWriter out=response.getWriter();
139 out.print("{action:\"poll\"}");
140 }
141 }
142 }
143 }
144
145 private synchronized void chat(HttpServletRequest request,HttpServletResponse response,String username,String message)
146 throws IOException
147 {
148 Map<String,Member> room=_rooms.get(request.getPathInfo());
149 if (room!=null)
150 {
151
152 for (Member m:room.values())
153 {
154 synchronized (m)
155 {
156 m._queue.add(username);
157 m._queue.add(message);
158
159
160 if (m._continuation!=null)
161 {
162 m._continuation.resume();
163 m._continuation=null;
164 }
165 }
166 }
167 }
168
169 response.setContentType("text/json;charset=utf-8");
170 PrintWriter out=response.getWriter();
171 out.print("{action:\"chat\"}");
172 }
173
174
175
176 @Override
177 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
178 {
179 if (request.getParameter("action")!=null)
180 doPost(request,response);
181 else
182 getServletContext().getNamedDispatcher("default").forward(request,response);
183 }
184
185 }