예제 #1
0
  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);
    }
  }
예제 #2
0
  private void send(final ByteBuf buffer) throws Exception {
    DefaultFullHttpResponse rsp = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, buffer);

    if (!headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
      headers
          .remove(HttpHeaderNames.TRANSFER_ENCODING)
          .set(HttpHeaderNames.CONTENT_LENGTH, buffer.readableBytes());
    }

    if (keepAlive) {
      headers.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
    }

    // dump headers
    rsp.headers().set(headers);

    Attribute<Boolean> async = ctx.attr(NettyRequest.ASYNC);
    boolean isAsync = async != null && async.get() == Boolean.TRUE;
    if (isAsync) {
      // we need flush, from async
      keepAlive(ctx.writeAndFlush(rsp));
    } else {
      keepAlive(ctx.write(rsp));
    }

    committed = true;
  }
  @Override
  public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
    long size = calculateSize(msg);
    long curtime = System.currentTimeMillis();

    if (trafficCounter != null) {
      trafficCounter.bytesRecvFlowControl(size);
      if (readLimit == 0) {
        // no action
        ctx.fireChannelRead(msg);

        return;
      }

      // compute the number of ms to wait before reopening the channel
      long wait =
          getTimeToWait(
              readLimit, trafficCounter.currentReadBytes(), trafficCounter.lastTime(), curtime);
      if (wait >= MINIMAL_WAIT) { // At least 10ms seems a minimal
        // time in order to
        // try to limit the traffic
        if (!isSuspended(ctx)) {
          ctx.attr(READ_SUSPENDED).set(true);

          // Create a Runnable to reactive the read if needed. If one was create before it will just
          // be
          // reused to limit object creation
          Attribute<Runnable> attr = ctx.attr(REOPEN_TASK);
          Runnable reopenTask = attr.get();
          if (reopenTask == null) {
            reopenTask = new ReopenReadTimerTask(ctx);
            attr.set(reopenTask);
          }
          ctx.executor().schedule(reopenTask, wait, TimeUnit.MILLISECONDS);
        } else {
          // Create a Runnable to update the next handler in the chain. If one was create before it
          // will
          // just be reused to limit object creation
          Runnable bufferUpdateTask =
              new Runnable() {
                @Override
                public void run() {
                  ctx.fireChannelRead(msg);
                }
              };
          ctx.executor().schedule(bufferUpdateTask, wait, TimeUnit.MILLISECONDS);
          return;
        }
      }
    }
    ctx.fireChannelRead(msg);
  }
예제 #4
0
파일: Decoder.java 프로젝트: hsdrose/TomP2P
  public boolean decode(
      ChannelHandlerContext ctx,
      final ByteBuf buf,
      InetSocketAddress recipient,
      final InetSocketAddress sender) {

    LOG.debug("Decoding of TomP2P starts now. Readable: {}.", buf.readableBytes());

    try {
      final int readerBefore = buf.readerIndex();
      // set the sender of this message for handling timeout
      final Attribute<InetSocketAddress> attributeInet = ctx.attr(INET_ADDRESS_KEY);
      attributeInet.set(sender);

      if (message == null && !headerDone) {
        headerDone = decodeHeader(buf, recipient, sender);
        if (headerDone) {
          // store the sender as an attribute
          final Attribute<PeerAddress> attributePeerAddress = ctx.attr(PEER_ADDRESS_KEY);
          attributePeerAddress.set(message.sender());
          message.udp(ctx.channel() instanceof DatagramChannel);
          if (message.isFireAndForget() && message.isUdp()) {
            TimeoutFactory.removeTimeout(ctx);
          }
        } else {
          return false;
        }
      }

      final boolean donePayload = decodePayload(buf);
      decodeSignature(buf, readerBefore, donePayload);

      if (donePayload) {
        boolean isRelay = message.sender().isRelayed();
        if (isRelay && !message.peerSocketAddresses().isEmpty()) {
          PeerAddress tmpSender =
              message.sender().changePeerSocketAddresses(message.peerSocketAddresses());
          message.sender(tmpSender);
        }
      }

      // see https://github.com/netty/netty/issues/1976
      buf.discardSomeReadBytes();
      return donePayload;

    } catch (Exception e) {
      ctx.fireExceptionCaught(e);
      e.printStackTrace();
      return true;
    }
  }
예제 #5
0
 @Override
 public void end() {
   if (ctx != null) {
     Attribute<NettyWebSocket> ws = ctx.attr(NettyWebSocket.KEY);
     if (ws != null && ws.get() != null) {
       status = HttpResponseStatus.SWITCHING_PROTOCOLS;
       ws.get().hankshake();
       ctx = null;
       committed = true;
       return;
     }
     if (!committed) {
       DefaultHttpResponse rsp = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status);
       // dump headers
       rsp.headers().set(headers);
       keepAlive(ctx.write(rsp));
     }
     committed = true;
     ctx = null;
   }
 }
예제 #6
0
 @Override
 public <X> X getAttribute(String key, Class<X> clz) {
   AttributeKey<X> attributeKey = AttributeKey.valueOf(key);
   Attribute<X> attribute = channel.attr(attributeKey);
   return attribute == null ? null : attribute.get();
 }
 @Override
 public void handle(NetworkContext context, MessageForgeHandshakeInOutAck message) {
   Session session = context.getSession();
   Attribute<ForgeServerHandshakePhase> phase =
       context.getChannel().attr(ForgeHandshakePhase.PHASE);
   switch (phase.get()) {
     case WAITING_ACK:
       if (!message.getPhase().equals(ForgeClientHandshakePhase.WAITING_SERVER_DATA)) {
         session.disconnect(
             "Retrieved unexpected forge handshake ack message. (Got "
                 + message.getPhase()
                 + ", expected "
                 + ForgeClientHandshakePhase.WAITING_SERVER_DATA
                 + ")");
       } else {
         List<MessageForgeHandshakeOutRegistryData.Entry> entries = Lists.newArrayList();
         entries.add(
             new MessageForgeHandshakeOutRegistryData.Entry(
                 "fml:items", Maps.newHashMap(), Lists.newArrayList()));
         entries.add(
             new MessageForgeHandshakeOutRegistryData.Entry(
                 "fml:blocks", Maps.newHashMap(), Lists.newArrayList()));
         session.send(new MessageForgeHandshakeOutRegistryData(entries));
         session.send(new MessageForgeHandshakeInOutAck(ForgeServerHandshakePhase.WAITING_ACK));
         phase.set(ForgeServerHandshakePhase.COMPLETE);
       }
       LanternGame.log()
           .info(
               "{}: Forge handshake -> Received ack (waitingServerData) message.",
               session.getGameProfile().getName());
       break;
     case COMPLETE:
       if (!message.getPhase().equals(ForgeClientHandshakePhase.WAITING_SERVER_COMPLETE)) {
         session.disconnect(
             "Retrieved unexpected forge handshake ack message. (Got "
                 + message.getPhase()
                 + ", expected "
                 + ForgeClientHandshakePhase.WAITING_SERVER_COMPLETE
                 + ")");
       } else {
         session.send(new MessageForgeHandshakeInOutAck(ForgeServerHandshakePhase.COMPLETE));
         phase.set(ForgeServerHandshakePhase.DONE);
       }
       LanternGame.log()
           .info(
               "{}: Forge handshake -> Received ack (waitingServerComplete) message.",
               session.getGameProfile().getName());
       break;
     case DONE:
       if (!message.getPhase().equals(ForgeClientHandshakePhase.PENDING_COMPLETE)
           && !message.getPhase().equals(ForgeClientHandshakePhase.COMPLETE)) {
         session.disconnect(
             "Retrieved unexpected forge handshake ack message. (Got "
                 + message.getPhase()
                 + ", expected "
                 + ForgeClientHandshakePhase.PENDING_COMPLETE
                 + " or "
                 + ForgeClientHandshakePhase.COMPLETE
                 + ")");
       } else {
         if (message.getPhase().equals(ForgeClientHandshakePhase.PENDING_COMPLETE)) {
           session.send(new MessageForgeHandshakeInOutAck(ForgeServerHandshakePhase.DONE));
           LanternGame.log()
               .info(
                   "{}: Forge handshake -> Received ack (pendingComplete) message.",
                   session.getGameProfile().getName());
         } else {
           session.setProtocolState(ProtocolState.PLAY);
           session.spawnPlayer();
           LanternGame.log()
               .info(
                   "{}: Forge handshake -> Received ack (complete) message.",
                   session.getGameProfile().getName());
         }
       }
       break;
     case ERROR:
       break;
     default:
       session.disconnect(
           "Retrieved unexpected forge handshake ack message. (Got " + message.getPhase() + ")");
   }
 }