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);
}
}
}
}
Aggregations