1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.jsr356.endpoints;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.Reader;
24 import java.nio.ByteBuffer;
25 import java.util.Map;
26 import javax.websocket.CloseReason;
27 import javax.websocket.Endpoint;
28 import javax.websocket.MessageHandler;
29 import javax.websocket.MessageHandler.Whole;
30 import javax.websocket.PongMessage;
31
32 import org.eclipse.jetty.util.BufferUtil;
33 import org.eclipse.jetty.util.log.Log;
34 import org.eclipse.jetty.util.log.Logger;
35 import org.eclipse.jetty.websocket.api.WebSocketPolicy;
36 import org.eclipse.jetty.websocket.api.extensions.Frame;
37 import org.eclipse.jetty.websocket.common.message.MessageInputStream;
38 import org.eclipse.jetty.websocket.common.message.MessageReader;
39 import org.eclipse.jetty.websocket.jsr356.JsrPongMessage;
40 import org.eclipse.jetty.websocket.jsr356.JsrSession;
41 import org.eclipse.jetty.websocket.jsr356.MessageHandlerWrapper;
42 import org.eclipse.jetty.websocket.jsr356.MessageType;
43 import org.eclipse.jetty.websocket.jsr356.messages.BinaryPartialMessage;
44 import org.eclipse.jetty.websocket.jsr356.messages.BinaryWholeMessage;
45 import org.eclipse.jetty.websocket.jsr356.messages.TextPartialMessage;
46 import org.eclipse.jetty.websocket.jsr356.messages.TextWholeMessage;
47
48
49
50
51 public class JsrEndpointEventDriver extends AbstractJsrEventDriver
52 {
53 private static final Logger LOG = Log.getLogger(JsrEndpointEventDriver.class);
54
55 private final Endpoint endpoint;
56 private Map<String, String> pathParameters;
57
58 public JsrEndpointEventDriver(WebSocketPolicy policy, EndpointInstance endpointInstance)
59 {
60 super(policy,endpointInstance);
61 this.endpoint = (Endpoint)endpointInstance.getEndpoint();
62 }
63
64 @Override
65 public void init(JsrSession jsrsession)
66 {
67 jsrsession.setPathParameters(pathParameters);
68 }
69
70 @Override
71 public void onBinaryFrame(ByteBuffer buffer, boolean fin) throws IOException
72 {
73 if (activeMessage == null)
74 {
75 final MessageHandlerWrapper wrapper = jsrsession.getMessageHandlerWrapper(MessageType.BINARY);
76 if (wrapper == null)
77 {
78 if (LOG.isDebugEnabled())
79 {
80 LOG.debug("No BINARY MessageHandler declared");
81 }
82 return;
83 }
84 if (wrapper.wantsPartialMessages())
85 {
86 activeMessage = new BinaryPartialMessage(wrapper);
87 }
88 else if (wrapper.wantsStreams())
89 {
90 final MessageInputStream stream = new MessageInputStream();
91 activeMessage = stream;
92 dispatch(new Runnable()
93 {
94 @SuppressWarnings("unchecked")
95 @Override
96 public void run()
97 {
98 MessageHandler.Whole<InputStream> handler = (Whole<InputStream>)wrapper.getHandler();
99 handler.onMessage(stream);
100 }
101 });
102 }
103 else
104 {
105 activeMessage = new BinaryWholeMessage(this,wrapper);
106 }
107 }
108
109 activeMessage.appendFrame(buffer,fin);
110
111 if (fin)
112 {
113 activeMessage.messageComplete();
114 activeMessage = null;
115 }
116 }
117
118 @Override
119 public void onBinaryMessage(byte[] data)
120 {
121
122 }
123
124 @Override
125 protected void onClose(CloseReason closereason)
126 {
127 endpoint.onClose(this.jsrsession,closereason);
128 }
129
130 @Override
131 public void onConnect()
132 {
133 if (LOG.isDebugEnabled())
134 {
135 LOG.debug("onConnect({}, {})",jsrsession,config);
136 }
137 try
138 {
139 endpoint.onOpen(jsrsession,config);
140 }
141 catch (Throwable t)
142 {
143 LOG.warn("Uncaught exception",t);
144 }
145 }
146
147 @Override
148 public void onError(Throwable cause)
149 {
150 endpoint.onError(jsrsession,cause);
151 }
152
153 @Override
154 public void onFrame(Frame frame)
155 {
156
157 }
158
159 @Override
160 public void onInputStream(InputStream stream)
161 {
162
163 }
164
165 @Override
166 public void onReader(Reader reader)
167 {
168
169 }
170
171 @Override
172 public void onTextFrame(ByteBuffer buffer, boolean fin) throws IOException
173 {
174 if (activeMessage == null)
175 {
176 final MessageHandlerWrapper wrapper = jsrsession.getMessageHandlerWrapper(MessageType.TEXT);
177 if (wrapper == null)
178 {
179 if (LOG.isDebugEnabled())
180 {
181 LOG.debug("No TEXT MessageHandler declared");
182 }
183 return;
184 }
185 if (wrapper.wantsPartialMessages())
186 {
187 activeMessage = new TextPartialMessage(wrapper);
188 }
189 else if (wrapper.wantsStreams())
190 {
191 final MessageReader stream = new MessageReader(new MessageInputStream());
192 activeMessage = stream;
193
194 dispatch(new Runnable()
195 {
196 @SuppressWarnings("unchecked")
197 @Override
198 public void run()
199 {
200 MessageHandler.Whole<Reader> handler = (Whole<Reader>)wrapper.getHandler();
201 handler.onMessage(stream);
202 }
203 });
204 }
205 else
206 {
207 activeMessage = new TextWholeMessage(this,wrapper);
208 }
209 }
210
211 activeMessage.appendFrame(buffer,fin);
212
213 if (fin)
214 {
215 activeMessage.messageComplete();
216 activeMessage = null;
217 }
218 }
219
220 @Override
221 public void onTextMessage(String message)
222 {
223
224 }
225
226 @Override
227 public void onPing(ByteBuffer buffer)
228 {
229 onPongMessage(buffer);
230 }
231
232 @Override
233 public void onPong(ByteBuffer buffer)
234 {
235 onPongMessage(buffer);
236 }
237
238 private void onPongMessage(ByteBuffer buffer)
239 {
240 final MessageHandlerWrapper wrapper = jsrsession.getMessageHandlerWrapper(MessageType.PONG);
241 if (wrapper == null)
242 {
243 if (LOG.isDebugEnabled())
244 {
245 LOG.debug("No PONG MessageHandler declared");
246 }
247 return;
248 }
249
250 ByteBuffer pongBuf = null;
251
252 if (BufferUtil.isEmpty(buffer))
253 {
254 pongBuf = BufferUtil.EMPTY_BUFFER;
255 }
256 else
257 {
258 pongBuf = ByteBuffer.allocate(buffer.remaining());
259 BufferUtil.put(buffer,pongBuf);
260 BufferUtil.flipToFlush(pongBuf,0);
261 }
262
263 @SuppressWarnings("unchecked")
264 Whole<PongMessage> pongHandler = (Whole<PongMessage>)wrapper.getHandler();
265 pongHandler.onMessage(new JsrPongMessage(pongBuf));
266 }
267
268 @Override
269 public void setPathParameters(Map<String, String> pathParameters)
270 {
271 this.pathParameters = pathParameters;
272 }
273
274 @Override
275 public String toString()
276 {
277 return String.format("%s[%s]",JsrEndpointEventDriver.class.getSimpleName(),endpoint.getClass().getName());
278 }
279 }