gpt4 book ai didi

java - 如何将应用程序/用户数据传递到 ChannelHandler Netty

转载 作者:太空宇宙 更新时间:2023-11-04 08:17:05 24 4
gpt4 key购买 nike

当您设计一个将连接到许多服务器的客户端时,例如爬虫。

您将编写类似的代码:

// the pipeline
public class CrawlerPipelineFactory implements ChannelPipelineFactory {
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new CrawlerHandler());
}
}

// the channel handler
public class CrawlerHandler extends SimpleChannelHandler {
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// ...
}
}


// the main :
public static void main(){
ChannelFactory factory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newCachedThreadPool());

ClientBootstrap scannerBootstrap = new ClientBootstrap(factory);
scannerBootstrap.setPipelineFactory(new CrawlerPipelineFactory());

while(true){
MyURL url = stack.pop();
ChannelFuture connect = scannerBootstrap.connect(url.getSocketAddress());
}
}

现在,当您在 ApplicationHandler 中时,即实现 SimpleChannelHandler 或 WhatEverStreamHandler 的内容(示例中的 CrawlerHander)中,您获得的唯一信息是您要连接的套接字地址,您可以在“public void channelConnected()”函数中恢复该信息。

好的,但是如果我想恢复一些用户数据,例如您在代码示例中看到的 MyURL 对象,该怎么办?

我使用了一个肮脏的黑客,我使用 Map<"ip:port",MyURL> 这样我就可以检索 channelConnected 中的关联数据,因为我知道我连接的 ip:port。

这个 hack 真的很脏,如果你同时连接到同一台服务器,它就不起作用(或者你必须绑定(bind)到本地端口并使用像“localport:ip:remoteport”这样的 key ,但它太脏了)。

所以我正在寻找向 CrawlerHander 传递数据的好方法是什么?

如果我们可以通过 Bootstrap 的 connect() 方法传递这些数据,那就太酷了。我知道我可以在 ChannelPipelineFactory.getPipeline() 中传递参数,因为它是通过 connect() 调用的。但现在我们不能了,所以这是我使用的另一个肮脏的黑客:

编辑:

// the main
while(!targets.isEmpty()){
client.connect("localhost",111); // we will never connect to localhost, it's a hack
}

// the pipleline
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(
new CrawlerHandler(targets.pop()) // I specify each new host to connect here
);
}

// in my channel handler
// Now I have the data I want in the constructor, so I m sure I get them before everything is called
public class CrawlerHandler extends SimpleChannelHandler {
ExtraParameter target;
public CrawlerHandler(ExtraParameter target) {
this.target = target;

// but, and it's the most dirty part, I have to abort the connection to localhost, and reinit a new connection to the real target
boolean bFirstConnect=true;
@Override
public void connectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
if(bFirstConnect){
bFirstConnect = false;
ctx.getChannel().connect(target.getSocketAddr());
}

最佳答案

您可以通过 Bootstrap 将变量传递给 Channel。

Netty.io 4.1 & SO - Adding an attribute to a Channel before creation

更新这个答案已经很晚了。

关于java - 如何将应用程序/用户数据传递到 ChannelHandler Netty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10230830/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com