Class WebSocketServer

  • All Implemented Interfaces:
    java.lang.Runnable, WebSocketListener

    public abstract class WebSocketServer
    extends AbstractWebSocket
    implements java.lang.Runnable
    WebSocketServer is an abstract class that only takes care of the HTTP handshake portion of WebSockets. It's up to a subclass to add functionality/purpose to the server.
    • Field Detail

      • AVAILABLE_PROCESSORS

        private static final int AVAILABLE_PROCESSORS
      • log

        private final org.slf4j.Logger log
        Logger instance
        Since:
        1.4.0
      • connections

        private final java.util.Collection<WebSocket> connections
        Holds the list of active WebSocket connections. "Active" means WebSocket handshake is complete and socket can be written to, or read from.
      • address

        private final java.net.InetSocketAddress address
        The port number that this WebSocket server should listen on. Default is WebSocketImpl.DEFAULT_PORT.
      • server

        private java.nio.channels.ServerSocketChannel server
        The socket channel for this WebSocket server.
      • selector

        private java.nio.channels.Selector selector
        The 'Selector' used to get event keys from the underlying socket.
      • drafts

        private java.util.List<Draft> drafts
        The Draft of the WebSocket protocol the Server is adhering to.
      • selectorthread

        private java.lang.Thread selectorthread
      • isclosed

        private final java.util.concurrent.atomic.AtomicBoolean isclosed
      • buffers

        private java.util.concurrent.BlockingQueue<java.nio.ByteBuffer> buffers
      • queueinvokes

        private int queueinvokes
      • queuesize

        private final java.util.concurrent.atomic.AtomicInteger queuesize
      • maxPendingConnections

        private int maxPendingConnections
        Attribute which allows you to configure the socket "backlog" parameter which determines how many client connections can be queued.
        Since:
        1.5.0
    • Constructor Detail

      • WebSocketServer

        public WebSocketServer()
        Creates a WebSocketServer that will attempt to listen on port WebSocketImpl.DEFAULT_PORT.
        See Also:
        more details here
      • WebSocketServer

        public WebSocketServer​(java.net.InetSocketAddress address)
        Creates a WebSocketServer that will attempt to bind/listen on the given address.
        Parameters:
        address - The address to listen to
        See Also:
        more details here
      • WebSocketServer

        public WebSocketServer​(java.net.InetSocketAddress address,
                               int decodercount)
        Parameters:
        address - The address (host:port) this server should listen on.
        decodercount - The number of WebSocketServer.WebSocketWorkers that will be used to process the incoming network data. By default this will be Runtime.getRuntime().availableProcessors()
        See Also:
        more details here
      • WebSocketServer

        public WebSocketServer​(java.net.InetSocketAddress address,
                               java.util.List<Draft> drafts)
        Parameters:
        address - The address (host:port) this server should listen on.
        drafts - The versions of the WebSocket protocol that this server instance should comply to. Clients that use an other protocol version will be rejected.
        See Also:
        more details here
      • WebSocketServer

        public WebSocketServer​(java.net.InetSocketAddress address,
                               int decodercount,
                               java.util.List<Draft> drafts)
        Parameters:
        address - The address (host:port) this server should listen on.
        decodercount - The number of WebSocketServer.WebSocketWorkers that will be used to process the incoming network data. By default this will be Runtime.getRuntime().availableProcessors()
        drafts - The versions of the WebSocket protocol that this server instance should comply to. Clients that use an other protocol version will be rejected.
        See Also:
        more details here
      • WebSocketServer

        public WebSocketServer​(java.net.InetSocketAddress address,
                               int decodercount,
                               java.util.List<Draft> drafts,
                               java.util.Collection<WebSocket> connectionscontainer)
        Creates a WebSocketServer that will attempt to bind/listen on the given address, and comply with Draft version draft.
        Parameters:
        address - The address (host:port) this server should listen on.
        decodercount - The number of WebSocketServer.WebSocketWorkers that will be used to process the incoming network data. By default this will be Runtime.getRuntime().availableProcessors()
        drafts - The versions of the WebSocket protocol that this server instance should comply to. Clients that use an other protocol version will be rejected.
        connectionscontainer - Allows to specify a collection that will be used to store the websockets in.
        If you plan to often iterate through the currently connected websockets you may want to use a collection that does not require synchronization like a CopyOnWriteArraySet. In that case make sure that you overload removeConnection(WebSocket) and addConnection(WebSocket).
        By default a HashSet will be used.
        See Also:
        for more control over syncronized operation, more about drafts
    • Method Detail

      • start

        public void start()
        Starts the server selectorthread that binds to the currently set port number and listeners for WebSocket connection requests. Creates a fixed thread pool with the size AVAILABLE_PROCESSORS
        May only be called once. Alternatively you can call run() directly.
        Throws:
        java.lang.IllegalStateException - Starting an instance again
      • stop

        public void stop​(int timeout)
                  throws java.lang.InterruptedException
        Closes all connected clients sockets, then closes the underlying ServerSocketChannel, effectively killing the server socket selectorthread, freeing the port the server was bound to and stops all internal workerthreads. If this method is called before the server is started it will never start.
        Parameters:
        timeout - Specifies how many milliseconds the overall close handshaking may take altogether before the connections are closed without proper close handshaking.
        Throws:
        java.lang.InterruptedException - Interrupt
      • stop

        public void stop()
                  throws java.io.IOException,
                         java.lang.InterruptedException
        Throws:
        java.io.IOException
        java.lang.InterruptedException
      • getConnections

        public java.util.Collection<WebSocket> getConnections()
        Returns all currently connected clients. This collection does not allow any modification e.g. removing a client.
        Specified by:
        getConnections in class AbstractWebSocket
        Returns:
        A unmodifiable collection of all currently connected clients
        Since:
        1.3.8
      • getAddress

        public java.net.InetSocketAddress getAddress()
      • getPort

        public int getPort()
        Gets the port number that this server listens on.
        Returns:
        The port number.
      • getDraft

        public java.util.List<Draft> getDraft()
        Get the list of active drafts
        Returns:
        the available drafts for this server
      • setMaxPendingConnections

        public void setMaxPendingConnections​(int numberOfConnections)
        Set the requested maximum number of pending connections on the socket. The exact semantics are implementation specific. The value provided should be greater than 0. If it is less than or equal to 0, then an implementation specific default will be used. This option will be passed as "backlog" parameter to ServerSocket.bind(SocketAddress, int)
        Since:
        1.5.0
      • getMaxPendingConnections

        public int getMaxPendingConnections()
        Returns the currently configured maximum number of pending connections.
        Since:
        1.5.0
        See Also:
        setMaxPendingConnections(int)
      • run

        public void run()
        Specified by:
        run in interface java.lang.Runnable
      • doAdditionalRead

        private void doAdditionalRead()
                               throws java.lang.InterruptedException,
                                      java.io.IOException
        Do an additional read
        Throws:
        java.lang.InterruptedException - thrown by taking a buffer
        java.io.IOException - if an error happened during read
      • doAccept

        private void doAccept​(java.nio.channels.SelectionKey key,
                              java.util.Iterator<java.nio.channels.SelectionKey> i)
                       throws java.io.IOException,
                              java.lang.InterruptedException
        Execute a accept operation
        Parameters:
        key - the selectionkey to read off
        i - the iterator for the selection keys
        Throws:
        java.lang.InterruptedException - thrown by taking a buffer
        java.io.IOException - if an error happened during accept
      • doRead

        private boolean doRead​(java.nio.channels.SelectionKey key,
                               java.util.Iterator<java.nio.channels.SelectionKey> i)
                        throws java.lang.InterruptedException,
                               WrappedIOException
        Execute a read operation
        Parameters:
        key - the selectionkey to read off
        i - the iterator for the selection keys
        Returns:
        true, if the read was successful, or false if there was an error
        Throws:
        java.lang.InterruptedException - thrown by taking a buffer
        java.io.IOException - if an error happened during read
        WrappedIOException
      • doWrite

        private void doWrite​(java.nio.channels.SelectionKey key)
                      throws WrappedIOException
        Execute a write operation
        Parameters:
        key - the selectionkey to write on
        Throws:
        java.io.IOException - if an error happened during batch
        WrappedIOException
      • doSetupSelectorAndServerThread

        private boolean doSetupSelectorAndServerThread()
        Setup the selector thread as well as basic server settings
        Returns:
        true, if everything was successful, false if some error happened
      • doEnsureSingleThread

        private boolean doEnsureSingleThread()
        The websocket server can only be started once
        Returns:
        true, if the server can be started, false if already a thread is running
      • doServerShutdown

        private void doServerShutdown()
        Clean up everything after a shutdown
      • allocateBuffers

        protected void allocateBuffers​(WebSocket c)
                                throws java.lang.InterruptedException
        Throws:
        java.lang.InterruptedException
      • releaseBuffers

        protected void releaseBuffers​(WebSocket c)
                               throws java.lang.InterruptedException
        Throws:
        java.lang.InterruptedException
      • createBuffer

        public java.nio.ByteBuffer createBuffer()
      • queue

        protected void queue​(WebSocketImpl ws)
                      throws java.lang.InterruptedException
        Throws:
        java.lang.InterruptedException
      • takeBuffer

        private java.nio.ByteBuffer takeBuffer()
                                        throws java.lang.InterruptedException
        Throws:
        java.lang.InterruptedException
      • pushBuffer

        private void pushBuffer​(java.nio.ByteBuffer buf)
                         throws java.lang.InterruptedException
        Throws:
        java.lang.InterruptedException
      • handleIOException

        private void handleIOException​(java.nio.channels.SelectionKey key,
                                       WebSocket conn,
                                       java.io.IOException ex)
      • handleFatal

        private void handleFatal​(WebSocket conn,
                                 java.lang.Exception e)
      • onWebsocketMessage

        public final void onWebsocketMessage​(WebSocket conn,
                                             java.lang.String message)
        Description copied from interface: WebSocketListener
        Called when an entire text frame has been received. Do whatever you want here...
        Specified by:
        onWebsocketMessage in interface WebSocketListener
        Parameters:
        conn - The WebSocket instance this event is occurring on.
        message - The UTF-8 decoded message that was received.
      • onWebsocketMessage

        public final void onWebsocketMessage​(WebSocket conn,
                                             java.nio.ByteBuffer blob)
        Description copied from interface: WebSocketListener
        Called when an entire binary frame has been received. Do whatever you want here...
        Specified by:
        onWebsocketMessage in interface WebSocketListener
        Parameters:
        conn - The WebSocket instance this event is occurring on.
        blob - The binary message that was received.
      • onWebsocketOpen

        public final void onWebsocketOpen​(WebSocket conn,
                                          Handshakedata handshake)
        Description copied from interface: WebSocketListener
        Called after onHandshakeReceived returns true. Indicates that a complete WebSocket connection has been established, and we are ready to send/receive data.
        Specified by:
        onWebsocketOpen in interface WebSocketListener
        Parameters:
        conn - The WebSocket instance this event is occuring on.
        handshake - The handshake of the websocket instance
      • onWebsocketClose

        public final void onWebsocketClose​(WebSocket conn,
                                           int code,
                                           java.lang.String reason,
                                           boolean remote)
        Description copied from interface: WebSocketListener
        Called after WebSocket#close is explicity called, or when the other end of the WebSocket connection is closed.
        Specified by:
        onWebsocketClose in interface WebSocketListener
        Parameters:
        conn - The WebSocket instance this event is occuring on.
        code - The codes can be looked up here: CloseFrame
        reason - Additional information string
        remote - Returns whether or not the closing of the connection was initiated by the remote host.
      • removeConnection

        protected boolean removeConnection​(WebSocket ws)
        This method performs remove operations on the connection and therefore also gives control over whether the operation shall be synchronized

        WebSocketServer(InetSocketAddress, int, List, Collection) allows to specify a collection which will be used to store current connections in.
        Depending on the type on the connection, modifications of that collection may have to be synchronized.

        Parameters:
        ws - The Websocket connection which should be removed
        Returns:
        Removing connection successful
      • addConnection

        protected boolean addConnection​(WebSocket ws)
        Parameters:
        ws - the Websocket connection which should be added
        Returns:
        Adding connection successful
        See Also:
        removeConnection(WebSocket)
      • onWebsocketError

        public final void onWebsocketError​(WebSocket conn,
                                           java.lang.Exception ex)
        Description copied from interface: WebSocketListener
        Called if an exception worth noting occurred. If an error causes the connection to fail onClose will be called additionally afterwards.
        Specified by:
        onWebsocketError in interface WebSocketListener
        Parameters:
        conn - The WebSocket instance this event is occuring on.
        ex - The exception that occurred.
        Might be null if the exception is not related to any specific connection. For example if the server port could not be bound.
      • onWriteDemand

        public final void onWriteDemand​(WebSocket w)
        Description copied from interface: WebSocketListener
        This method is used to inform the selector thread that there is data queued to be written to the socket.
        Specified by:
        onWriteDemand in interface WebSocketListener
        Parameters:
        w - The WebSocket instance this event is occuring on.
      • onWebsocketCloseInitiated

        public void onWebsocketCloseInitiated​(WebSocket conn,
                                              int code,
                                              java.lang.String reason)
        Description copied from interface: WebSocketListener
        send when this peer sends a close handshake
        Specified by:
        onWebsocketCloseInitiated in interface WebSocketListener
        Parameters:
        conn - The WebSocket instance this event is occuring on.
        code - The codes can be looked up here: CloseFrame
        reason - Additional information string
      • onWebsocketClosing

        public void onWebsocketClosing​(WebSocket conn,
                                       int code,
                                       java.lang.String reason,
                                       boolean remote)
        Description copied from interface: WebSocketListener
        Called as soon as no further frames are accepted
        Specified by:
        onWebsocketClosing in interface WebSocketListener
        Parameters:
        conn - The WebSocket instance this event is occuring on.
        code - The codes can be looked up here: CloseFrame
        reason - Additional information string
        remote - Returns whether or not the closing of the connection was initiated by the remote host.
      • onCloseInitiated

        public void onCloseInitiated​(WebSocket conn,
                                     int code,
                                     java.lang.String reason)
      • onClosing

        public void onClosing​(WebSocket conn,
                              int code,
                              java.lang.String reason,
                              boolean remote)
      • getSocket

        private java.net.Socket getSocket​(WebSocket conn)
        Getter to return the socket used by this specific connection
        Parameters:
        conn - The specific connection
        Returns:
        The socket used by this connection
      • onOpen

        public abstract void onOpen​(WebSocket conn,
                                    ClientHandshake handshake)
        Called after an opening handshake has been performed and the given websocket is ready to be written on.
        Parameters:
        conn - The WebSocket instance this event is occuring on.
        handshake - The handshake of the websocket instance
      • onClose

        public abstract void onClose​(WebSocket conn,
                                     int code,
                                     java.lang.String reason,
                                     boolean remote)
        Called after the websocket connection has been closed.
        Parameters:
        conn - The WebSocket instance this event is occuring on.
        code - The codes can be looked up here: CloseFrame
        reason - Additional information string
        remote - Returns whether or not the closing of the connection was initiated by the remote host.
      • onMessage

        public abstract void onMessage​(WebSocket conn,
                                       java.lang.String message)
        Callback for string messages received from the remote host
        Parameters:
        conn - The WebSocket instance this event is occuring on.
        message - The UTF-8 decoded message that was received.
        See Also:
        onMessage(WebSocket, ByteBuffer)
      • onError

        public abstract void onError​(WebSocket conn,
                                     java.lang.Exception ex)
        Called when errors occurs. If an error causes the websocket connection to fail onClose(WebSocket, int, String, boolean) will be called additionally.
        This method will be called primarily because of IO or protocol errors.
        If the given exception is an RuntimeException that probably means that you encountered a bug.
        Parameters:
        conn - Can be null if there error does not belong to one specific websocket. For example if the servers port could not be bound.
        ex - The exception causing this error
      • onStart

        public abstract void onStart()
        Called when the server started up successfully. If any error occured, onError is called instead.
      • onMessage

        public void onMessage​(WebSocket conn,
                              java.nio.ByteBuffer message)
        Callback for binary messages received from the remote host
        Parameters:
        conn - The WebSocket instance this event is occurring on.
        message - The binary message that was received.
        See Also:
        onMessage(WebSocket, ByteBuffer)
      • broadcast

        public void broadcast​(java.lang.String text)
        Send a text to all connected endpoints
        Parameters:
        text - the text to send to the endpoints
      • broadcast

        public void broadcast​(byte[] data)
        Send a byte array to all connected endpoints
        Parameters:
        data - the data to send to the endpoints
      • broadcast

        public void broadcast​(java.nio.ByteBuffer data)
        Send a ByteBuffer to all connected endpoints
        Parameters:
        data - the data to send to the endpoints
      • broadcast

        public void broadcast​(byte[] data,
                              java.util.Collection<WebSocket> clients)
        Send a byte array to a specific collection of websocket connections
        Parameters:
        data - the data to send to the endpoints
        clients - a collection of endpoints to whom the text has to be send
      • broadcast

        public void broadcast​(java.nio.ByteBuffer data,
                              java.util.Collection<WebSocket> clients)
        Send a ByteBuffer to a specific collection of websocket connections
        Parameters:
        data - the data to send to the endpoints
        clients - a collection of endpoints to whom the text has to be send
      • broadcast

        public void broadcast​(java.lang.String text,
                              java.util.Collection<WebSocket> clients)
        Send a text to a specific collection of websocket connections
        Parameters:
        text - the text to send to the endpoints
        clients - a collection of endpoints to whom the text has to be send
      • doBroadcast

        private void doBroadcast​(java.lang.Object data,
                                 java.util.Collection<WebSocket> clients)
        Private method to cache all the frames to improve memory footprint and conversion time
        Parameters:
        data - the data to broadcast
        clients - the clients to send the message to
      • fillFrames

        private void fillFrames​(Draft draft,
                                java.util.Map<Draft,​java.util.List<Framedata>> draftFrames,
                                java.lang.String sData,
                                java.nio.ByteBuffer bData)
        Fills the draftFrames with new data for the broadcast
        Parameters:
        draft - The draft to use
        draftFrames - The list of frames per draft to fill
        sData - the string data, can be null
        bData - the bytebuffer data, can be null