当前位置: 首页 > 知识库问答 >
问题:

净代理延迟响应

东门航
2023-03-14

我正在用Netty框架创建一个代理,但我注意到收到的最后一条消息在传递到下一个节点之前往往会延迟。

设计:

客户|

基本上,当服务器在将消息传递给客户机之前启动消息时会出现延迟,或者如果服务器在第一条消息之后立即发送后续消息,那么第一条消息就会通过,第二条消息会延迟几秒钟。为什么会这样?是否缺少一些配置参数?

        Executor executor = Executors.newCachedThreadPool();
        ServerBootstrap sb = new ServerBootstrap(
                new NioServerSocketChannelFactory(executor, executor));

        // Set up the event pipeline factory.
        ClientSocketChannelFactory cf =
                new NioClientSocketChannelFactory(executor, executor);

        sb.setPipelineFactory(
                new ProxyPipelineFactory(cf, remoteHost, remotePort));

        sb.setOption("child.tcpNoDelay", true);
        sb.setOption("child.keepAlive", true);

        // Start up the server.
        sb.bind(new InetSocketAddress(localPort));
@Override
public ChannelPipeline getPipeline() throws Exception {
    ChannelPipeline p = pipeline(); 
    p.addLast("handler", new ClientHandler(cf, remoteHost, remotePort));
    return p;
}
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
        throws Exception {
    // Suspend incoming traffic until connected to the remote host.
    final Channel inboundChannel = e.getChannel();
    inboundChannel.setReadable(false);

    // Start the connection attempt.
    ClientBootstrap cb = new ClientBootstrap(cf);

        cb.setOption("child.tcpNoDelay", true);
        cb.setOption("child.keepAlive", true);
    ChannelPipeline p = cb.getPipeline();
    p.addLast("famer", new DelimiterBasedFrameDecoder(8192, false, new ChannelBuffer[]{ChannelBuffers.wrappedBuffer("</cmd>".getBytes())}));
p.addLast("handler", new ServerHandler(e.getChannel(), trafficLock));
    ChannelFuture f = cb.connect(new InetSocketAddress(remoteHost, remotePort));

    outboundChannel = f.getChannel();
    f.addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (future.isSuccess()) {
                // Connection attempt succeeded:
                // Begin to accept incoming traffic.
                inboundChannel.setReadable(true);
            } else {
                // Close the connection if the connection attempt has failed.
                inboundChannel.close();
            }
        }
    });
}

@Override
public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e)
        throws Exception {

    BigEndianHeapChannelBuffer msg = (BigEndianHeapChannelBuffer) e.getMessage();

    if (log.isDebugEnabled()) {
        byte[] bytes = new byte[msg.capacity()];
        msg.readBytes(bytes);
        msg.setIndex(0, bytes.length);
        StringBuilder out = new StringBuilder("\nPROXY[ ").append(e.getChannel().getRemoteAddress()).append(" ---> Server ]");
        out.append("\nMESSAGE length=").append(bytes.length).append("\n").append(new String(bytes));
        log.debug(out.toString());
    }

    synchronized (trafficLock) {
        outboundChannel.write(msg);
        // If outboundChannel is saturated, do not read until notified in
        // OutboundHandler.channelInterestChanged().
        if (!outboundChannel.isWritable()) {
            e.getChannel().setReadable(false);
        }
    }
}
@Override
public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e)
        throws Exception {
    BigEndianHeapChannelBuffer msg = (BigEndianHeapChannelBuffer) e.getMessage();
    proxy(e.getChannel(), msg);
}
private void proxy(Channel connection, ChannelBuffer raw) {
    synchronized (trafficLock) {
        inboundChannel.write(raw);
        // If inboundChannel is saturated, do not read until notified in
        // ClientHandler.channelInterestChanged().
        if (!inboundChannel.isWritable()) {
            connection.setReadable(false);
        }
    }
}

共有1个答案

程枫
2023-03-14

您禁用了连接的可读性,在哪里再次打开它以读取更多的字节?您可以在netty.io上阅读Prxoy Server示例,该示例执行完全相同的操作。

private void proxy(Channel connection, ChannelBuffer raw) {
    synchronized (trafficLock) {
        inboundChannel.write(raw);
        // If inboundChannel is saturated, do not read until notified in
        // ClientHandler.channelInterestChanged().
        if (!inboundChannel.isWritable()) {
            connection.setReadable(false);
        }
    }
}
 类似资料:
  • 我试图将SDL程序限制为60 FPS,并使用以下代码计算FPS: 但似乎SDL_Delay以某种方式影响了SDL_GetTicks的返回值,因此time_delta得到的值类似于0到3,而当我只删除最后2行时,它通常约为15。 对我来说,这毫无意义。有人知道怎么回事吗? 编辑: 上面的代码基本上是我程序的主循环。我首先实现了一个fps计数器,通过在start_time和afterwords中计算多

  • 首先,是否有人对GRPC客户机服务器实现与websocket protobuf客户机服务器实现之间的吞吐量/延迟进行了性能比较?或者至少是类似的东西。 为了实现这一目标,我正在试用示例JAVA helloworld grpc客户机服务器,并尝试将响应的延迟与类似的websocket客户机服务器进行比较。目前,我正在本地机器上用客户端和服务器进行测试。 websocket客户端服务器在服务器端有一个

  • 问题内容: 我正在尝试使用新的React Lazy和Suspense创建后备加载组件。这很好用,但后备时间仅显示几毫秒。有没有办法增加额外的延迟或最短时间,因此我可以在渲染下一个组件之前显示该组件的动画? 现在懒导入 等待组件: 我可以做这样的事情吗? 问题答案: 函数应该返回对象的承诺,该对象由具有默认导出功能的模块返回。不会返回承诺,也不能那样使用。尽管任意承诺可以: 如果目标是提供 最小的

  • 如何在Vertx中处理延迟作业列表(实际上是数百个HTTP GET请求,到禁止快速请求主机的有限API)?现在,我正在使用此代码,它被阻止,因为Vertx一次启动所有请求。希望在每个请求之间有5秒的延迟来处理每个请求。

  • 问题内容: 因此,当我运行此代码时,我的JFrame变得无响应。我设法将其追溯到gameLoop()下的while循环。无论使用其中调用Thread.sleep()的delay(1000 / FRAMERATE),它都不允许键或鼠标侦听器执行其工作。 下面的完整代码,gameLoop()中存在问题 如果很重要,程序将从此处开始,然后转到Game类 可能无关紧要,但这是github存储库的插件htt

  • 以下是一些背景代码: InitiativeProfileQuestion。java: ProfileAnswer.java: InitiativeProfileQuestionRepository。java: InitiativeProfileService。java: 基础ontroller.java: 在我的BaseController中调用get问题()会返回“无法初始化代理-没有会话”错误