vertx实现简单的反向代理

一提到反向代理,我们首先想到的或许是nginx,但某些场景,我们不能随意的去搭建一个NG。如果我们此时只有一个JavaWeb项目可用,或许最好的办法,就是在已有项目中集成一个反向代理服务。
所以我们就需要用Java手写一个简单的反向代理。
  • 语言:Java
  • 技术框架:Vert.x
  • 代理:TCP反向代理

例子描述

本机暴露8088端口,外部客户端访问该端口的连接,都映射到xxx.xxx.xxx.xxx:3306上。
简单来说,就是我们做了一个MySQL的代理。

思路

1.监听8088端口
2.监视8088端口的连接(取名A)操作,每有一个连接创建,我们就创建一个xxx.xxx.xxx.xxx:3306的连接(取名B)
3.把A发来的消息,转发给B
4.把B发来的消息,转发给A

代码示例

@Slf4j
public class VertxProxy {

    public static void main(String[] args) {
        NetServer netServer = Vertx.vertx().createNetServer();
        NetClient netClient = Vertx.vertx().createNetClient();
        netServer.connectHandler(clientSocket -> {
            log.info("客户端 {}:{} 创建连接", clientSocket.remoteAddress().host(), clientSocket.remoteAddress().port());
            netClient.connect(3306, "xxx.xxx.xxx.xxx", result -> {
                if (result.succeeded()) {
                    NetSocket proxySocket = result.result();
                    log.info("代理连接成功");
                    Pump.pump(clientSocket, proxySocket).start();
                    Pump.pump(proxySocket, clientSocket).start();
                    proxySocket.closeHandler(event -> log.info("代理连接关闭"));
                } else {
                    log.error("代理连接失败");
                }
                clientSocket.closeHandler(event -> log.info("客户端 {}:{} 断开连接", clientSocket.remoteAddress().host(), clientSocket.remoteAddress().port()));
            });
        });
        log.info("开始监听 8088");
        netServer.listen(8088);
    }
}
这就是一个反向代理的简单实现。
Pump.pump(A, B).start();
Pump.pump(B, A).start();
上面思路中的第3和第4,就是这两行代码实现的。

vertx实现简单的反向代理_第1张图片

这是pump()方法注释截图。

顽皮

如果你想看看消息中到底发了什么东西,那么我们就需要手动实现消息转发,不用pump()方法。
@Slf4j
public class VertxProxy {

    public static void main(String[] args) {
        NetServer netServer = Vertx.vertx().createNetServer();
        NetClient netClient = Vertx.vertx().createNetClient();
        netServer.connectHandler(clientSocket -> {
            log.info("客户端 {}:{} 创建连接", clientSocket.remoteAddress().host(), clientSocket.remoteAddress().port());
            netClient.connect(3306, "xxx.xxx.xxx.xxx", result -> {
                if (result.succeeded()) {
                    NetSocket proxySocket = result.result();
                    log.info("代理连接成功");
                    //Pump.pump(clientSocket, proxySocket).start()
                    clientSocket.handler(buffer -> {
                        log.debug("客户端消息: {}", buffer);
                        proxySocket.write(buffer);
                    });
                    //Pump.pump(proxySocket, clientSocket).start()
                    proxySocket.handler(buffer -> {
                        log.debug("代理端消息: {}", buffer);
                        clientSocket.write(buffer);
                    });
                    proxySocket.closeHandler(event -> log.info("代理连接关闭"));
                } else {
                    log.error("代理连接失败");
                }
                clientSocket.closeHandler(event -> log.info("客户端 {}:{} 断开连接", clientSocket.remoteAddress().host(), clientSocket.remoteAddress().port()));
            });
        });
        log.info("开始监听 8088");
        netServer.listen(8088);
    }
}

我们通过NetSocket.handler()方法接收消息并打印,然后通过NetSocket.write()方法把消息转发给另一方,即可实现。

你可能感兴趣的:(iCode)