Skip to content

Commit db8a725

Browse files
committed
feat: 1. 初步完成http反向代理 2. 调整tcp反向代理的细节
1 parent 538acfd commit db8a725

File tree

4 files changed

+117
-76
lines changed

4 files changed

+117
-76
lines changed

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
<artifactId>vertx-core</artifactId>
3434
<version>4.5.10</version>
3535
</dependency>
36+
<dependency>
37+
<groupId>io.vertx</groupId>
38+
<artifactId>vertx-web</artifactId>
39+
<version>4.5.10</version>
40+
</dependency>
3641
</dependencies>
3742

3843

Lines changed: 90 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,90 @@
1-
//package top.meethigher;
2-
//
3-
//import io.vertx.core.http.HttpClient;
4-
//import io.vertx.core.http.HttpServer;
5-
//import org.slf4j.Logger;
6-
//import org.slf4j.LoggerFactory;
7-
//
8-
//import java.util.concurrent.ThreadLocalRandom;
9-
//
10-
//public class VertxHTTPReverseProxy {
11-
//
12-
// private static final Logger log = LoggerFactory.getLogger(VertxHTTPReverseProxy.class);
13-
//
14-
// private static final char[] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
15-
//
16-
// private String sourceHost = "0.0.0.0";
17-
//
18-
// private int sourcePort = 999;
19-
//
20-
// private final HttpServer server;
21-
//
22-
// private final HttpClient httpClient;
23-
//
24-
// private final HttpClient httpsClient;
25-
//
26-
// private final String targetHost;
27-
//
28-
// private final int targetPort;
29-
//
30-
// private final String name;
31-
//
32-
// private static String generateName() {
33-
// final String prefix = "VertxHTTPReverseProxy-";
34-
// try {
35-
// // 池号对于虚拟机来说是全局的,以避免在类加载器范围的环境中池号重叠
36-
// synchronized (System.getProperties()) {
37-
// final String next = String.valueOf(Integer.getInteger("top.meethigher.VertxHTTPReverseProxy.name", 0) + 1);
38-
// System.setProperty("top.meethigher.VertxHTTPReverseProxy.name", next);
39-
// return prefix + next;
40-
// }
41-
// } catch (Exception e) {
42-
// final ThreadLocalRandom random = ThreadLocalRandom.current();
43-
// final StringBuilder sb = new StringBuilder(prefix);
44-
// for (int i = 0; i < 4; i++) {
45-
// sb.append(ID_CHARACTERS[random.nextInt(62)]);
46-
// }
47-
// return sb.toString();
48-
// }
49-
// }
50-
//}
1+
package top.meethigher;
2+
3+
import io.vertx.core.AsyncResult;
4+
import io.vertx.core.Future;
5+
import io.vertx.core.Handler;
6+
import io.vertx.core.Vertx;
7+
import io.vertx.core.http.HttpClient;
8+
import io.vertx.core.http.HttpClientOptions;
9+
import io.vertx.core.http.HttpServer;
10+
import io.vertx.ext.web.Router;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
14+
import java.util.concurrent.ThreadLocalRandom;
15+
16+
public class VertxHTTPReverseProxy {
17+
18+
private static final Logger log = LoggerFactory.getLogger(VertxHTTPReverseProxy.class);
19+
20+
private static final char[] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
21+
22+
private String sourceHost = "0.0.0.0";
23+
24+
private int sourcePort = 998;
25+
26+
27+
private final Router router;
28+
private final HttpServer httpServer;
29+
private final HttpClient httpClient;
30+
private final HttpClient httpsClient;
31+
private final String name;
32+
33+
private VertxHTTPReverseProxy(Router router, HttpServer httpServer, HttpClient httpClient, HttpClient httpsClient, String name) {
34+
this.router = router;
35+
this.httpServer = httpServer;
36+
this.httpClient = httpClient;
37+
this.httpsClient = httpsClient;
38+
this.name = name;
39+
}
40+
41+
public static VertxHTTPReverseProxy create(Vertx vertx, String name) {
42+
return new VertxHTTPReverseProxy(Router.router(vertx), vertx.createHttpServer(), vertx.createHttpClient(), vertx.createHttpClient(new HttpClientOptions().setSsl(true).setTrustAll(true)), name);
43+
}
44+
45+
public static VertxHTTPReverseProxy create(Vertx vertx) {
46+
return new VertxHTTPReverseProxy(Router.router(vertx), vertx.createHttpServer(), vertx.createHttpClient(), vertx.createHttpClient(new HttpClientOptions().setSsl(true).setTrustAll(true)), generateName());
47+
}
48+
49+
50+
private static String generateName() {
51+
final String prefix = "VertxHTTPReverseProxy-";
52+
try {
53+
// 池号对于虚拟机来说是全局的,以避免在类加载器范围的环境中池号重叠
54+
synchronized (System.getProperties()) {
55+
final String next = String.valueOf(Integer.getInteger("top.meethigher.VertxHTTPReverseProxy.name", 0) + 1);
56+
System.setProperty("top.meethigher.VertxHTTPReverseProxy.name", next);
57+
return prefix + next;
58+
}
59+
} catch (Exception e) {
60+
final ThreadLocalRandom random = ThreadLocalRandom.current();
61+
final StringBuilder sb = new StringBuilder(prefix);
62+
for (int i = 0; i < 4; i++) {
63+
sb.append(ID_CHARACTERS[random.nextInt(62)]);
64+
}
65+
return sb.toString();
66+
}
67+
}
68+
69+
public void start() {
70+
httpServer.requestHandler(router).exceptionHandler(e -> log.error("request failed", e));
71+
Future<HttpServer> listenFuture = httpServer.listen(sourcePort, sourceHost);
72+
73+
Handler<AsyncResult<HttpServer>> asyncResultHandler = ar -> {
74+
if (ar.succeeded()) {
75+
log.info("{} started on {}:{}", name, sourceHost, sourcePort);
76+
} else {
77+
Throwable e = ar.cause();
78+
log.error("{} start failed", name, e);
79+
80+
}
81+
};
82+
listenFuture.onComplete(asyncResultHandler);
83+
}
84+
85+
public void stop() {
86+
httpServer.close()
87+
.onSuccess(v -> log.info("{} closed", name))
88+
.onFailure(e -> log.error("{} close failed", name, e));
89+
}
90+
}

src/main/java/top/meethigher/VertxTCPReverseProxy.java

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,11 @@ public class VertxTCPReverseProxy {
2323

2424
private int sourcePort = 999;
2525

26+
private final Handler<NetSocket> connectHandler;
2627
private final NetServer netServer;
27-
2828
private final NetClient netClient;
29-
3029
private final String targetHost;
31-
3230
private final int targetPort;
33-
3431
private final String name;
3532

3633
private VertxTCPReverseProxy(NetServer netServer, NetClient netClient,
@@ -40,6 +37,23 @@ private VertxTCPReverseProxy(NetServer netServer, NetClient netClient,
4037
this.targetPort = targetPort;
4138
this.netServer = netServer;
4239
this.netClient = netClient;
40+
this.connectHandler = sourceSocket -> {
41+
sourceSocket.pause();
42+
netClient.connect(targetPort, targetHost)
43+
.onSuccess(targetSocket -> {
44+
log.info("connected {} <--> {}", sourceSocket.remoteAddress().toString(), targetSocket.remoteAddress().toString());
45+
targetSocket.pause();
46+
sourceSocket.closeHandler(v -> targetSocket.close()).pipeTo(targetSocket);
47+
targetSocket.closeHandler(v -> {
48+
sourceSocket.close();
49+
log.info("closed {} <--> {}", sourceSocket.remoteAddress().toString(), targetSocket.remoteAddress().toString());
50+
}).pipeTo(sourceSocket);
51+
sourceSocket.resume();
52+
targetSocket.resume();
53+
})
54+
.onFailure(e -> log.error("failed to connect to {}:{}", targetHost, targetPort, e));
55+
56+
};
4357
}
4458

4559
public static VertxTCPReverseProxy create(Vertx vertx,
@@ -83,25 +97,9 @@ private static String generateName() {
8397
}
8498

8599
public void start() {
86-
Handler<NetSocket> connectHandler = sourceSocket -> {
87-
sourceSocket.pause();
88-
netClient.connect(targetPort, targetHost)
89-
.onSuccess(targetSocket -> {
90-
log.info("connected {} <--> {}", sourceSocket.remoteAddress().toString(), targetSocket.remoteAddress().toString());
91-
targetSocket.pause();
92-
sourceSocket.pipeTo(targetSocket);
93-
targetSocket.closeHandler(v -> {
94-
sourceSocket.close().onSuccess(vv -> {
95-
log.info("closed {} <--> {}", sourceSocket.remoteAddress().toString(), targetSocket.remoteAddress().toString());
96-
});
97-
}).pipeTo(sourceSocket);
98-
sourceSocket.resume();
99-
targetSocket.resume();
100-
})
101-
.onFailure(e -> log.error("failed to connect to {}:{}", targetHost, targetPort, e));
100+
netServer.connectHandler(connectHandler).exceptionHandler(e -> log.error("connect failed", e));
101+
Future<NetServer> listenFuture = netServer.listen(sourcePort, sourceHost);
102102

103-
};
104-
Handler<Throwable> connectFailedHandler = e -> log.error("connect failed", e);
105103
Handler<AsyncResult<NetServer>> asyncResultHandler = ar -> {
106104
if (ar.succeeded()) {
107105
log.info("{} started on {}:{}", name, sourceHost, sourcePort);
@@ -110,9 +108,7 @@ public void start() {
110108
log.error("{} start failed", name, e);
111109
}
112110
};
113-
netServer.connectHandler(connectHandler).exceptionHandler(connectFailedHandler);
114-
Future<NetServer> listen = sourceHost == null ? netServer.listen(sourcePort) : netServer.listen(sourcePort, sourceHost);
115-
listen.onComplete(asyncResultHandler);
111+
listenFuture.onComplete(asyncResultHandler);
116112
}
117113

118114
public void stop() {

src/test/java/top/meethigher/VertxTCPReverseProxyTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class VertxTCPReverseProxyTest {
1010

1111
@Test
1212
public void testVertxTCPReverseProxy() throws Exception {
13-
VertxTCPReverseProxy proxy = VertxTCPReverseProxy.create(Vertx.vertx(), "10.0.0.1", 4321);
13+
VertxTCPReverseProxy proxy = VertxTCPReverseProxy.create(Vertx.vertx(), "10.0.0.9", 5432);
1414
proxy.port(22).start();
1515
TimeUnit.MINUTES.sleep(10);
1616
proxy.stop();

0 commit comments

Comments
 (0)