1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.cometd;
16 import java.io.IOException;
17 import java.util.List;
18
19 import javax.servlet.ServletException;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22
23 import org.mortbay.cometd.AbstractBayeux;
24 import org.mortbay.cometd.AbstractCometdServlet;
25 import org.mortbay.cometd.ClientImpl;
26 import org.mortbay.cometd.MessageImpl;
27 import org.mortbay.cometd.Transport;
28
29 import dojox.cometd.Extension;
30 import dojox.cometd.Message;
31
32 public class SuspendingCometdServlet extends AbstractCometdServlet
33 {
34
35 protected AbstractBayeux newBayeux()
36 {
37 return new SuspendingBayeux();
38 }
39
40
41 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
42 {
43 doPost(req,resp);
44 }
45
46
47 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
48 {
49
50 SuspendingClient client=null;
51 Transport transport=null;
52 boolean connect=false;
53 int num_msgs=-1;
54
55
56 boolean initial=false;
57 if (request.isInitial() || request.getAttribute(CLIENT_ATTR)==null)
58 {
59 initial=true;
60
61 Message[] messages = getMessages(request);
62 num_msgs=messages.length;
63
64
65 String jsonpParam=request.getParameter("jsonp");
66
67
68 boolean response_pending=false;
69 try
70 {
71 for (Message message : messages)
72 {
73 if (jsonpParam!=null)
74 message.put("jsonp",jsonpParam);
75
76 if (client==null)
77 {
78 client=(SuspendingClient)_bayeux.getClient((String)message.get(AbstractBayeux.CLIENT_FIELD));
79
80
81 if (client==null)
82 {
83
84 String browser_id=browserId(request);
85 if (browser_id==null)
86 browser_id=newBrowserId(request,response);
87
88 if (transport==null)
89 {
90 transport=_bayeux.newTransport(client,message);
91 transport.setResponse(response);
92 }
93 _bayeux.handle(null,transport,message);
94 message=null;
95
96 continue;
97 }
98 else
99 {
100 String browser_id=browserId(request);
101 if (browser_id!=null && (client.getBrowserId()==null || !client.getBrowserId().equals(browser_id)))
102 client.setBrowserId(browser_id);
103
104
105 if (transport==null)
106 {
107 transport=_bayeux.newTransport(client,message);
108 transport.setResponse(response);
109 }
110
111
112 if (!transport.resumePoll())
113 {
114 response_pending=true;
115 client.responsePending();
116 }
117 }
118 }
119
120 String channel=_bayeux.handle(client,transport,message);
121 connect|=AbstractBayeux.META_CONNECT.equals(channel);
122 }
123 }
124 finally
125 {
126 if (response_pending)
127 client.responded();
128
129 for (Message message : messages)
130 ((MessageImpl)message).decRef();
131 }
132 }
133 else
134 {
135 transport=(Transport)request.getAttribute(TRANSPORT_ATTR);
136 transport.setResponse(response);
137 Object clientObj=request.getAttribute(CLIENT_ATTR);
138 client=(clientObj instanceof ClientImpl)?(SuspendingClient)clientObj:null;
139 if (client!=null)
140 client.setPollRequest(null);
141 }
142
143
144 if (transport!=null)
145 {
146 Message pollReply=transport.getPollReply();
147 if (pollReply!=null)
148 {
149 if (_bayeux.isLogDebug())
150 _bayeux.logDebug("doPost: transport is polling");
151 long timeout=client.getTimeout();
152 if (timeout==0)
153 timeout=_bayeux.getTimeout();
154
155 if (initial)
156 client.access();
157
158
159 synchronized (client)
160 {
161 if (!client.hasMessages() && initial && num_msgs<=1)
162 {
163
164 client.setPollRequest(request);
165 request.setAttribute(CLIENT_ATTR,client);
166 request.setAttribute(TRANSPORT_ATTR,transport);
167 request.suspend(timeout);
168 return;
169 }
170 }
171
172 for (Extension e:_bayeux.getExtensions())
173 pollReply=e.sendMeta(pollReply);
174 transport.send(pollReply);
175 }
176 else if (client!=null)
177 {
178 client.access();
179 }
180 }
181
182
183
184 if (client!=null)
185 {
186 List<Message> messages = null;
187 Message message = null;
188 synchronized(client)
189 {
190 switch (client.getMessages())
191 {
192 case 0:
193 break;
194 case 1:
195 message = client.takeMessage();
196 break;
197 default:
198 messages = client.takeMessages();
199 break;
200 }
201
202 if (!_asyncDeliver)
203 {
204 try
205 {
206 if (message!=null)
207 transport.send(message);
208 else if (messages!=null)
209 transport.send(messages);
210
211 transport.complete();
212 response.flushBuffer();
213
214 if (transport.resumePoll())
215 client.resume();
216
217 return;
218 }
219 catch(Throwable e)
220 {
221
222 if (message!=null)
223 client.returnMessage(message);
224 else if (messages!=null)
225 client.returnMessages(messages);
226
227 if (e instanceof ServletException)
228 throw (ServletException)e;
229 if (e instanceof IOException)
230 throw (IOException)e;
231 if (e instanceof RuntimeException)
232 throw (RuntimeException)e;
233 if (e instanceof Error)
234 throw (Error)e;
235 if (e instanceof ThreadDeath)
236 throw (ThreadDeath)e;
237 throw new ServletException(e);
238 }
239 }
240 }
241 if (message!=null)
242 transport.send(message);
243 else if (messages!=null)
244 transport.send(messages);
245
246 if (transport.resumePoll())
247 client.resume();
248 }
249
250 if (transport!=null)
251 transport.complete();
252 }
253 }