OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 private WebSocketConnectionState state; | 49 private WebSocketConnectionState state; |
50 private final Object closeEventLock = new Object(); | 50 private final Object closeEventLock = new Object(); |
51 private boolean closeEvent; | 51 private boolean closeEvent; |
52 // WebSocket send queue. Messages are added to the queue when WebSocket | 52 // WebSocket send queue. Messages are added to the queue when WebSocket |
53 // client is not registered and are consumed in register() call. | 53 // client is not registered and are consumed in register() call. |
54 private final LinkedList<String> wsSendQueue; | 54 private final LinkedList<String> wsSendQueue; |
55 | 55 |
56 /** | 56 /** |
57 * Possible WebSocket connection states. | 57 * Possible WebSocket connection states. |
58 */ | 58 */ |
59 public enum WebSocketConnectionState { | 59 public enum WebSocketConnectionState { NEW, CONNECTED, REGISTERED, CLOSED, ERR
OR } |
60 NEW, CONNECTED, REGISTERED, CLOSED, ERROR | |
61 }; | |
62 | 60 |
63 /** | 61 /** |
64 * Callback interface for messages delivered on WebSocket. | 62 * Callback interface for messages delivered on WebSocket. |
65 * All events are dispatched from a looper executor thread. | 63 * All events are dispatched from a looper executor thread. |
66 */ | 64 */ |
67 public interface WebSocketChannelEvents { | 65 public interface WebSocketChannelEvents { |
68 void onWebSocketMessage(final String message); | 66 void onWebSocketMessage(final String message); |
69 void onWebSocketClose(); | 67 void onWebSocketClose(); |
70 void onWebSocketError(final String description); | 68 void onWebSocketError(final String description); |
71 } | 69 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 checkIfCalledOnValidThread(); | 170 checkIfCalledOnValidThread(); |
173 Log.d(TAG, "Disconnect WebSocket. State: " + state); | 171 Log.d(TAG, "Disconnect WebSocket. State: " + state); |
174 if (state == WebSocketConnectionState.REGISTERED) { | 172 if (state == WebSocketConnectionState.REGISTERED) { |
175 // Send "bye" to WebSocket server. | 173 // Send "bye" to WebSocket server. |
176 send("{\"type\": \"bye\"}"); | 174 send("{\"type\": \"bye\"}"); |
177 state = WebSocketConnectionState.CONNECTED; | 175 state = WebSocketConnectionState.CONNECTED; |
178 // Send http DELETE to http WebSocket server. | 176 // Send http DELETE to http WebSocket server. |
179 sendWSSMessage("DELETE", ""); | 177 sendWSSMessage("DELETE", ""); |
180 } | 178 } |
181 // Close WebSocket in CONNECTED or ERROR states only. | 179 // Close WebSocket in CONNECTED or ERROR states only. |
182 if (state == WebSocketConnectionState.CONNECTED | 180 if (state == WebSocketConnectionState.CONNECTED || state == WebSocketConnect
ionState.ERROR) { |
183 || state == WebSocketConnectionState.ERROR) { | |
184 ws.disconnect(); | 181 ws.disconnect(); |
185 state = WebSocketConnectionState.CLOSED; | 182 state = WebSocketConnectionState.CLOSED; |
186 | 183 |
187 // Wait for websocket close event to prevent websocket library from | 184 // Wait for websocket close event to prevent websocket library from |
188 // sending any pending messages to deleted looper thread. | 185 // sending any pending messages to deleted looper thread. |
189 if (waitForComplete) { | 186 if (waitForComplete) { |
190 synchronized (closeEventLock) { | 187 synchronized (closeEventLock) { |
191 while (!closeEvent) { | 188 while (!closeEvent) { |
192 try { | 189 try { |
193 closeEventLock.wait(CLOSE_TIMEOUT); | 190 closeEventLock.wait(CLOSE_TIMEOUT); |
(...skipping 18 matching lines...) Expand all Loading... |
212 events.onWebSocketError(errorMessage); | 209 events.onWebSocketError(errorMessage); |
213 } | 210 } |
214 } | 211 } |
215 }); | 212 }); |
216 } | 213 } |
217 | 214 |
218 // Asynchronously send POST/DELETE to WebSocket server. | 215 // Asynchronously send POST/DELETE to WebSocket server. |
219 private void sendWSSMessage(final String method, final String message) { | 216 private void sendWSSMessage(final String method, final String message) { |
220 String postUrl = postServerUrl + "/" + roomID + "/" + clientID; | 217 String postUrl = postServerUrl + "/" + roomID + "/" + clientID; |
221 Log.d(TAG, "WS " + method + " : " + postUrl + " : " + message); | 218 Log.d(TAG, "WS " + method + " : " + postUrl + " : " + message); |
222 AsyncHttpURLConnection httpConnection = new AsyncHttpURLConnection( | 219 AsyncHttpURLConnection httpConnection = |
223 method, postUrl, message, new AsyncHttpEvents() { | 220 new AsyncHttpURLConnection(method, postUrl, message, new AsyncHttpEvents
() { |
224 @Override | 221 @Override |
225 public void onHttpError(String errorMessage) { | 222 public void onHttpError(String errorMessage) { |
226 reportError("WS " + method + " error: " + errorMessage); | 223 reportError("WS " + method + " error: " + errorMessage); |
227 } | 224 } |
228 | 225 |
229 @Override | 226 @Override |
230 public void onHttpComplete(String response) { | 227 public void onHttpComplete(String response) {} |
231 } | |
232 }); | 228 }); |
233 httpConnection.send(); | 229 httpConnection.send(); |
234 } | 230 } |
235 | 231 |
236 // Helper method for debugging purposes. Ensures that WebSocket method is | 232 // Helper method for debugging purposes. Ensures that WebSocket method is |
237 // called on a looper thread. | 233 // called on a looper thread. |
238 private void checkIfCalledOnValidThread() { | 234 private void checkIfCalledOnValidThread() { |
239 if (Thread.currentThread() != handler.getLooper().getThread()) { | 235 if (Thread.currentThread() != handler.getLooper().getThread()) { |
240 throw new IllegalStateException( | 236 throw new IllegalStateException("WebSocket method is not called on valid t
hread"); |
241 "WebSocket method is not called on valid thread"); | |
242 } | 237 } |
243 } | 238 } |
244 | 239 |
245 private class WebSocketObserver implements WebSocketConnectionObserver { | 240 private class WebSocketObserver implements WebSocketConnectionObserver { |
246 @Override | 241 @Override |
247 public void onOpen() { | 242 public void onOpen() { |
248 Log.d(TAG, "WebSocket connection opened to: " + wsServerUrl); | 243 Log.d(TAG, "WebSocket connection opened to: " + wsServerUrl); |
249 handler.post(new Runnable() { | 244 handler.post(new Runnable() { |
250 @Override | 245 @Override |
251 public void run() { | 246 public void run() { |
252 state = WebSocketConnectionState.CONNECTED; | 247 state = WebSocketConnectionState.CONNECTED; |
253 // Check if we have pending register request. | 248 // Check if we have pending register request. |
254 if (roomID != null && clientID != null) { | 249 if (roomID != null && clientID != null) { |
255 register(roomID, clientID); | 250 register(roomID, clientID); |
256 } | 251 } |
257 } | 252 } |
258 }); | 253 }); |
259 } | 254 } |
260 | 255 |
261 @Override | 256 @Override |
262 public void onClose(WebSocketCloseNotification code, String reason) { | 257 public void onClose(WebSocketCloseNotification code, String reason) { |
263 Log.d(TAG, "WebSocket connection closed. Code: " + code | 258 Log.d(TAG, "WebSocket connection closed. Code: " + code + ". Reason: " + r
eason + ". State: " |
264 + ". Reason: " + reason + ". State: " + state); | 259 + state); |
265 synchronized (closeEventLock) { | 260 synchronized (closeEventLock) { |
266 closeEvent = true; | 261 closeEvent = true; |
267 closeEventLock.notify(); | 262 closeEventLock.notify(); |
268 } | 263 } |
269 handler.post(new Runnable() { | 264 handler.post(new Runnable() { |
270 @Override | 265 @Override |
271 public void run() { | 266 public void run() { |
272 if (state != WebSocketConnectionState.CLOSED) { | 267 if (state != WebSocketConnectionState.CLOSED) { |
273 state = WebSocketConnectionState.CLOSED; | 268 state = WebSocketConnectionState.CLOSED; |
274 events.onWebSocketClose(); | 269 events.onWebSocketClose(); |
(...skipping 11 matching lines...) Expand all Loading... |
286 public void run() { | 281 public void run() { |
287 if (state == WebSocketConnectionState.CONNECTED | 282 if (state == WebSocketConnectionState.CONNECTED |
288 || state == WebSocketConnectionState.REGISTERED) { | 283 || state == WebSocketConnectionState.REGISTERED) { |
289 events.onWebSocketMessage(message); | 284 events.onWebSocketMessage(message); |
290 } | 285 } |
291 } | 286 } |
292 }); | 287 }); |
293 } | 288 } |
294 | 289 |
295 @Override | 290 @Override |
296 public void onRawTextMessage(byte[] payload) { | 291 public void onRawTextMessage(byte[] payload) {} |
297 } | |
298 | 292 |
299 @Override | 293 @Override |
300 public void onBinaryMessage(byte[] payload) { | 294 public void onBinaryMessage(byte[] payload) {} |
301 } | |
302 } | 295 } |
303 | |
304 } | 296 } |
OLD | NEW |