|
35 | 35 | import org.java_websocket.WebSocketImpl; |
36 | 36 | import org.java_websocket.WrappedByteChannel; |
37 | 37 | import org.java_websocket.drafts.Draft; |
| 38 | +import org.java_websocket.exceptions.InvalidDataException; |
38 | 39 | import org.java_websocket.framing.CloseFrame; |
39 | 40 | import org.java_websocket.framing.Framedata; |
40 | 41 | import org.java_websocket.handshake.ClientHandshake; |
41 | 42 | import org.java_websocket.handshake.Handshakedata; |
| 43 | +import org.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 | public void stop( int timeout ) throws IOException , 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( WebSocket ws : connections ) { |
209 | | - ws.close( CloseFrame.GOING_AWAY ); |
210 | | - } |
| 213 | + socketsToClose = new ArrayList<WebSocket>( connections ); |
| 214 | + } |
| 215 | + |
| 216 | + for( WebSocket ws : 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 | + public ServerHandshakeBuilder onWebsocketHandshakeReceivedAsServer( WebSocket conn, Draft draft, ClientHandshake request ) throws InvalidDataException { |
| 538 | + return super.onWebsocketHandshakeReceivedAsServer( conn, draft, request ); |
| 539 | + } |
| 540 | + |
528 | 541 | /** @see #removeConnection(WebSocket) */ |
529 | 542 | protected boolean addConnection( WebSocket ws ) { |
530 | | - synchronized ( connections ) { |
531 | | - return this.connections.add( ws ); |
| 543 | + if( isclosed.get() ) { |
| 544 | + synchronized ( connections ) { |
| 545 | + boolean succ = this.connections.add( ws ); |
| 546 | + assert ( succ ); |
| 547 | + return succ; |
| 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 | + return true;// 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