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