Search in sources :

Example 1 with WrappedByteChannel

use of org.java_websocket.WrappedByteChannel in project quorrabot by GloriousEggroll.

the class WebSocketServer method run.

// Runnable IMPLEMENTATION /////////////////////////////////////////////////
public void run() {
    synchronized (this) {
        if (selectorthread != null) {
            throw new IllegalStateException(getClass().getName() + " can only be started once.");
        }
        selectorthread = Thread.currentThread();
        if (isclosed.get()) {
            return;
        }
    }
    selectorthread.setName("WebsocketSelector" + selectorthread.getId());
    try {
        server = ServerSocketChannel.open();
        server.configureBlocking(false);
        ServerSocket socket = server.socket();
        socket.setReceiveBufferSize(WebSocketImpl.RCVBUF);
        socket.bind(address);
        selector = Selector.open();
        server.register(selector, server.validOps());
    } catch (IOException ex) {
        handleFatal(null, ex);
        return;
    }
    try {
        while (!selectorthread.isInterrupted()) {
            SelectionKey key = null;
            WebSocketImpl conn = null;
            try {
                selector.select();
                Set<SelectionKey> keys = selector.selectedKeys();
                Iterator<SelectionKey> i = keys.iterator();
                while (i.hasNext()) {
                    key = i.next();
                    if (!key.isValid()) {
                        // Object o = key.attachment();
                        continue;
                    }
                    if (key.isAcceptable()) {
                        if (!onConnect(key)) {
                            key.cancel();
                            continue;
                        }
                        SocketChannel channel = server.accept();
                        channel.configureBlocking(false);
                        WebSocketImpl w = wsf.createWebSocket(this, drafts, channel.socket());
                        w.key = channel.register(selector, SelectionKey.OP_READ, w);
                        w.channel = wsf.wrapChannel(channel, w.key);
                        i.remove();
                        allocateBuffers(w);
                        continue;
                    }
                    if (key.isReadable()) {
                        conn = (WebSocketImpl) key.attachment();
                        ByteBuffer buf = takeBuffer();
                        try {
                            if (SocketChannelIOHelper.read(buf, conn, conn.channel)) {
                                if (buf.hasRemaining()) {
                                    conn.inQueue.put(buf);
                                    queue(conn);
                                    i.remove();
                                    if (conn.channel instanceof WrappedByteChannel) {
                                        if (((WrappedByteChannel) conn.channel).isNeedRead()) {
                                            iqueue.add(conn);
                                        }
                                    }
                                } else {
                                    pushBuffer(buf);
                                }
                            } else {
                                pushBuffer(buf);
                            }
                        } catch (IOException e) {
                            pushBuffer(buf);
                            throw e;
                        }
                    }
                    if (key.isWritable()) {
                        conn = (WebSocketImpl) key.attachment();
                        if (SocketChannelIOHelper.batch(conn, conn.channel)) {
                            if (key.isValid()) {
                                key.interestOps(SelectionKey.OP_READ);
                            }
                        }
                    }
                }
                while (!iqueue.isEmpty()) {
                    conn = iqueue.remove(0);
                    WrappedByteChannel c = ((WrappedByteChannel) conn.channel);
                    ByteBuffer buf = takeBuffer();
                    try {
                        if (SocketChannelIOHelper.readMore(buf, conn, c)) {
                            iqueue.add(conn);
                        }
                        if (buf.hasRemaining()) {
                            conn.inQueue.put(buf);
                            queue(conn);
                        } else {
                            pushBuffer(buf);
                        }
                    } catch (IOException e) {
                        pushBuffer(buf);
                        throw e;
                    }
                }
            } catch (CancelledKeyException e) {
            // an other thread may cancel the key
            } catch (ClosedByInterruptException e) {
                // do the same stuff as when InterruptedException is thrown
                return;
            } catch (IOException ex) {
                if (key != null) {
                    key.cancel();
                }
                handleIOException(key, conn, ex);
            } catch (InterruptedException e) {
                // FIXME controlled shutdown (e.g. take care of buffermanagement)
                return;
            }
        }
    } catch (RuntimeException e) {
        // should hopefully never occur
        handleFatal(null, e);
    } finally {
        if (decoders != null) {
            for (WebSocketWorker w : decoders) {
                w.interrupt();
            }
        }
        if (server != null) {
            try {
                server.close();
            } catch (IOException e) {
                onError(null, e);
            }
        }
    }
}
Also used : SelectionKey(java.nio.channels.SelectionKey) SocketChannel(java.nio.channels.SocketChannel) ServerSocketChannel(java.nio.channels.ServerSocketChannel) CancelledKeyException(java.nio.channels.CancelledKeyException) ServerSocket(java.net.ServerSocket) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) ClosedByInterruptException(java.nio.channels.ClosedByInterruptException) WrappedByteChannel(org.java_websocket.WrappedByteChannel) WebSocketImpl(org.java_websocket.WebSocketImpl)

Aggregations

IOException (java.io.IOException)1 ServerSocket (java.net.ServerSocket)1 ByteBuffer (java.nio.ByteBuffer)1 CancelledKeyException (java.nio.channels.CancelledKeyException)1 ClosedByInterruptException (java.nio.channels.ClosedByInterruptException)1 SelectionKey (java.nio.channels.SelectionKey)1 ServerSocketChannel (java.nio.channels.ServerSocketChannel)1 SocketChannel (java.nio.channels.SocketChannel)1 WebSocketImpl (org.java_websocket.WebSocketImpl)1 WrappedByteChannel (org.java_websocket.WrappedByteChannel)1