@Override public short closeStatusCode() { checkClose(); if (!closeParsed) parseCloseFrame(); return this.closeStatusCode; }
@Override public WebSocketFrame textFrame(String str, boolean isFinal) { return new WebSocketFrameImpl(str, isFinal); }
private void checkClose() { if (!isClose()) throw new IllegalStateException("This should be a close frame"); }
} else if (msg instanceof WebSocketFrame) { WebSocketFrameInternal frame = decodeFrame((WebSocketFrame) msg); switch (frame.type()) { case BINARY: case CONTINUATION: case PING: chctx.writeAndFlush(new PongWebSocketFrame(frame.getBinaryData().copy())); break; case CLOSE: CloseWebSocketFrame closeFrame = new CloseWebSocketFrame(frame.closeStatusCode(), frame.closeReason()); chctx.writeAndFlush(closeFrame).addListener(ChannelFutureListener.CLOSE); closeFrameSent = true; throw new IllegalStateException("Invalid type: " + frame.type());
void handleFrame(WebSocketFrameInternal frame) { synchronized (conn) { if (frame.type() != FrameType.CLOSE) { conn.reportBytesRead(frame.length()); if (!pending.write(frame.binaryData())) { conn.doPause(); } } switch(frame.type()) { case PONG: if (pongHandler != null) { pongHandler.handle(frame.binaryData()); } break; case TEXT: case CLOSE: case BINARY: case CONTINUATION: if (frameHandler != null) { frameHandler.handle(frame); } break; } } }
WebSocketFrame encodeFrame(WebSocketFrameImpl frame) { ByteBuf buf = frame.getBinaryData(); if (buf != Unpooled.EMPTY_BUFFER) { buf = safeBuffer(buf, chctx.alloc()); } switch (frame.type()) { case BINARY: return new BinaryWebSocketFrame(frame.isFinal(), 0, buf); case TEXT: return new TextWebSocketFrame(frame.isFinal(), 0, buf); case CLOSE: return new CloseWebSocketFrame(true, 0, buf); case CONTINUATION: return new ContinuationWebSocketFrame(frame.isFinal(), 0, buf); case PONG: return new PongWebSocketFrame(buf); case PING: return new PingWebSocketFrame(buf); default: throw new IllegalStateException("Unsupported websocket msg " + frame); } }
public String textData() { return getBinaryData().toString(CharsetUtil.UTF_8); }
private void parseCloseFrame() { int length = length(); if (length < 2) { closeStatusCode = 1000; closeReason = null; } else { int index = binaryData.readerIndex(); closeStatusCode = binaryData.getShort(index); if (length == 2) { closeReason = null; } else { closeReason = binaryData.toString(index + 2, length - 2, StandardCharsets.UTF_8); } } }
@Override public S writeFrame(WebSocketFrame frame) { synchronized (conn) { checkClosed(); conn.reportBytesWritten(((WebSocketFrameInternal)frame).length()); conn.writeToChannel(conn.encodeFrame((WebSocketFrameImpl) frame)); } return (S) this; }
@Override public WebSocketFrame pongFrame(Buffer data) { return new WebSocketFrameImpl(FrameType.PONG, data.getByteBuf(), true); } }
private void handleOther(Object msg) { if (msg instanceof WebSocketFrame) { WebSocketFrameInternal frame = decodeFrame((WebSocketFrame) msg); switch (frame.type()) { case PING: chctx.writeAndFlush(new PongWebSocketFrame(frame.getBinaryData())); return; case CLOSE: CloseWebSocketFrame closeFrame = new CloseWebSocketFrame(frame.closeStatusCode(), frame.closeReason()); chctx.writeAndFlush(closeFrame).addListener(ChannelFutureListener.CLOSE); closeFrameSent = true;
@Override public String closeReason() { checkClose(); if (!closeParsed) parseCloseFrame(); return this.closeReason; }
@Override public String toString() { return getClass().getSimpleName() + "(type: " + type + ", " + "data: " + getBinaryData() + ')'; }
@Override public WebSocketFrame continuationFrame(Buffer data, boolean isFinal) { return new WebSocketFrameImpl(FrameType.CONTINUATION, data.getByteBuf(), isFinal); }
@Override public WebSocketFrame pingFrame(Buffer data) { return new WebSocketFrameImpl(FrameType.PING, data.getByteBuf(), true); }
private void writeTextFrameInternal(String str) { WebSocketFrame frame = new WebSocketFrameImpl(str); writeFrame(frame); }
@Override public WebSocketFrame binaryFrame(Buffer data, boolean isFinal) { return new WebSocketFrameImpl(FrameType.BINARY, data.getByteBuf(), isFinal); }
private void writeBinaryFrameInternal(Buffer data) { ByteBuf buf = data.getByteBuf(); WebSocketFrame frame = new WebSocketFrameImpl(FrameType.BINARY, buf); writeFrame(frame); }
WebSocketFrameInternal decodeFrame(WebSocketFrame msg) { ByteBuf payload = safeBuffer(msg, chctx.alloc()); boolean isFinal = msg.isFinalFragment(); FrameType frameType; if (msg instanceof BinaryWebSocketFrame) { frameType = FrameType.BINARY; } else if (msg instanceof CloseWebSocketFrame) { frameType = FrameType.CLOSE; } else if (msg instanceof PingWebSocketFrame) { frameType = FrameType.PING; } else if (msg instanceof PongWebSocketFrame) { frameType = FrameType.PONG; } else if (msg instanceof TextWebSocketFrame) { frameType = FrameType.TEXT; } else if (msg instanceof ContinuationWebSocketFrame) { frameType = FrameType.CONTINUATION; } else { throw new IllegalStateException("Unsupported websocket msg " + msg); } return new WebSocketFrameImpl(frameType, payload, isFinal); }
/** * Splits the provided buffer into multiple frames (which do not exceed the maximum web socket frame size) * and writes them in order to the socket. */ private void writePartialMessage(FrameType frameType, Buffer data, int offset) { int end = offset + maxWebSocketFrameSize; boolean isFinal; if (end >= data.length()) { end = data.length(); isFinal = true; } else { isFinal = false; } Buffer slice = data.slice(offset, end); WebSocketFrame frame; if (offset == 0 || !supportsContinuation) { frame = new WebSocketFrameImpl(frameType, slice.getByteBuf(), isFinal); } else { frame = WebSocketFrame.continuationFrame(slice, isFinal); } writeFrame(frame); int newOffset = offset + maxWebSocketFrameSize; if (!isFinal) { writePartialMessage(frameType, data, newOffset); } }