最近在看netty,光看看书也是挺无聊的,就想着写点东西。Netty的Github上面有很多example可以学习,想到之前做的项目用Javascript写了一个http/https代理服务器来获取某些请求的参数,就想着自己再用netty来实现一下。思想很简单,实现的时候还是有很多细节的地方要注意。而且暂时https的代理还没能实现,遇到了一些问题,暂时避开这方面。
首先看一张架构图吧,代码实现基于下图的流程:
有几点需要解释一下:
- 代理服务器通过bind()操作,与本机地址的某个端口绑定,bind()操作会产生一个Channel,属于本地的Channel。这个Channel没有在上图中画出来;
- 代理服务器通过与客户端建立连接,为每个客户端生成一个Channel,即图中名为inbound的通道;
- 这个时候,客户端的请求发送到了我们的代理服务器,代理服务器要做的就是解析请求的host,然后与真正的server建立连接,此时建立的即为图中名为outbound的通道,然后将客户端的请求发送过去;
- outbound中收到Server的回复时,再写入inbound通道,客户端就可以看见真正的服务器返回的数据。
代码中值得一提的是,什么时候建立outbound通道?因为建立outbound通道需要知道Server的地址,所以在读取到第一个FullHttpRequest的时候时候,解析Request中host和port,然后建立。还有一点需要注意的是,outbound通道所依赖的EventLoop应该与inbound一致,这样避免了新建额外的线程,也省去了一些线程切换的开销。
完整代码在我的Github上,基于maven构建,写的比较糙,欢迎交流、批评指正。