99import java .nio .channels .ServerSocketChannel ;
1010import java .nio .channels .SocketChannel ;
1111import java .util .Collections ;
12- import java .util .HashSet ;
1312import java .util .Iterator ;
1413import java .util .Set ;
14+ import java .util .concurrent .CopyOnWriteArraySet ;
1515
1616import org .java_websocket .drafts .Draft ;
1717import org .java_websocket .framing .CloseFrame ;
@@ -32,7 +32,7 @@ public abstract class WebSocketServer extends WebSocketAdapter implements Runnab
3232 * Holds the list of active WebSocket connections. "Active" means WebSocket
3333 * handshake is complete and socket can be written to, or read from.
3434 */
35- private final Set <WebSocket > connections = new HashSet < WebSocket >() ;
35+ private final CopyOnWriteArraySet <WebSocket > connections ;
3636 /**
3737 * The port number that this WebSocket server should listen on. Default is
3838 * WebSocket.DEFAULT_PORT.
@@ -83,6 +83,7 @@ public WebSocketServer( InetSocketAddress address ) {
8383 * instance should comply to.
8484 */
8585 public WebSocketServer ( InetSocketAddress address , Draft draft ) {
86+ this .connections = new CopyOnWriteArraySet <WebSocket >();
8687 this .draft = draft ;
8788 setAddress ( address );
8889 }
@@ -108,10 +109,8 @@ public void start() {
108109 * When socket related I/O errors occur.
109110 */
110111 public void stop () throws IOException {
111- synchronized ( connections ) {
112- for ( WebSocket ws : connections ) {
113- ws .close ( CloseFrame .NORMAL );
114- }
112+ for ( WebSocket ws : connections ) {
113+ ws .close ( CloseFrame .NORMAL );
115114 }
116115 thread .interrupt ();
117116 this .server .close ();
@@ -120,13 +119,11 @@ public void stop() throws IOException {
120119
121120 /**
122121 * Returns a WebSocket[] of currently connected clients.
123- * Its iterators will be failfast and its not judicious
124- * to modify it.
125122 *
126- * @return The currently connected clients.
123+ * @return The currently connected clients in a WebSocket[] .
127124 */
128125 public Set <WebSocket > connections () {
129- return this .connections ;
126+ return Collections . unmodifiableSet ( this .connections ) ;
130127 }
131128
132129 /**
@@ -211,18 +208,16 @@ public void run() {
211208 key .channel ().register ( selector , SelectionKey .OP_READ , conn );
212209 }
213210 }
214- synchronized ( connections ) {
215- Iterator <WebSocket > it = this .connections .iterator ();
216- while ( it .hasNext () ) {
217- // We have to do this check here, and not in the thread that
218- // adds the buffered data to the WebSocket, because the
219- // Selector is not thread-safe, and can only be accessed
220- // by this thread.
221- conn = it .next ();
222- if ( conn .hasBufferedData () ) {
223- conn .flush ();
224- // key.channel().register( selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, conn );
225- }
211+ Iterator <WebSocket > it = this .connections .iterator ();
212+ while ( it .hasNext () ) {
213+ // We have to do this check here, and not in the thread that
214+ // adds the buffered data to the WebSocket, because the
215+ // Selector is not thread-safe, and can only be accessed
216+ // by this thread.
217+ conn = it .next ();
218+ if ( conn .hasBufferedData () ) {
219+ conn .flush ();
220+ // key.channel().register( selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, conn );
226221 }
227222 }
228223 } catch ( IOException ex ) {
@@ -232,9 +227,6 @@ public void run() {
232227 if ( conn != null ) {
233228 conn .close ( CloseFrame .ABNROMAL_CLOSE );
234229 }
235- } catch ( Throwable e ) {
236- System .out .println ( e );
237- e .printStackTrace ();
238230 }
239231 }
240232 }
@@ -268,19 +260,15 @@ public final void onWebsocketMessage( WebSocket conn, byte[] blob ) {
268260
269261 @ Override
270262 public final void onWebsocketOpen ( WebSocket conn , Handshakedata handshake ) {
271- synchronized ( connections ) {
272- if ( this .connections .add ( conn ) ) {
273- onOpen ( conn , (ClientHandshake ) handshake );
274- }
263+ if ( this .connections .add ( conn ) ) {
264+ onOpen ( conn , (ClientHandshake ) handshake );
275265 }
276266 }
277267
278268 @ Override
279269 public final void onWebsocketClose ( WebSocket conn , int code , String reason , boolean remote ) {
280- synchronized ( connections ) {
281- if ( this .connections .remove ( conn ) ) {
282- onClose ( conn , code , reason , remote );
283- }
270+ if ( this .connections .remove ( conn ) ) {
271+ onClose ( conn , code , reason , remote );
284272 }
285273 }
286274
0 commit comments