當您設計將連接到許多服務器的客戶端時,如爬行器。如何將應用程序/用戶數據傳遞給ChannelHandler Netty
編寫代碼,這樣的事情:當你在你的ApplicationHandler
// 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());
}
}
現在,實現你的SimpleChannelHandler或WhatEverStreamHandler的東西,(在本例中CrawlerHander)的信息的唯一的一塊,你得到的是socketAdress你連接到你可以在「public void channelConnected()」函數中恢復。
好吧,但如果我想恢復一些用戶數據,如我在代碼示例中看到的MyURL對象,該怎麼辦?我使用一個骯髒的黑客,我使用一個地圖<「ip:port」,MyURL>所以我可以檢索channelConnected中的關聯數據,因爲我知道ip:port我連接上了。
這個黑客真的很髒,如果你同時連接到同一個服務器,它將無法工作(或者你必須綁定到本地端口並使用像「localport:ip:remoteport」這樣的密鑰,但它是太髒)。
所以我正在尋求什麼是傳遞數據的好方法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());
}
你在說什麼同步問題?將它傳遞給ChannelPipelineFactory是進入atm的方式。我想我們之前有想法能夠在connect方法中傳遞某種附件,然後它會自動傳遞給ChannelPipeline.getPipeline()方法。但我無法找到關於它的郵件。 – 2012-04-19 19:30:01
嘿,諾曼,你是在好的方式,我所有的問題將被解決,如果我可以傳遞附件在connect(),所以我可以通過我的ChannelPipelineFactory.getPipeline(Object theNewExtraParamater)傳遞給我的ChannelHandler()的consuctor; – Pierre 2012-04-20 05:39:24
對不起,我的最後一句話不是同步問題,這是因爲我的另一種方法是弄髒,查看編輯過的帖子,我添加了一個代碼示例 – Pierre 2012-04-20 05:40:04