@Override
    public void onWebSocketText(String message) {
      LOG.debug("onWebSocketText({})", message);
      calls.incrementAndGet();
      if (message.equalsIgnoreCase("openSessions")) {
        Collection<WebSocketSession> sessions = container.getOpenSessions();

        StringBuilder ret = new StringBuilder();
        ret.append("openSessions.size=").append(sessions.size()).append('\n');
        int idx = 0;
        for (WebSocketSession sess : sessions) {
          ret.append('[').append(idx++).append("] ").append(sess.toString()).append('\n');
        }
        session.getRemote().sendStringByFuture(ret.toString());
        session.close(StatusCode.NORMAL, "ContainerSocket");
      } else if (message.equalsIgnoreCase("calls")) {
        session.getRemote().sendStringByFuture(String.format("calls=%,d", calls.get()));
      }
    }
  // 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(WebSocket.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();
          registerWrite();

          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, (ByteChannel) conn.channel)) {
                  conn.inQueue.put(buf);
                  queue(conn);
                  i.remove();
                  if (conn.channel instanceof WrappedByteChannel) {
                    if (((WrappedByteChannel) conn.channel).isNeedRead()) {
                      iqueue.add(conn);
                    }
                  }
                } else {
                  pushBuffer(buf);
                }
              } catch (IOException e) {
                pushBuffer(buf);
                throw e;
              } catch (RuntimeException e) {
                pushBuffer(buf);
                throw e;
              }
            }
            if (key.isWritable()) {
              conn = (WebSocketImpl) key.attachment();
              if (SocketChannelIOHelper.batch(conn, (ByteChannel) 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);
              conn.inQueue.put(buf);
              queue(conn);
            } finally {
              pushBuffer(buf);
            }
          }
        } catch (CancelledKeyException e) {
          // an other thread may cancel the key
        } catch (IOException ex) {
          if (key != null) key.cancel();
          handleIOException(conn, ex);
        } catch (InterruptedException e) {
          return; // FIXME controlled shutdown
        }
      }

    } catch (RuntimeException e) {
      // should hopefully never occur
      handleFatal(null, e);
    }
  }
Example #3
0
  // Runnable IMPLEMENTATION /////////////////////////////////////////////////
  public void run() {
    if (selectorthread != null)
      throw new IllegalStateException(
          "This instance of "
              + getClass().getSimpleName()
              + " can only be started once the same time.");
    selectorthread = Thread.currentThread();
    selectorthread.setName("WebsocketSelector" + selectorthread.getId());
    try {
      server = ServerSocketChannel.open();
      server.configureBlocking(false);
      ServerSocket socket = server.socket();
      socket.setReceiveBufferSize(WebSocket.RCVBUF);
      socket.bind(address);
      selector = Selector.open();
      server.register(selector, server.validOps());
    } catch (IOException ex) {
      onWebsocketError(null, ex);
      return;
    }
    try {
      while (!selectorthread.isInterrupted()) {
        SelectionKey key = null;
        WebSocketImpl conn = null;
        try {
          selector.select();
          registerWrite();

          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()) {
              SocketChannel channel = server.accept();
              channel.configureBlocking(false);
              WebSocketImpl c = wsf.createWebSocket(this, drafts, channel.socket());
              c.key = channel.register(selector, SelectionKey.OP_READ, c);
              c.ioobject = wsf.wrapChannel(channel);
              i.remove();
              allocateBuffers(c);
              continue;
            }

            if (key.isReadable()) {
              conn = (WebSocketImpl) key.attachment();
              ByteBuffer buf = takeBuffer();
              try {
                if (SocketChannelIOHelper.read(buf, conn, (ByteChannel) conn.ioobject)) {
                  conn.in.put(buf);
                  queue(conn);
                  i.remove();
                } else {
                  pushBuffer(buf);
                }
              } catch (IOException e) {
                pushBuffer(buf);
                throw e;
              } catch (RuntimeException e) {
                pushBuffer(buf);
                throw e;
              }
            }
            if (key.isWritable()) {
              conn = (WebSocketImpl) key.attachment();
              if (SocketChannelIOHelper.batch(conn, (ByteChannel) conn.ioobject)) {
                if (key.isValid())
                  key.channel().register(selector, SelectionKey.OP_READ, key.attachment());
              }
            }
          }
        } catch (CancelledKeyException e) {
          // an other thread may cancel the key
        } catch (IOException ex) {
          if (key != null) key.cancel();
          handleIOException(conn, ex);
        } catch (InterruptedException e) {
          return;
        }
      }
    } catch (RuntimeException e) {
      // should hopefully never occur
      handleFatal(null, e);
    }
  }