@Override protected void encode(ChannelHandlerContext chc, SubscribeMessage message, ByteBuf out) { if (message.subscriptions().isEmpty()) { throw new IllegalArgumentException("Found a subscribe message with empty topics"); } if (message.getQos() != AbstractMessage.QOSType.LEAST_ONE) { throw new IllegalArgumentException( "Expected a message with QOS 1, found " + message.getQos()); } ByteBuf variableHeaderBuff = chc.alloc().buffer(4); ByteBuf buff = null; try { variableHeaderBuff.writeShort(message.getMessageID()); for (SubscribeMessage.Couple c : message.subscriptions()) { variableHeaderBuff.writeBytes(Utils.encodeString(c.topicFilter)); variableHeaderBuff.writeByte(c.qos); } int variableHeaderSize = variableHeaderBuff.readableBytes(); byte flags = Utils.encodeFlags(message); buff = chc.alloc().buffer(2 + variableHeaderSize); buff.writeByte(AbstractMessage.SUBSCRIBE << 4 | flags); buff.writeBytes(Utils.encodeRemainingLength(variableHeaderSize)); buff.writeBytes(variableHeaderBuff); out.writeBytes(buff); } finally { variableHeaderBuff.release(); buff.release(); } }
private void handleHTTP(OutPacketMessage msg, ChannelHandlerContext ctx, ChannelPromise promise) throws IOException { Channel channel = ctx.channel(); Attribute<Boolean> attr = channel.attr(WRITE_ONCE); Queue<Packet> queue = msg.getClientHead().getPacketsQueue(msg.getTransport()); if (!channel.isActive() || queue.isEmpty() || !attr.compareAndSet(null, true)) { promise.setSuccess(); return; } ByteBuf out = encoder.allocateBuffer(ctx.alloc()); Boolean b64 = ctx.channel().attr(EncoderHandler.B64).get(); if (b64 != null && b64) { Integer jsonpIndex = ctx.channel().attr(EncoderHandler.JSONP_INDEX).get(); encoder.encodeJsonP(jsonpIndex, queue, out, ctx.alloc(), 50); String type = "application/javascript"; if (jsonpIndex == null) { type = "text/plain"; } sendMessage(msg, channel, out, type, promise); } else { encoder.encodePackets(queue, out, ctx.alloc(), 50); sendMessage(msg, channel, out, "application/octet-stream", promise); } }
private void encodeChunkedContent( ChannelHandlerContext ctx, Object msg, int contentLength, List<Object> out) { if (contentLength > 0) { byte[] length = Integer.toHexString(contentLength).getBytes(CharsetUtil.US_ASCII); ByteBuf buf = ctx.alloc().buffer(length.length + 2); buf.writeBytes(length); buf.writeBytes(CRLF); out.add(buf); out.add(encodeAndRetain(msg)); out.add(CRLF_BUF.duplicate()); } if (msg instanceof LastHttpContent) { HttpHeaders headers = ((LastHttpContent) msg).trailingHeaders(); if (headers.isEmpty()) { out.add(ZERO_CRLF_CRLF_BUF.duplicate()); } else { ByteBuf buf = ctx.alloc().buffer(); buf.writeBytes(ZERO_CRLF); HttpHeaders.encode(headers, buf); buf.writeBytes(CRLF); out.add(buf); } state = ST_INIT; } else { if (contentLength == 0) { // Need to produce some output otherwise an // IllegalstateException will be thrown out.add(EMPTY_BUFFER); } } }
@Override protected void encode(ChannelHandlerContext ctx, Event event, List<Object> out) throws Exception { ByteBuf msg = null; if (null != event.getSource()) { LOG.trace("Event class: {}", event.getClass()); ByteBuf buf = ctx.alloc().buffer(1); buf.writeByte(event.getType()); msg = Unpooled.wrappedBuffer(buf, Unpooled.wrappedBuffer(msgPack.write(event.getSource()))); } else { msg = ctx.alloc().buffer(1); msg.writeByte(event.getType()); } out.add(msg); }
@Override public HttpContent readChunk(ChannelHandlerContext ctx) throws Exception { long offset = this.offset; if (offset >= endOffset) { if (sentLastChunk) { return null; } else { // Send last chunk for this file sentLastChunk = true; return new DefaultLastHttpContent(); } } int chunkSize = (int) Math.min(this.chunkSize, endOffset - offset); // Check if the buffer is backed by an byte array. If so we can optimize it a bit an safe a copy ByteBuf buf = ctx.alloc().heapBuffer(chunkSize); boolean release = true; try { file.readFully(buf.array(), buf.arrayOffset(), chunkSize); buf.writerIndex(chunkSize); this.offset = offset + chunkSize; release = false; return new DefaultHttpContent(buf); } finally { if (release) { buf.release(); } } }
/** * 发送消息 * * @param message * @param msg */ public void send(final Payload message, final byte[] msg) { try { final ByteBuf data = context.alloc().buffer(msg.length); // (2) data.writeBytes(msg); final ChannelFuture cf = context.writeAndFlush(data); cf.addListener( new GenericFutureListener<Future<? super Void>>() { @Override public void operationComplete(Future<? super Void> future) throws Exception { if (cf.cause() != null) { logger.error("{}, Send Error.", context, cf.cause()); PayloadServiceImpl.instance.updateSendStatus( message, userId, new PushStatus(PushStatus.WriterError, cf.cause().getMessage())); } else { updateOpTime(); PayloadServiceImpl.instance.updateSendStatus( message, userId, new PushStatus(PushStatus.Success)); ClientServiceImpl.instance.updateBadge(userId, 1); if (logger.isDebugEnabled()) { logger.debug("Send Done, userId={}, messageId={}", userId, message.getId()); } } } }); } catch (Exception e) { message.setStatus(userId, new PushStatus(PushStatus.UnKnown, e.getMessage())); logger.error(e.getMessage(), e); } }
public ByteBuf readChunk(ChannelHandlerContext var1) throws Exception { long var2 = this.offset; if (var2 >= this.endOffset) { return null; } else { int var4 = (int) Math.min((long) this.chunkSize, this.endOffset - var2); ByteBuf var5 = var1.alloc().buffer(var4); boolean var6 = true; try { int var7 = 0; while (true) { int var8 = var5.writeBytes((ScatteringByteChannel) this.in, var4 - var7); if (var8 >= 0) { var7 += var8; if (var7 != var4) { continue; } } this.offset += (long) var7; var6 = false; ByteBuf var12 = var5; return var12; } } finally { if (var6) { var5.release(); } } } }
@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { if (msg instanceof WebSocketFrameInternal) { WebSocketFrameInternal frame = (WebSocketFrameInternal) msg; ByteBuf buf = frame.getBinaryData(); if (buf != Unpooled.EMPTY_BUFFER) { buf = safeBuffer(buf, ctx.alloc()); } switch (frame.type()) { case BINARY: msg = new BinaryWebSocketFrame(frame.isFinal(), 0, buf); break; case TEXT: msg = new TextWebSocketFrame(frame.isFinal(), 0, buf); break; case CLOSE: msg = new CloseWebSocketFrame(true, 0, buf); break; case CONTINUATION: msg = new ContinuationWebSocketFrame(frame.isFinal(), 0, buf); break; case PONG: msg = new PongWebSocketFrame(buf); break; case PING: msg = new PingWebSocketFrame(buf); break; default: throw new IllegalStateException("Unsupported websocket msg " + msg); } } ctx.write(msg, promise); }
private boolean handleCompressedFrame(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (!in.isReadable(FRAME_COMPRESS_HEADER_LENGTH)) { return false; } int compressedPayloadLength = in.readInt(); if (!in.isReadable(compressedPayloadLength)) { return false; } // decompress payload Inflater inflater = new Inflater(); if (in.hasArray()) { inflater.setInput(in.array(), in.arrayOffset() + in.readerIndex(), compressedPayloadLength); in.skipBytes(compressedPayloadLength); } else { byte[] array = new byte[compressedPayloadLength]; in.readBytes(array); inflater.setInput(array); } while (!inflater.finished()) { ByteBuf decompressed = ctx.alloc().heapBuffer(1024, 1024); byte[] outArray = decompressed.array(); int count = inflater.inflate(outArray, decompressed.arrayOffset(), decompressed.writableBytes()); decompressed.writerIndex(count); // put data in the pipeline out.add(decompressed); } return true; }
@Override public void sendError(int status, String message) throws IOException { if (committed) { throw new IllegalStateException(); } final HttpResponseStatus responseStatus; if (message != null) { responseStatus = new HttpResponseStatus(status, message); setStatus(status); } else { responseStatus = HttpResponseStatus.valueOf(status); setStatus(status); } io.netty.handler.codec.http.HttpResponse response = null; if (message != null) { ByteBuf byteBuf = ctx.alloc().buffer(); byteBuf.writeBytes(message.getBytes()); response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseStatus, byteBuf); } else { response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseStatus); } if (keepAlive) { // Add keep alive and content length if needed response.headers().add(Names.CONNECTION, Values.KEEP_ALIVE); if (message == null) response.headers().add(Names.CONTENT_LENGTH, 0); else response.headers().add(Names.CONTENT_LENGTH, message.getBytes().length); } ctx.writeAndFlush(response); committed = true; }
private void wrap(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException { ByteBuf out = null; ChannelPromise promise = null; ByteBufAllocator alloc = ctx.alloc(); try { for (; ; ) { Object msg = pendingUnencryptedWrites.current(); if (msg == null) { break; } ByteBuf buf = (ByteBuf) msg; if (out == null) { out = allocateOutNetBuf(ctx, buf.readableBytes()); } SSLEngineResult result = wrap(alloc, engine, buf, out); if (!buf.isReadable()) { promise = pendingUnencryptedWrites.remove(); } else { promise = null; } if (result.getStatus() == Status.CLOSED) { // SSLEngine has been closed already. // Any further write attempts should be denied. pendingUnencryptedWrites.removeAndFailAll(SSLENGINE_CLOSED); return; } else { switch (result.getHandshakeStatus()) { case NEED_TASK: runDelegatedTasks(); break; case FINISHED: setHandshakeSuccess(); // deliberate fall-through case NOT_HANDSHAKING: setHandshakeSuccessIfStillHandshaking(); // deliberate fall-through case NEED_WRAP: finishWrap(ctx, out, promise, inUnwrap); promise = null; out = null; break; case NEED_UNWRAP: return; default: throw new IllegalStateException( "Unknown handshake status: " + result.getHandshakeStatus()); } } } } catch (SSLException e) { setHandshakeFailure(ctx, e); throw e; } finally { finishWrap(ctx, out, promise, inUnwrap); } }
/** * Always prefer a direct buffer when it's pooled, so that we reduce the number of memory copies * in {@link OpenSslEngine}. */ private ByteBuf allocate(ChannelHandlerContext ctx, int capacity) { ByteBufAllocator alloc = ctx.alloc(); if (wantsDirectBuffer) { return alloc.directBuffer(capacity); } else { return alloc.buffer(capacity); } }
public ChannelOutputStream( ChannelHandlerContext chc, String id, int bufSize, final Object monitor) { this.chc = chc; this.id = id; this.bufSize = bufSize; this.buf = chc.alloc().buffer(bufSize); this.channelWritabilityMonitor = monitor; }
private void wrapNonAppData(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException { ByteBuf out = null; try { for (; ; ) { if (out == null) { out = ctx.alloc().buffer(maxPacketBufferSize); } SSLEngineResult result = wrap(engine, Unpooled.EMPTY_BUFFER, out); if (result.bytesProduced() > 0) { ctx.write(out); if (inUnwrap) { needsFlush = true; } out = null; } switch (result.getHandshakeStatus()) { case FINISHED: setHandshakeSuccess(); break; case NEED_TASK: runDelegatedTasks(); break; case NEED_UNWRAP: if (!inUnwrap) { unwrapNonApp(ctx); } break; case NEED_WRAP: break; case NOT_HANDSHAKING: setHandshakeSuccessIfStillHandshaking(); // Workaround for TLS False Start problem reported at: // https://github.com/netty/netty/issues/1108#issuecomment-14266970 if (!inUnwrap) { unwrapNonApp(ctx); } break; default: throw new IllegalStateException( "Unknown handshake status: " + result.getHandshakeStatus()); } if (result.bytesProduced() == 0) { break; } } } catch (SSLException e) { setHandshakeFailure(e); throw e; } finally { if (out != null) { out.release(); } } }
@Override protected ByteBuf encodeMessage(ChannelHandlerContext ctx, M msg) { ByteBuf buf = ctx.alloc().buffer(); encodeHeader(buf, msg.getHeader()); encodeExtras(buf, msg.getExtras()); encodeKey(buf, msg.getKey()); return buf; }
private static ByteBuf encodeContent(StompContentSubframe content, ChannelHandlerContext ctx) { if (content instanceof LastStompContentSubframe) { ByteBuf buf = ctx.alloc().buffer(content.content().readableBytes() + 1); buf.writeBytes(content.content()); buf.writeByte(StompConstants.NUL); return buf; } else { return content.content().retain(); } }
@Override public void channelActive(ChannelHandlerContext ctx) { this.ctx = ctx; // Initialize the message. content = ctx.alloc().directBuffer(DiscardClient.SIZE).writeZero(DiscardClient.SIZE); // Send the initial messages. generateTraffic(); }
private void write(XHROptionsMessage msg, ChannelHandlerContext ctx, ChannelPromise promise) { HttpResponse res = new DefaultHttpResponse(HTTP_1_1, HttpResponseStatus.OK); HttpHeaders.addHeader(res, "Set-Cookie", "io=" + msg.getSessionId()); HttpHeaders.addHeader(res, CONNECTION, KEEP_ALIVE); HttpHeaders.addHeader(res, ACCESS_CONTROL_ALLOW_HEADERS, CONTENT_TYPE); addOriginHeaders(ctx.channel(), res); ByteBuf out = encoder.allocateBuffer(ctx.alloc()); sendMessage(msg, ctx.channel(), out, res, promise); }
@Override public void write(ChannelHandlerContext ctx, Object msg) throws Exception { Assert.assertSame(t, Thread.currentThread()); ByteBuf out = ctx.alloc().buffer(4); int m = (Integer) msg; int expected = outCnt++; Assert.assertEquals(expected, m); out.writeInt(m); ctx.write(out); }
@Override public void channelActive(ChannelHandlerContext ctx) { this.ctx = ctx; System.out.println("1: " + System.currentTimeMillis()); // Initialize the message. content = ctx.alloc().directBuffer(DiscardClient.SIZE).writeZero(DiscardClient.SIZE); // Send the initial messages. generateTraffic(); }
protected ByteBuf extractFrame(ChannelHandlerContext ctx, ByteBuf buffer, int index, int length) { // make a sliced buffer for reading full contents, then if enough data doesn't reached yet, // ReplayingDecoder will throw an error for replaying decode operation at this line. // // Don't create a new buffer with ctx.alloc().buffer() before enough data has come. It will not // be released (and leaked). // If sliced buffer is created successfully, enough data has come. ByteBuf slice = buffer.slice(index, length); ByteBuf frame = ctx.alloc().buffer(length); frame.writeBytes(slice, 0, length); return frame; }
@Override public void channelRead0(final ChannelHandlerContext c, Object msg) throws Exception { Channel ch = ctx.channel(); if (response == null) { if (msg instanceof FullHttpResponse) { response = (FullHttpResponse) msg; } else { response = new WSResponse((DefaultHttpResponse) msg, ctx.alloc().buffer()); } if (completeHandshake(ctx)) { return; } } if (msg instanceof LastHttpContent) { return; } if (!(msg instanceof WebSocketFrame)) { throw new Exception( "Unexpected FullHttpResponse (getStatus=" + response.getStatus() + ", " + "content=" + response.content().toString(CharsetUtil.UTF_8) + ')'); } final WebSocketFrame frame = (WebSocketFrame) msg; if (frame instanceof TextWebSocketFrame) { for (WebSocketEventListener l : listensers) { l.onMessage(c, new WebSocketMessage(((TextWebSocketFrame) frame).text())); } } else if (frame instanceof PingWebSocketFrame) { if (autoPong) { ctx.writeAndFlush(new PongWebSocketFrame(frame.content().copy())); } for (WebSocketEventListener l : listensers) { l.onPing(c, (PingWebSocketFrame) frame.copy()); } } else if (frame instanceof PongWebSocketFrame) { Logger.getLogger(getClass()) .warn( String.format( "WebSocketClient received a PongWebSocketFrame, that shouldn't happen! Data : %s", frame.content().toString(CharsetUtil.UTF_8))); } else if (frame instanceof CloseWebSocketFrame) { ch.close(); for (WebSocketEventListener l : listensers) { l.onClose(c, (CloseWebSocketFrame) frame.copy()); } } }
private void handleWebsocket( final OutPacketMessage msg, ChannelHandlerContext ctx, ChannelPromise promise) throws IOException { while (true) { Queue<Packet> queue = msg.getClientHead().getPacketsQueue(msg.getTransport()); Packet packet = queue.poll(); if (packet == null) { promise.setSuccess(); break; } final ByteBuf out = encoder.allocateBuffer(ctx.alloc()); encoder.encodePacket(packet, out, ctx.alloc(), true); WebSocketFrame res = new TextWebSocketFrame(out); if (log.isTraceEnabled()) { log.trace( "Out message: {} sessionId: {}", out.toString(CharsetUtil.UTF_8), msg.getSessionId()); } if (out.isReadable()) { ctx.channel().writeAndFlush(res, promise); } else { promise.setSuccess(); out.release(); } for (ByteBuf buf : packet.getAttachments()) { ByteBuf outBuf = encoder.allocateBuffer(ctx.alloc()); outBuf.writeByte(4); outBuf.writeBytes(buf); if (log.isTraceEnabled()) { log.trace( "Out attachment: {} sessionId: {}", ByteBufUtil.hexDump(outBuf), msg.getSessionId()); } ctx.channel().writeAndFlush(new BinaryWebSocketFrame(outBuf)); } } }
@Override protected void encode(ChannelHandlerContext ctx, NetBuffer buf, ByteBuf out) throws Exception { out = ctx.alloc().directBuffer(); byte[] data = buf.getMessages(); int dataLength = data.length; logger.debug("=====length:[\t" + dataLength + "\t]======="); // д��Ϣ out.writeShort(NetConstants.MAGIC_HEADER); // Matgic Header out.writeInt(dataLength); // ��Ҫ����ָ���� out.writeBytes(data); // ����protobuf���� ctx.write(out); ctx.flush(); }
@Override public void channelActive(final ChannelHandlerContext ctx) { // (1) final ByteBuf time = ctx.alloc().buffer(4); // (2) time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L)); final ChannelFuture f = ctx.writeAndFlush(time); // (3) f.addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { assert f == future; ctx.close(); } }); // (4) }
@Override protected void encode(ChannelHandlerContext ctx, OnDemandResponse response, List<Object> out) { FileDescriptor descriptor = response.getFileDescriptor(); int fileSize = response.getFileSize(); int chunkId = response.getChunkId(); ByteBuf chunkData = response.getChunkData(); ByteBuf buffer = ctx.alloc().buffer(6 + chunkData.readableBytes()); buffer.writeByte(descriptor.getType() - 1); buffer.writeShort(descriptor.getFile()); buffer.writeShort(fileSize); buffer.writeByte(chunkId); buffer.writeBytes(chunkData); out.add(buffer); }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Thread t = this.t; if (t == null) { this.t = Thread.currentThread(); } else { Assert.assertSame(t, Thread.currentThread()); } ByteBuf out = ctx.alloc().buffer(4); int m = ((Integer) msg).intValue(); int expected = inCnt++; Assert.assertEquals(expected, m); out.writeInt(m); ctx.fireChannelRead(out); }
private static ByteBuf encodeFrame(StompHeadersSubframe frame, ChannelHandlerContext ctx) { ByteBuf buf = ctx.alloc().buffer(); buf.writeBytes(frame.command().toString().getBytes(CharsetUtil.US_ASCII)); buf.writeByte(StompConstants.CR).writeByte(StompConstants.LF); StompHeaders headers = frame.headers(); for (String k : headers.keySet()) { List<String> values = headers.getAll(k); for (String v : values) { buf.writeBytes(k.getBytes(CharsetUtil.US_ASCII)) .writeByte(StompConstants.COLON) .writeBytes(v.getBytes(CharsetUtil.US_ASCII)); buf.writeByte(StompConstants.CR).writeByte(StompConstants.LF); } } buf.writeByte(StompConstants.CR).writeByte(StompConstants.LF); return buf; }
@Override public ByteBuf encode(ChannelHandlerContext ctx, SpdyHeadersFrame frame) throws Exception { if (frame == null) { throw new IllegalArgumentException("frame"); } if (finished) { return Unpooled.EMPTY_BUFFER; } ByteBuf decompressed = super.encode(ctx, frame); if (decompressed.readableBytes() == 0) { return Unpooled.EMPTY_BUFFER; } ByteBuf compressed = ctx.alloc().buffer(); setInput(decompressed); encode(compressed); return compressed; }
@Override public ByteBuf readChunk(ChannelHandlerContext ctx) throws Exception { if (endOfInput) return null; ByteBuf buffer = ctx.alloc().buffer(DEFAULT_CHUNK_SIZE); Body.BodyState state = body.transferTo(buffer); switch (state) { case STOP: endOfInput = true; return buffer; case SUSPEND: // this will suspend the stream in ChunkedWriteHandler return null; case CONTINUE: return buffer; default: throw new IllegalStateException("Unknown state: " + state); } }