Practical Netty (5) TCP反向代理服务器
- 作者:柳大·Poechant(钟超)
- 邮箱:zhongchao.ustc#gmail.com(# -> @)
- 博客:Blog.youkuaiyun.com/Poechant
- 微博:weibo.com/lauginhom
- 日期:June 11th, 2012
以下针对 TCP 反向代理服务器。
1. 前端连接被创建时,创建后端连接
一个平凡的 ServerBootstrap 会有如下的一个语句:
serverBootstrap.setPipelineFactory(
new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline p = pipeline();
p.addLast("handler", new PoechantProxyHandler());
return p;
}
});
这个PoechantProxyHandler
如何实现,就成了关键了。
每个 connection 建立后,会创建一个 channel 专门用于服务这个连接。此时会响应ChannelPipelineHandler
的此方法:
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
这时你可以为这个 connection(不妨称其为前端连接),创建一个与后端连接的 connection(不妨称其为后端连接)。此时对于后端服务器,你要扮演的是 client 的角色,所以需要一个 ClientBootstrap。该 client 连接成功后,就可以从前端连接中读取数据了。
private volatile Channel outboundChannel;
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
final Channel inboundChannel = e.getChannel();
inboundChannel.setReadable(false);
ClientBootstrap cb = new ClientBootstrap(cf);
cb.getPipeline().addLast("handler", new BackendChannelHandler(e.getChannel()));
ChannelFuture f = cb.connect(new InetSocketAddress(remoteHost, remotePort));
outboundChannel = f.getChannel();
f.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
inboundChannel.setReadable(true);
} else {
inboundChannel.close();
}
}
});
}
<