Skip to content

Commit 6de68fa

Browse files
Migrate away from Vert.X (#175)
* Initial work on it * Fixed missing Guild Features and works now! * Spotless * Satisfy sonar * Satisfy sonar * disable test * disable test * chore: review comments --------- Co-authored-by: Suraj Kumar <[email protected]>
1 parent 57d4f48 commit 6de68fa

File tree

10 files changed

+169
-102
lines changed

10 files changed

+169
-102
lines changed

api/src/test/integration/com/javadiscord/jdi/core/api/UserRequestTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ void testGetCurrentUser() throws InterruptedException {
5252
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
5353
}
5454

55+
/* DISABLED Until tests are reworked
5556
@Test
5657
void testGetUser() throws InterruptedException {
5758
long wazeiUserId = 821143476455342120L;
@@ -69,6 +70,8 @@ void testGetUser() throws InterruptedException {
6970
assertTrue(countDownLatch.await(30, TimeUnit.SECONDS));
7071
}
7172
73+
*/
74+
7275
@Test
7376
@Disabled
7477
void testModifyCurrentUser() throws InterruptedException {

api/src/test/integration/com/javadiscord/jdi/core/api/VoiceRequestTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public static void setup() throws InterruptedException {
2727
guild = new LiveDiscordHelper().getGuild();
2828
}
2929

30+
/*
31+
3032
@Test
3133
void testListVoiceRegions() throws InterruptedException {
3234
CountDownLatch latch = new CountDownLatch(1);
@@ -43,4 +45,6 @@ void testListVoiceRegions() throws InterruptedException {
4345
});
4446
assertTrue(latch.await(30, TimeUnit.SECONDS));
4547
}
48+
49+
*/
4650
}

gateway/build.gradle

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ dependencies {
44

55
implementation 'com.github.mizosoft.methanol:methanol:1.7.0'
66

7-
implementation 'io.vertx:vertx-web-client:4.5.8'
8-
implementation 'io.vertx:vertx-core:4.5.8'
7+
implementation 'org.java-websocket:Java-WebSocket:1.5.7'
98

109
implementation 'com.fasterxml.jackson.core:jackson-core:2.18.0'
1110
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.17.2'
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.javadiscord.jdi.internal.gateway;
2+
3+
import java.net.URI;
4+
import java.util.function.Consumer;
5+
6+
import org.java_websocket.WebSocket;
7+
import org.java_websocket.client.WebSocketClient;
8+
import org.java_websocket.framing.Framedata;
9+
import org.java_websocket.handshake.ServerHandshake;
10+
11+
public class GatewayWebSocketClient extends WebSocketClient {
12+
private final Runnable onSuccess;
13+
private final Consumer<Exception> onFailure;
14+
private Consumer<String> onReceive = (message) -> {};
15+
private Runnable onClose = () -> {};
16+
private Consumer<Framedata> frameHandler = (framedata) -> {};
17+
18+
public GatewayWebSocketClient(
19+
URI serverUri, Runnable onSuccess, Consumer<Exception> onFailure
20+
) {
21+
super(serverUri);
22+
this.onSuccess = onSuccess;
23+
this.onFailure = onFailure;
24+
}
25+
26+
@Override
27+
public void onOpen(ServerHandshake serverHandshake) {
28+
onSuccess.run();
29+
}
30+
31+
@Override
32+
public void onMessage(String message) {
33+
onReceive.accept(message);
34+
}
35+
36+
@Override
37+
public void onClose(int code, String reason, boolean remote) {
38+
onClose.run();
39+
}
40+
41+
@Override
42+
public void onError(Exception e) {
43+
onFailure.accept(e);
44+
}
45+
46+
@Override
47+
public void onWebsocketPing(WebSocket conn, Framedata f) {
48+
frameHandler.accept(f);
49+
}
50+
51+
@Override
52+
public void onWebsocketPong(WebSocket conn, Framedata f) {
53+
frameHandler.accept(f);
54+
}
55+
56+
public void setOnReceive(Consumer<String> onReceive) {
57+
this.onReceive = onReceive;
58+
}
59+
60+
public void setOnClose(Runnable onClose) {
61+
this.onClose = onClose;
62+
}
63+
64+
public void setFrameHandler(Consumer<Framedata> frameHandler) {
65+
this.frameHandler = frameHandler;
66+
}
67+
}

gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketHandler.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,10 @@
1515
import com.fasterxml.jackson.databind.ObjectMapper;
1616
import com.fasterxml.jackson.databind.json.JsonMapper;
1717
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
18-
import io.vertx.core.Handler;
19-
import io.vertx.core.buffer.Buffer;
20-
import io.vertx.core.http.WebSocket;
2118
import org.apache.logging.log4j.LogManager;
2219
import org.apache.logging.log4j.Logger;
2320

24-
public class WebSocketHandler implements Handler<WebSocket> {
21+
public class WebSocketHandler {
2522
private static final Logger LOGGER = LogManager.getLogger(WebSocketHandler.class);
2623
private static final ObjectMapper OBJECT_MAPPER =
2724
JsonMapper.builder().addModule(new JavaTimeModule()).build();
@@ -56,18 +53,17 @@ GatewayOpcode.HEARTBEAT, new HeartbeatAckOperationHandler(heartbeatService)
5653
OPERATION_HANDLER.put(GatewayOpcode.INVALID_SESSION, reconnectMessageHandler);
5754
}
5855

59-
@Override
60-
public void handle(WebSocket webSocket) {
61-
webSocket.handler(this::handleMessage);
62-
webSocket.closeHandler(this::handleClose);
56+
public void handle(GatewayWebSocketClient client) {
57+
client.setOnReceive(this::handleMessage);
58+
client.setOnClose(this::handleClose);
6359
}
6460

65-
private void handleMessage(Buffer buffer) {
66-
LOGGER.trace("Received message from gateway: {}", buffer);
61+
private void handleMessage(String message) {
62+
LOGGER.trace("Received message from gateway: {}", message);
6763

6864
try {
6965
GatewayEvent gatewayEvent =
70-
OBJECT_MAPPER.readValue(buffer.toString(), GatewayEvent.class);
66+
OBJECT_MAPPER.readValue(message, GatewayEvent.class);
7167

7268
connectionMediator.getConnectionDetails().setSequence(gatewayEvent.sequenceNumber());
7369

@@ -84,7 +80,7 @@ private void handleMessage(Buffer buffer) {
8480
}
8581
}
8682

87-
private void handleClose(Void unused) {
83+
private void handleClose() {
8884
LOGGER.warn(
8985
"The web socket connection to discord was closed. You will no longer receive"
9086
+ " gateway events."
Lines changed: 63 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
11
package com.javadiscord.jdi.internal.gateway;
22

3+
import java.net.URI;
4+
35
import com.javadiscord.jdi.internal.cache.Cache;
46
import com.javadiscord.jdi.internal.gateway.handlers.heartbeat.HeartbeatService;
57
import com.javadiscord.jdi.internal.gateway.identify.IdentifyRequest;
68

79
import com.fasterxml.jackson.core.JsonProcessingException;
810
import com.fasterxml.jackson.databind.ObjectMapper;
9-
import io.vertx.core.Vertx;
10-
import io.vertx.core.buffer.Buffer;
11-
import io.vertx.core.http.WebSocket;
12-
import io.vertx.core.http.WebSocketClient;
13-
import io.vertx.core.http.WebSocketConnectOptions;
14-
import io.vertx.core.http.WebSocketFrame;
1511
import org.apache.logging.log4j.LogManager;
1612
import org.apache.logging.log4j.Logger;
13+
import org.java_websocket.client.WebSocketClient;
14+
import org.java_websocket.framing.CloseFrame;
15+
import org.java_websocket.framing.Framedata;
16+
import org.java_websocket.framing.PingFrame;
17+
import org.java_websocket.framing.PongFrame;
1718

1819
public class WebSocketManager {
1920
private static final Logger LOGGER = LogManager.getLogger(WebSocketManager.class);
2021
private final GatewaySetting gatewaySetting;
2122
private final IdentifyRequest identifyRequest;
22-
private final Vertx vertx;
2323
private final WebSocketRetryHandler retryHandler;
2424
private final Cache cache;
25-
private WebSocket webSocket;
26-
private WebSocketClient webSocketClient;
25+
private GatewayWebSocketClient client;
2726
private HeartbeatService heartbeatService;
2827
private boolean retryAllowed;
2928

@@ -32,66 +31,61 @@ public WebSocketManager(
3231
) {
3332
this.gatewaySetting = gatewaySetting;
3433
this.identifyRequest = identifyRequest;
35-
this.vertx = Vertx.vertx();
36-
this.retryHandler = new WebSocketRetryHandler(vertx);
34+
this.retryHandler = new WebSocketRetryHandler();
3735
this.cache = cache;
3836
}
3937

4038
public void start(ConnectionMediator connectionMediator) {
4139
heartbeatService = new HeartbeatService(connectionMediator);
40+
retryAllowed = true;
4241

4342
String gatewayURL = connectionMediator.getConnectionDetails().getGatewayURL();
44-
45-
WebSocketConnectOptions webSocketConnectOptions =
46-
new WebSocketConnectOptions()
47-
.addHeader("Origin", "localhost")
48-
.setAbsoluteURI(
43+
client =
44+
new GatewayWebSocketClient(
45+
URI.create(
4946
"%s/?v=%d&encoding=%s"
5047
.formatted(
5148
gatewayURL,
5249
gatewaySetting.getApiVersion(),
5350
gatewaySetting.getEncoding()
5451
)
55-
)
56-
.setSsl(true);
57-
58-
webSocketClient = vertx.createWebSocketClient();
59-
retryAllowed = true;
60-
webSocketClient.connect(webSocketConnectOptions)
61-
.onSuccess(
62-
webSocket -> {
52+
),
53+
() -> {
54+
// Success
6355
LOGGER.info("Connected to Discord");
64-
65-
this.webSocket = webSocket;
66-
6756
WebSocketHandler webSocketHandler =
6857
new WebSocketHandler(connectionMediator, cache, heartbeatService);
6958

70-
webSocketHandler.handle(webSocket);
59+
webSocketHandler.handle(client);
7160

72-
webSocket.frameHandler(frame -> frameHandler(frame, webSocketHandler));
61+
client.setFrameHandler(frame -> frameHandler(frame, webSocketHandler));
7362

7463
if (retryHandler.hasRetried()) {
7564
retryHandler.clear();
76-
sendResumeEvent(webSocket, connectionMediator);
65+
sendResumeEvent(connectionMediator);
7766
} else {
78-
sendIdentify(webSocket, identifyRequest);
67+
sendIdentify(client, identifyRequest);
7968
}
80-
}
81-
)
82-
.onFailure(
83-
error -> {
84-
LOGGER.warn("Failed to connect to {} {}", gatewayURL, error.getCause());
69+
},
70+
(exception) -> {
71+
// Error
72+
LOGGER.warn(
73+
"An error occurred in the gateway's connection: {} {}", gatewayURL,
74+
exception.getCause()
75+
);
8576
if (retryAllowed) {
8677
retryHandler.retry(() -> restart(connectionMediator));
8778
}
8879
}
8980
);
81+
client.connect();
9082
}
9183

92-
private void frameHandler(WebSocketFrame frame, WebSocketHandler webSocketHandler) {
93-
if (frame.isClose()) {
94-
webSocketHandler.handleClose(frame.closeStatusCode(), frame.closeReason());
84+
private void frameHandler(Framedata frame, WebSocketHandler webSocketHandler) {
85+
if (frame instanceof PingFrame) {
86+
client.sendFrame(new PongFrame());
87+
} else if (frame instanceof CloseFrame closeFrame) {
88+
webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage());
9589
}
9690
}
9791

@@ -102,54 +96,57 @@ public void restart(ConnectionMediator connectionMediator) {
10296
}
10397

10498
public void stop() {
105-
if (webSocket != null && !webSocket.isClosed()) {
106-
webSocket.close();
99+
if (client != null && !client.isClosed()) {
100+
try {
101+
client.closeBlocking();
102+
LOGGER.info("Web socket has closed successfully");
103+
} catch (InterruptedException e) {
104+
LOGGER.error("Failed to close websocket client: {}", e.getMessage());
105+
Thread.currentThread().interrupt();
106+
}
107107
}
108+
108109
if (heartbeatService != null) {
109110
heartbeatService.stop();
110111
}
111-
webSocketClient.close()
112-
.onSuccess(res -> LOGGER.info("Web socket client has been shutdown"))
113-
.onFailure(err -> LOGGER.error("Failed to shutdown web socket client", err));
112+
114113
retryAllowed = false;
115-
vertx.close()
116-
.onSuccess(res -> LOGGER.info("Gateway has shutdown"))
117-
.onFailure(err -> LOGGER.error("Failed to shutdown gateway", err));
118114
}
119115

120-
public WebSocket getWebSocket() {
121-
return webSocket;
116+
public WebSocketClient getWebSocket() {
117+
return client;
122118
}
123119

124-
private static void sendIdentify(WebSocket webSocket, IdentifyRequest identifyRequest) {
120+
private static void sendIdentify(
121+
org.java_websocket.client.WebSocketClient client,
122+
IdentifyRequest identifyRequest
123+
) {
125124
try {
126-
webSocket.write(
127-
Buffer.buffer((new ObjectMapper().writeValueAsString(identifyRequest)))
125+
client.send(
126+
new ObjectMapper().writeValueAsString(identifyRequest)
128127
);
129128
} catch (JsonProcessingException e) {
130129
LOGGER.error("Failed to send identify request, restarting bot");
131130
}
132131
}
133132

134-
private void sendResumeEvent(WebSocket webSocket, ConnectionMediator connectionMediator) {
133+
private void sendResumeEvent(ConnectionMediator connectionMediator) {
135134
String botToken = identifyRequest.getD().getToken();
136135
String sessionId = connectionMediator.getConnectionDetails().getSessionId();
137136
int sequence = connectionMediator.getConnectionDetails().getSequence();
138137
int opcode = GatewayOpcode.RESUME;
139-
webSocket.write(
140-
Buffer.buffer(
138+
client.send(
139+
"""
140+
{
141+
"op": %d,
142+
"d": {
143+
"token": "%s",
144+
"session_id": "%s",
145+
"seq": %d
146+
}
147+
}
141148
"""
142-
{
143-
"op": %d,
144-
"d": {
145-
"token": "%s",
146-
"session_id": "%s",
147-
"seq": %d
148-
}
149-
}
150-
"""
151-
.formatted(opcode, botToken, sessionId, sequence)
152-
)
149+
.formatted(opcode, botToken, sessionId, sequence)
153150
);
154151
}
155152
}

gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManagerProxy.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.javadiscord.jdi.internal.gateway;
22

3-
import io.vertx.core.http.WebSocket;
3+
import org.java_websocket.client.WebSocketClient;
44

55
public class WebSocketManagerProxy {
66
private final WebSocketManager webSocketManager;
@@ -17,7 +17,7 @@ public void restart(ConnectionMediator connectionMediator) {
1717
webSocketManager.restart(connectionMediator);
1818
}
1919

20-
public WebSocket getWebSocket() {
20+
public WebSocketClient getWebSocket() {
2121
return webSocketManager.getWebSocket();
2222
}
2323
}

0 commit comments

Comments
 (0)