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

在netty中汇集客户渠道的正确方法?

邰德业
2023-03-14

我正在买java。nio。频道。以下代码中出现NotYetConnectedException,因为我正在尝试写入尚未打开的通道。

基本上,我拥有的是一个通道池,在其中,如果一个通道空闲,我将获取一个要写入的通道,如果一个通道不可用,我将创建一个新的通道。我的问题是,当我创建一个新通道时,当我调用connect时,该通道还没有准备好写入,我不想等到连接打开后再返回,因为我不想阻塞线程。最好的方法是什么?此外,我检索/返回通道的逻辑是否有效?请参阅下面的代码。

我有一个简单的连接池,如下所示:

private static class ChannelPool {
    private final ClientBootstrap cb;
    private Set<Channel> activeChannels = new HashSet<Channel>();
    private Deque<Channel> freeChannels = new ArrayDeque<Channel>();
    public ChannelPool() {
        ChannelFactory clientFactory =
                new NioClientSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool());
        cb = new ClientBootstrap(clientFactory);
        cb.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() {
                return Channels.pipeline(
                        new HttpRequestEncoder(),
                        new HttpResponseDecoder(),
                        new ResponseHandler());
            }
        });
    }

    private Channel newChannel() {
        ChannelFuture cf;
        synchronized (cb) {
            cf = cb.connect(new InetSocketAddress("localhost", 18080));
        }
        final Channel ret = cf.getChannel();
        ret.getCloseFuture().addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture arg0) throws Exception {
                System.out.println("channel closed?");
                synchronized (activeChannels) {
                    activeChannels.remove(ret);
                }
            }
        });
        synchronized (activeChannels) {
            activeChannels.add(ret);
        }
        System.out.println("returning new channel");
        return ret;
    }

    public Channel getFreeChannel() {
        synchronized (freeChannels) {
            while (!freeChannels.isEmpty()) {
                Channel ch = freeChannels.pollFirst();
                if (ch.isOpen()) {
                    return ch;
                }
            }
        }
        return newChannel();
    }

    public void returnChannel(Channel ch) {
        synchronized (freeChannels) {
            freeChannels.addLast(ch);
        }
    }
}

我试图在处理程序中使用它,如下所示:

private static class RequestHandler extends SimpleChannelHandler {

    @Override
    public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) {
        final HttpRequest request = (HttpRequest) e.getMessage();
        Channel proxyChannel = pool.getFreeChannel();
        proxyToClient.put(proxyChannel, e.getChannel());
        proxyChannel.write(request);
    }
}

共有1个答案

东门新立
2023-03-14

您必须在bootstrap.connect(...)返回的ChannelFuture中添加一个侦听器,并在添加的侦听器中将通道添加到activeChannel,而不是在bootstrap.connect(...)之后立即将新通道添加到activeChannel。这样,getFreeChannel()将永远不会获得尚未连接的通道。

因为即使调用了newChannel()newChannel()甚至在建立连接之前就会返回),activeChannels也可能是空的,所以在这种情况下,您必须决定该怎么办。如果我是你,我会将getFreeChannel()的返回类型从Channel更改为ChannelFuture,以便在空闲通道就绪时通知调用方。

 类似资料:
  • 以往,推广渠道彼此独立,不同渠道有不同的客户资源和流程,市场部只能在各个渠道分别进行推广和跟踪。通过纷享营销通,可以对推广渠道进行统一管理,整合渠道推广效果、线索获取情况。让市场部能够一目了然地掌握客户动态,如:官网带来了哪些客户,他们对什么产品感兴趣,是否有关注企业的微信公众号,有没有参加过公司举办的线下活动等等; 营销通已支持接入企业常用的线索获取渠道,打通了官网、线下活动、微信等渠道,通过这

  • 本文向大家介绍Android多渠道打包时获取当前渠道的方法,包括了Android多渠道打包时获取当前渠道的方法的使用技巧和注意事项,需要的朋友参考一下 作为Android app,发布多个分发平台是常规操作。然后,有时由于个渠道面对的用户不同,或平台审核标准不同,需要在各渠道使用不同的业务逻辑,这就需要根据渠道使用选择差异化代码。 这里把简单的代码记一下。 首先,分渠道打包很简单。 在项目的bui

  • 渠道分析 渠道来源细分

  • 问题内容: 我需要使客户端能够建立许多连接。我使用Netty 4.0。不幸的是,所有现有示例都没有显示如何创建大量连接。 这是正确的决定吗?还是会更好? 问题答案: 是的,它几乎是正确的。您唯一需要更改的就是在每个连接上创建NioEventLoopGroup。 NioEventLoopGroup实例非常昂贵,因此应该共享它们。创建一个实例并共享它,方法是每次都将同一个实例传递给Bootstrap.

  • 我将创建一个身份验证服务器,它本身与一组不同的Oauth2.0服务器交互。Netty似乎是在这里实现网络部分的一个很好的候选者。但在开始之前,我需要澄清一些关于netty的细节,因为我是新手。例行程序如下: > < li> 服务器接受来自客户端的HTTPS连接。 然后,不关闭第一个连接,它通过HTTPS与远程OAuth2.0服务器建立另一个连接并获取数据 毕竟,服务器将结果发送回客户端,客户端应该

  • 问题内容: 我想知道将jQuery插件集成到我的angular应用程序中的正确方法是什么。我发现了一些教程和屏幕录像,但是它们似乎适合特定的插件。 我应该像这样创建指令吗? 然后在html中调用脚本和指令? 提前谢谢 问题答案: 是的,你是对的。如果您使用的是jQuery插件,请不要将代码放在控制器中。而是创建一个指令,并将您通常具有的代码放入该指令的函数中。 您可以查看文档中的几点。您可以在这里