/** * Closes all connected clients sockets, then closes the underlying ServerSocketChannel, * effectively killing the server socket thread and freeing the port the server was bound to. * * @throws IOException When socket related I/O errors occur. */ public void stop() throws IOException { for (WebSocket ws : connections) { ws.close(CloseFrame.NORMAL); } thread.interrupt(); this.server.close(); }
@Test(expected = IllegalArgumentException.class) public void sendMessageWhileClosed() throws NoSuchAlgorithmException, URISyntaxException { TestMessageHandler handler = new TestMessageHandler(); Configuration configuration = new Configuration(handler, "ws://echo.websocket.org", SSLContext.getDefault()); WebSocket socket = new WebSocket(configuration); socket.sendMessage("some random message"); }
/** {@inheritDoc} */ @Override public void broadcastFragment( final Iterable<? extends WebSocket> recipients, final String text, final boolean last) { for (WebSocket websocket : recipients) { if (websocket.isConnected()) { try { websocket.stream(last, text); } catch (WebSocketException ignored) { } } } }
/** {@inheritDoc} */ @Override public void broadcast(final Iterable<? extends WebSocket> recipients, final byte[] binary) { for (WebSocket websocket : recipients) { if (websocket.isConnected()) { try { websocket.send(binary); } catch (WebSocketException ignored) { } } } }
/** {@inheritDoc} */ @Override public final void onFailure(Throwable t) { for (WebSocketListener listener : listeners) { if (!ok.get() && webSocket != null) { webSocket.addWebSocketListener(listener); } listener.onError(t); } }
/** {@inheritDoc} */ @Override public final void onSuccess(WebSocket webSocket) { this.webSocket = webSocket; for (WebSocketListener listener : listeners) { webSocket.addWebSocketListener(listener); listener.onOpen(webSocket); } ok.set(true); }
@Override public Response serve(final IHTTPSession session) { Map<String, String> headers = session.getHeaders(); if (isWebsocketRequested(session)) { if (!NanoWebSocketServer.HEADER_WEBSOCKET_VERSION_VALUE.equalsIgnoreCase( headers.get(NanoWebSocketServer.HEADER_WEBSOCKET_VERSION))) { return newFixedLengthResponse( Response.Status.BAD_REQUEST, NanoHTTPD.MIME_PLAINTEXT, "Invalid Websocket-Version " + headers.get(NanoWebSocketServer.HEADER_WEBSOCKET_VERSION)); } if (!headers.containsKey(NanoWebSocketServer.HEADER_WEBSOCKET_KEY)) { return newFixedLengthResponse( Response.Status.BAD_REQUEST, NanoHTTPD.MIME_PLAINTEXT, "Missing Websocket-Key"); } WebSocket webSocket = openWebSocket(session); Response handshakeResponse = webSocket.getHandshakeResponse(); try { handshakeResponse.addHeader( NanoWebSocketServer.HEADER_WEBSOCKET_ACCEPT, makeAcceptKey(headers.get(NanoWebSocketServer.HEADER_WEBSOCKET_KEY))); } catch (NoSuchAlgorithmException e) { return newFixedLengthResponse( Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "The SHA-1 Algorithm required for websockets is not available on the server."); } if (headers.containsKey(NanoWebSocketServer.HEADER_WEBSOCKET_PROTOCOL)) { handshakeResponse.addHeader( NanoWebSocketServer.HEADER_WEBSOCKET_PROTOCOL, headers.get(NanoWebSocketServer.HEADER_WEBSOCKET_PROTOCOL).split(",")[0]); } return handshakeResponse; } else { return super.serve(session); } }
/** * Gets the XML string that should be returned if a client requests a Flash security policy. * * <p>The default implementation allows access from all remote domains, but only on the port that * this WebSocketServer is listening on. * * <p>This is specifically implemented for gitime's WebSocket client for Flash: * http://github.com/gimite/web-socket-js * * @return An XML String that comforts to Flash's security policy. You MUST not include the null * char at the end, it is appended automatically. * @throws InvalidDataException thrown when some data that is required to generate the * flash-policy like the websocket local port could not be obtained e.g because the websocket * is not connected. */ @Override public String getFlashPolicy(WebSocket conn) throws InvalidDataException { InetSocketAddress adr = conn.getLocalSocketAddress(); if (null == adr) { throw new InvalidHandshakeException("socket not bound"); } StringBuffer sb = new StringBuffer(90); sb.append("<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\""); sb.append(adr.getPort()); sb.append("\" /></cross-domain-policy>\0"); return sb.toString(); }
/** {@inheritDoc} */ @Override public final void onSuccess(WebSocket webSocket) { this.webSocket = webSocket; for (WebSocketListener listener : listeners) { webSocket.addWebSocketListener(listener); listener.onOpen(webSocket); } if (isNonEmpty(bufferedFrames)) { for (Runnable bufferedFrame : bufferedFrames) { bufferedFrame.run(); } bufferedFrames = null; } ok.set(true); }
public final void onClose(WebSocket webSocket, int status, String reasonPhrase) { // Connect failure if (this.webSocket == null) this.webSocket = webSocket; for (WebSocketListener listener : listeners) { if (webSocket != null) { webSocket.addWebSocketListener(listener); } listener.onClose(webSocket); if (listener instanceof WebSocketCloseCodeReasonListener) { WebSocketCloseCodeReasonListener.class .cast(listener) .onClose(webSocket, status, reasonPhrase); } } }
/** * This default implementation will send a pong in response to the received ping. The pong frame * will have the same payload as the ping frame. * * @see org.usfirst.frc.team2503.lib.websocket.WebSocketListener#onWebsocketPing(WebSocket, * FrameData) */ @Override public void onWebsocketPing(WebSocket conn, FrameData f) { FrameDataImplementation resp = new FrameDataImplementation(f); resp.setOptcode(Opcode.PONG); conn.sendFrame(resp); }
/* ------------------------------------------------------------ */ public Connection handle() throws IOException { try { // handle stupid hixie random bytes if (_hixieBytes != null) { // take any available bytes from the parser buffer, which may have already been read Buffer buffer = _parser.getBuffer(); if (buffer != null && buffer.length() > 0) { int l = buffer.length(); if (l > (8 - _hixieBytes.length())) l = 8 - _hixieBytes.length(); _hixieBytes.put(buffer.peek(buffer.getIndex(), l)); buffer.skip(l); } // while we are not blocked while (_endp.isOpen()) { // do we now have enough if (_hixieBytes.length() == 8) { // we have the silly random bytes // so let's work out the stupid 16 byte reply. doTheHixieHixieShake(); _endp.flush(_hixieBytes); _hixieBytes = null; _endp.flush(); break; } // no, then let's fill int filled = _endp.fill(_hixieBytes); if (filled < 0) { _endp.flush(); _endp.close(); break; } } if (_websocket instanceof OnFrame) ((OnFrame) _websocket).onHandshake(this); _websocket.onOpen(this); return this; } // handle the framing protocol boolean progress = true; while (progress) { int flushed = _generator.flush(); int filled = _parser.parseNext(); progress = flushed > 0 || filled > 0; _endp.flush(); if (_endp instanceof AsyncEndPoint && ((AsyncEndPoint) _endp).hasProgressed()) progress = true; } } catch (IOException e) { LOG.debug(e); try { if (_endp.isOpen()) _endp.close(); } catch (IOException e2) { LOG.ignore(e2); } throw e; } finally { if (_endp.isOpen()) { if (_endp.isInputShutdown() && _generator.isBufferEmpty()) _endp.close(); else checkWriteable(); checkWriteable(); } } return this; }
protected void onWebsocketOpen() { _websocket.onOpen(this); }
/* ------------------------------------------------------------ */ public void onClose() { _websocket.onClose(WebSocketConnectionD06.CLOSE_NORMAL, ""); }
// Runnable IMPLEMENTATION ///////////////////////////////////////////////// public void run() { if (thread != null) throw new IllegalStateException( "This instance of " + getClass().getSimpleName() + " can only be started once the same time."); thread = Thread.currentThread(); try { server = ServerSocketChannel.open(); server.configureBlocking(false); server.socket().bind(address); // InetAddress.getLocalHost() selector = Selector.open(); server.register(selector, server.validOps()); } catch (IOException ex) { onWebsocketError(null, ex); return; } while (!thread.isInterrupted()) { SelectionKey key = null; WebSocket conn = null; try { selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> i = keys.iterator(); while (i.hasNext()) { key = i.next(); // Remove the current key i.remove(); // if isAcceptable == true // then a client required a connection if (key.isAcceptable()) { SocketChannel client = server.accept(); client.configureBlocking(false); WebSocket c = new WebSocket(this, Collections.singletonList(draft), client); client.register(selector, SelectionKey.OP_READ, c); } // if isReadable == true // then the server is ready to read if (key.isReadable()) { conn = (WebSocket) key.attachment(); conn.handleRead(); } // if isWritable == true // then we need to send the rest of the data to the client if (key.isValid() && key.isWritable()) { conn = (WebSocket) key.attachment(); conn.flush(); key.channel().register(selector, SelectionKey.OP_READ, conn); } } Iterator<WebSocket> it = this.connections.iterator(); while (it.hasNext()) { // We have to do this check here, and not in the thread that // adds the buffered data to the WebSocket, because the // Selector is not thread-safe, and can only be accessed // by this thread. conn = it.next(); if (conn.hasBufferedData()) { conn.flush(); // key.channel().register( selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, conn // ); } } } catch (IOException ex) { if (key != null) key.cancel(); onWebsocketError(conn, ex); // conn may be null here if (conn != null) { conn.close(CloseFrame.ABNROMAL_CLOSE); } } } }
private void handleError() { stopit(); websocket.handleReceiverError(); }
public WebSocketReceiver(DataInputStream input, WebSocket websocket) { this.input = input; this.websocket = websocket; this.eventHandler = websocket.getEventHandler(); }