使用Netty代理,提高工作效率
来源:互联网 发布:网络拓扑发现算法 编辑:程序博客网 时间:2024/04/28 13:22
最近工作中负责银行监管系统的对接。在申请银行测试环境的时候,流程复杂繁琐,耗费时间长。 我负责开发和测试银行的接口,但是开发阶段必须连接银行环境,但是银行环境又不能直接到本地。如果指定了本地端口,等测试验收时环境又不一样。银行回复给我们消息时服务地址又要改变,申请银行更改端口流程又负责。所以想在开发阶段和测试验收阶段使用同一个服务端,我采用了代理的方式。
当在本地local 端想通过中间proxy 来发送和接收请求到银行remote端,就可以使用代理。 就像我们平时使用的vpn一样,连接到vpn服务器上,然后通vpn服务器来转发和接收你的请求。
在netty的example中就有简单的例子。我的例子就是从里面改变而来。
ProxyConfig.properties 配置端口:
localIp=221.228.241.106localPort=8443 ProxyIp =192.168.2.13ProxyPort =54951remoteIp=202.108.57.118remotePort=35053HexDumpProxy.java 代理服务器端:
public final class HexDumpProxy{private static Logger logger = LoggerFactory.getLogger(HexDumpProxy.class);//中间IP和端口static final String PROXY_IP =ProxyConfig.getInstance().getProxyIp();static final int PROXY_PORT = Integer.parseInt(ProxyConfig.getInstance().getProxyPort());public static void main(String[] args) throws Exception{ logger.info("**********************启动代理 ********************** Ip:{} port:{}",PROXY_IP,PROXY_PORT);EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup();try{ //这里启动代理服务器端,用来接收local端和remote端的消息//把从来自local端的消息转发到remote端//把从来自remote端的消息转发到local端ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new HexDumpProxyInitializer()).childOption(ChannelOption.AUTO_READ, false).bind(new InetSocketAddress(PROXY_IP, PROXY_PORT)) //代理端口.sync().channel().closeFuture().sync();}finally{bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}}HexDumpProxyInitializer.java 文件 主要处理proxy服务器的handler
public class HexDumpProxyInitializer extends ChannelInitializer<SocketChannel>{public HexDumpProxyInitializer(){}@Overridepublic void initChannel(SocketChannel ch){ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO),new HexDumpProxyFrontendHandler());}}
在HexDumpProxy 中主要关注HexDumpProxyFrontendHandler该类主要处理连接事件和数据的读取写入事件。
public class HexDumpProxyFrontendHandler extends ChannelInboundHandlerAdapter {private static Logger logger =LoggerFactory.getLogger(HexDumpProxyFrontendHandler.class); //写入银行的通道 private volatile Channel outbound2BankChannel; public HexDumpProxyFrontendHandler() { } //当local或者remote与proxy连接时,proxy会发起到local或者remote端的连接 @Override public void channelActive(ChannelHandlerContext ctx) { final Channel inboundChannel = ctx.channel(); InetSocketAddress address = (InetSocketAddress)inboundChannel.remoteAddress(); logger.info("============连接代理成功=================="); logger.info("channelActive IP:{} port:{}",address.getHostString(),address.getPort()); // Start the connection attempt. Bootstrap b = new Bootstrap(); b.group(inboundChannel.eventLoop()) .channel(ctx.channel().getClass()) .option(ChannelOption.AUTO_READ, true) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); //p.addLast(new LoggingHandler(LogLevel.INFO)); p.addLast(new HexDumpProxyBackendHandler(inboundChannel),new LoggingHandler(LogLevel.INFO)); } }); ChannelFuture f = b.connect(ProxyConfig.getInstance().getRemoteIp(), Integer.parseInt(ProxyConfig.getInstance().getRemotePort())); outbound2BankChannel = f.channel(); f.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { if (future.isSuccess()) { // connection complete start to read first data inboundChannel.read(); } else { // Close the connection if the connection attempt has failed. inboundChannel.close(); } } }); } //当从local或者remote写入到proxy时,proxy把读取到的数据直接写入到local或者remote端 @Override public void channelRead(final ChannelHandlerContext ctx, Object msg) { logger.debug("==============向目标服务器写入数据========================"); InetSocketAddress fromAddress = (InetSocketAddress)ctx.channel().remoteAddress(); logger.debug("数据来自:{}",fromAddress.getHostName()); if (outbound2BankChannel.isActive()) { outbound2BankChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { if (future.isSuccess()) { InetSocketAddress toAddress = (InetSocketAddress)outbound2BankChannel.remoteAddress(); logger.debug("数据发往:{}",toAddress.getHostName()); // was able to flush out data, start to read the next chunk ctx.channel().read(); } else { future.channel().close(); } } }); } } @Override public void channelInactive(ChannelHandlerContext ctx) { Channel ch = ctx.channel(); InetSocketAddress address = (InetSocketAddress)ch.remoteAddress(); logger.info("=============与代理服务器端口断开连接=================="); logger.info("channelInactive IP:{} port:{}",address.getHostString(),address.getPort()); if (outbound2BankChannel != null) { closeOnFlush(outbound2BankChannel); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { Channel ch = ctx.channel(); InetSocketAddress address = (InetSocketAddress)ch.remoteAddress(); logger.info("=============与代理服务器端口端口连接=================="); logger.info("exceptionCaught IP:{} port:{}",address.getHostString(),address.getPort()); cause.printStackTrace(); closeOnFlush(ctx.channel()); } /** * Closes the specified channel after all queued write requests are flushed. */ static void closeOnFlush(Channel ch) { if (ch.isActive()) { ch.flush(); } }}
HexDumpProxyBackendHandler.java 文件主要负责数据的搬运。
public class HexDumpProxyBackendHandler extends ChannelInboundHandlerAdapter {private static Logger logger =LoggerFactory.getLogger(HexDumpProxyBackendHandler.class); //写入本地的通道 private volatile Channel outbound2LocalChannel; public HexDumpProxyBackendHandler(Channel outbound2LocalChannel) { this.outbound2LocalChannel =outbound2LocalChannel; } //当proxy与local或者remote连接时,开始从proxy中读取数据 @Override public void channelActive(ChannelHandlerContext ctx) { final Channel inboundChannel = ctx.channel(); InetSocketAddress address = (InetSocketAddress)inboundChannel.remoteAddress(); logger.info("##################代理连接目标端口成功#######################"); logger.info("连接目标端口成功。 ip:{} port:{}",address.getHostName(),address.getPort()); ctx.read(); } //把proxy中的数据读取,同时把数据写入local或者remote端 @Override public void channelRead(final ChannelHandlerContext ctx, Object msg) { logger.info("##################目标服务器向代理写入数据#######################"); InetSocketAddress fromAddress = (InetSocketAddress)ctx.channel().remoteAddress(); logger.debug("数据来自:{}",fromAddress.getHostName()); outbound2LocalChannel.writeAndFlush(msg).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { if (future.isSuccess()) { InetSocketAddress toAddress = (InetSocketAddress)outbound2LocalChannel.remoteAddress();logger.debug("数据发往:{}",toAddress.getHostName()); ctx.channel().read(); } else { future.channel().close(); } } }); } @Override public void channelInactive(ChannelHandlerContext ctx) { logger.info("############代理和目标地址端口断开连接##############"); HexDumpProxyFrontendHandler.closeOnFlush(ctx.channel()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { logger.info("############代理和目标地址端口断开连接##############"); logger.debug("exceptionCaught:{}",cause.getMessage()); cause.printStackTrace(); HexDumpProxyFrontendHandler.closeOnFlush(ctx.channel()); }}
0 0
- 使用Netty代理,提高工作效率
- 使用动态代理,提高工作效率
- 使用Netty代理你的请求
- 使用EditPlus技巧,提高工作效率
- Javascript使用技巧-提高工作效率
- 使用脚本来提高工作效率
- 使用EditPlus技巧,提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- 提高工作效率
- JVM的内存区域划分
- Request获取url各种信息的方法
- mysql乐观锁总结和实践
- Android梳理 屏幕适配
- Tomcat显示文件目录&文件列表
- 使用Netty代理,提高工作效率
- oracle 导出数据 dmp
- UIAlertView
- MFC 创建带窗口的dll链接库.窗口为非模态窗口
- .NET生成静态页面的方案总结
- 谁的青春不迷茫
- 图片上传时,同时显示出图片
- LRU算法
- jQuery CSS 操作 - position() 方法