/** * Set the RSV which is used for extensions. * <p> * This can only be set before any write or transfer operations where passed * to the wrapped {@link org.xnio.channels.StreamSinkChannel}, after that an {@link IllegalStateException} will be thrown. * */ public void setRsv(int rsv) { if (!areExtensionsSupported() && rsv != 0) { throw WebSocketMessages.MESSAGES.extensionsNotSupported(); } this.rsv = rsv; }
private static void sendBlockingInternal(final PooledByteBuffer pooledData, WebSocketFrameType type, final WebSocketChannel wsChannel) throws IOException { boolean closePooledData = true; try { StreamSinkFrameChannel channel = wsChannel.send(type); // TODO chunk data into some MTU-like thing to control packet size closePooledData = false; // channel.send takes ownership of pooledData so it no longer needs to be closed if(!channel.send(pooledData)) { throw WebSocketMessages.MESSAGES.unableToSendOnNewChannel(); } channel.shutdownWrites(); while (!channel.flush()) { channel.awaitWritable(); } if (type == WebSocketFrameType.CLOSE && wsChannel.isCloseFrameReceived()) { IoUtils.safeClose(wsChannel); } } finally { if (closePooledData) { pooledData.close(); } } }
public WebSocketChannel getWebSocketChannel() { return getChannel(); }
@Override public void flush() throws IOException { checkClosed(); if(Thread.currentThread() == sender.getIoThread()) { throw UndertowMessages.MESSAGES.awaitCalledFromIoThread(); } sender.flush(); }
/** * Send a Close frame without a payload */ public void sendClose() throws IOException { closeReason = ""; closeCode = CloseMessage.NORMAL_CLOSURE; StreamSinkFrameChannel closeChannel = send(WebSocketFrameType.CLOSE); closeChannel.shutdownWrites(); if (!closeChannel.flush()) { closeChannel.getWriteSetter().set(ChannelListeners.flushingChannelListener( null, new ChannelExceptionHandler<StreamSinkChannel>() { @Override public void handleException(final StreamSinkChannel channel, final IOException exception) { IoUtils.safeClose(WebSocketChannel.this); } } )); closeChannel.resumeWrites(); } }
private static void setupTimeout(final StreamSinkFrameChannel channel, long timeoutmillis) { final XnioExecutor.Key key = WorkerUtils.executeAfter(channel.getIoThread(), new Runnable() { @Override public void run() { if (channel.isOpen()) { IoUtils.safeClose(channel); } } }, timeoutmillis, TimeUnit.MILLISECONDS); channel.getCloseSetter().set(new ChannelListener<StreamSinkFrameChannel>() { @Override public void handleEvent(StreamSinkFrameChannel channel) { key.remove(); } }); }
if (newFrame.getType() != WebSocketFrameType.PONG && newFrame.getType() != WebSocketFrameType.PING) { StreamSinkFrameChannel order = strictOrderQueue.peek(); if (order != null) { if (order != newFrame && order.isOpen()) { if (newFrame.getType() != WebSocketFrameType.CLOSE) { return false; } else if (!newFrame.getWebSocketChannel().isCloseFrameReceived() && !immediateCloseFrame) { return false; if(order == newFrame && newFrame.isFinalFragment()) { strictOrderQueue.poll(); newFrame.markBroken(); return true; if (!newFrame.isWritesShutdown()) { } else if (newFrame.getType() == WebSocketFrameType.PING || newFrame.getType() == WebSocketFrameType.PONG) { WebSocketFrameType type = pendingFrames.get(index).getType(); if(type != WebSocketFrameType.PING && type != WebSocketFrameType.PONG) { pendingFrames.add(index, newFrame); } else if (newFrame.getType() == WebSocketFrameType.PING || newFrame.getType() == WebSocketFrameType.PONG) {
@Override public void write(byte[] b, int off, int len) throws IOException { checkClosed(); if(Thread.currentThread() == sender.getIoThread()) { throw UndertowMessages.MESSAGES.awaitCalledFromIoThread(); } Channels.writeBlocking(sender, ByteBuffer.wrap(b, off, len)); }
@Override public void handleException(StreamSinkFrameChannel channel, IOException exception) { if (callback != null) { callback.onError(wsChannel, context, exception); } IoUtils.safeClose(channel, wsChannel); //we explicitly set the channel to null, as in some situations this //listener may get invoked twice channel.getWriteSetter().set(null); } }
@Override public void frameAdded(StreamSinkFrameChannel addedFrame, List<StreamSinkFrameChannel> pendingFrames, Deque<StreamSinkFrameChannel> holdFrames) { if (addedFrame.isFinalFragment()) { while (true) { StreamSinkFrameChannel frame = strictOrderQueue.peek(); if(frame == null) { break; } if(holdFrames.contains(frame)) { if(insertFrame(frame, pendingFrames)) { holdFrames.remove(frame); } else { break; } } else { break; } } while (!holdFrames.isEmpty()) { StreamSinkFrameChannel frame = holdFrames.peek(); if (insertFrame(frame, pendingFrames)) { holdFrames.poll(); } else { return; } } } }
compress.setInput(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining()); } else { inputBuffer = toArrayBacked(buffer, channel.getWebSocketChannel().getBufferPool()); compress.setInput(inputBuffer.getBuffer().array(), inputBuffer.getBuffer().arrayOffset() + inputBuffer.getBuffer().position(), inputBuffer.getBuffer().remaining()); PooledByteBuffer output = allocateBufferWithArray(channel.getWebSocketChannel(), 0); // first pass ByteBuffer outputBuffer = output.getBuffer(); output = largerBuffer(output, channel.getWebSocketChannel(), outputBuffer.capacity() * 2); outputBuffer = output.getBuffer();
private static <T> void flushChannelAsync(final WebSocketChannel wsChannel, final WebSocketCallback<T> callback, StreamSinkFrameChannel channel, final T context, long timeoutmillis) throws IOException { final WebSocketFrameType type = channel.getType(); channel.shutdownWrites(); if (!channel.flush()) { channel.getWriteSetter().set(flushingChannelListener( new ChannelListener<StreamSinkFrameChannel>() { @Override setupTimeout(channel, timeoutmillis); channel.resumeWrites(); return;
if (newFrame.getType() != WebSocketFrameType.PONG && newFrame.getType() != WebSocketFrameType.PING) { StreamSinkFrameChannel order = strictOrderQueue.peek(); if (order != null) { if (order != newFrame && order.isOpen()) { if (newFrame.getType() != WebSocketFrameType.CLOSE) { return false; } else if (!newFrame.getWebSocketChannel().isCloseFrameReceived() && !immediateCloseFrame) { return false; if(order == newFrame && newFrame.isFinalFragment()) { strictOrderQueue.poll(); newFrame.markBroken(); return true; if (!newFrame.isWritesShutdown()) { } else if (newFrame.getType() == WebSocketFrameType.PING || newFrame.getType() == WebSocketFrameType.PONG) { WebSocketFrameType type = pendingFrames.get(index).getType(); if(type != WebSocketFrameType.PING && type != WebSocketFrameType.PONG) { pendingFrames.add(index, newFrame); } else if (newFrame.getType() == WebSocketFrameType.PING || newFrame.getType() == WebSocketFrameType.PONG) {
@Override public void flush() throws IOException { checkClosed(); if(Thread.currentThread() == sender.getIoThread()) { throw UndertowMessages.MESSAGES.awaitCalledFromIoThread(); } sender.flush(); }
private static void setupTimeout(final StreamSinkFrameChannel channel, long timeoutmillis) { final XnioExecutor.Key key = WorkerUtils.executeAfter(channel.getIoThread(), new Runnable() { @Override public void run() { if (channel.isOpen()) { IoUtils.safeClose(channel); } } }, timeoutmillis, TimeUnit.MILLISECONDS); channel.getCloseSetter().set(new ChannelListener<StreamSinkFrameChannel>() { @Override public void handleEvent(StreamSinkFrameChannel channel) { key.remove(); } }); }
@Override public void write(int b) throws IOException { checkClosed(); if(Thread.currentThread() == sender.getIoThread()) { throw UndertowMessages.MESSAGES.awaitCalledFromIoThread(); } Channels.writeBlocking(sender, ByteBuffer.wrap(new byte[]{(byte) b})); }
@Override public void handleEvent(StreamSinkFrameChannel channel) { if (callback != null) { callback.complete(wsChannel, context); } if (type == WebSocketFrameType.CLOSE && wsChannel.isCloseFrameReceived()) { IoUtils.safeClose(wsChannel); } //we explicitly set the channel to null, as in some situations this //listener may get invoked twice channel.getWriteSetter().set(null); } }, new ChannelExceptionHandler<StreamSinkFrameChannel>() {
@Override public void frameAdded(StreamSinkFrameChannel addedFrame, List<StreamSinkFrameChannel> pendingFrames, Deque<StreamSinkFrameChannel> holdFrames) { if (addedFrame.isFinalFragment()) { while (true) { StreamSinkFrameChannel frame = strictOrderQueue.peek(); if(frame == null) { break; } if(holdFrames.contains(frame)) { if(insertFrame(frame, pendingFrames)) { holdFrames.remove(frame); } else { break; } } else { break; } } while (!holdFrames.isEmpty()) { StreamSinkFrameChannel frame = holdFrames.peek(); if (insertFrame(frame, pendingFrames)) { holdFrames.poll(); } else { return; } } } }