|
35 | 35 | importorg.java_websocket.WebSocketImpl; |
36 | 36 | importorg.java_websocket.WrappedByteChannel; |
37 | 37 | importorg.java_websocket.drafts.Draft; |
| 38 | +importorg.java_websocket.exceptions.InvalidDataException; |
38 | 39 | importorg.java_websocket.framing.CloseFrame; |
39 | 40 | importorg.java_websocket.framing.Framedata; |
40 | 41 | importorg.java_websocket.handshake.ClientHandshake; |
41 | 42 | importorg.java_websocket.handshake.Handshakedata; |
| 43 | +importorg.java_websocket.handshake.ServerHandshakeBuilder; |
42 | 44 |
|
43 | 45 | /** |
44 | 46 | * <tt>WebSocketServer</tt> is an abstract class that only takes care of the |
@@ -200,15 +202,21 @@ public void start(){ |
200 | 202 | * @throws InterruptedException |
201 | 203 | */ |
202 | 204 | publicvoidstop( inttimeout ) throwsIOException , InterruptedException{ |
203 | | -if( !isclosed.compareAndSet( false, true ) ){ |
| 205 | +if( !isclosed.compareAndSet( false, true ) ){// this also makes sure that no further connections will be added to this.connections |
204 | 206 | return; |
205 | 207 | } |
206 | 208 |
|
| 209 | +List<WebSocket> socketsToClose = null; |
| 210 | + |
| 211 | +// copy the connections in a list (prevent callback deadlocks) |
207 | 212 | synchronized ( connections ){ |
208 | | -for( WebSocketws : connections ){ |
209 | | -ws.close( CloseFrame.GOING_AWAY ); |
210 | | - } |
| 213 | +socketsToClose = newArrayList<WebSocket>( connections ); |
| 214 | + } |
| 215 | + |
| 216 | +for( WebSocketws : socketsToClose ){ |
| 217 | +ws.close( CloseFrame.GOING_AWAY ); |
211 | 218 | } |
| 219 | + |
212 | 220 | synchronized ( this ){ |
213 | 221 | if( selectorthread != null ){ |
214 | 222 | if( Thread.currentThread() != selectorthread ){ |
@@ -525,13 +533,25 @@ protected boolean removeConnection( WebSocket ws ){ |
525 | 533 | } |
526 | 534 | } |
527 | 535 |
|
| 536 | +@Override |
| 537 | +publicServerHandshakeBuilderonWebsocketHandshakeReceivedAsServer( WebSocketconn, Draftdraft, ClientHandshakerequest ) throwsInvalidDataException{ |
| 538 | +returnsuper.onWebsocketHandshakeReceivedAsServer( conn, draft, request ); |
| 539 | + } |
| 540 | + |
528 | 541 | /** @see #removeConnection(WebSocket) */ |
529 | 542 | protectedbooleanaddConnection( WebSocketws ){ |
530 | | -synchronized ( connections ){ |
531 | | -returnthis.connections.add( ws ); |
| 543 | +if( isclosed.get() ){ |
| 544 | +synchronized ( connections ){ |
| 545 | +booleansucc = this.connections.add( ws ); |
| 546 | +assert ( succ ); |
| 547 | +returnsucc; |
| 548 | + } |
| 549 | + } else{ |
| 550 | +// This case will happen when a new connection gets ready while the server is already stopping. |
| 551 | +ws.close( CloseFrame.GOING_AWAY ); |
| 552 | +returntrue;// for consistency sake we will make sure that both onOpen will be called |
532 | 553 | } |
533 | 554 | } |
534 | | - |
535 | 555 | /** |
536 | 556 | * @param conn |
537 | 557 | * may be null if the error does not belong to a single connection |
|
0 commit comments