Skip to content

Commit 83e402e

Browse files
committed
fix(ws): added fixes for websocket & gateway that allow multiple discord.jar instances to run under a single java process - this previously didn't work because of static variables
1 parent b1765df commit 83e402e

File tree

6 files changed

+31
-25
lines changed

6 files changed

+31
-25
lines changed

src/main/java/com/seailz/discordjar/DiscordJar.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1561,7 +1561,7 @@ public EnumSet<CacheType> getCacheTypes() {
15611561
* <br>The time is in milliseconds.
15621562
*/
15631563
public List<Long> getGatewayPingHistory() {
1564-
return Gateway.pingHistoryMs;
1564+
return getGateway().pingHistoryMs;
15651565
}
15661566

15671567
/**

src/main/java/com/seailz/discordjar/gateway/Gateway.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ public class Gateway {
6262
private boolean resumedConnection = false;
6363
private boolean reconnecting = false;
6464
private ReconnectInfo resumeInfo;
65-
public static long lastSequenceNumber = -1;
65+
public long lastSequenceNumber = -1;
6666
private boolean readyForMessages = false;
6767
private boolean receivedReady = false;
6868
private HeartLogic heartbeatManager;
69-
public static Date lastHeartbeatSent = new Date();
69+
public Date lastHeartbeatSent = new Date();
7070

71-
public static List<Long> pingHistoryMs = new ArrayList<>();
71+
public List<Long> pingHistoryMs = new ArrayList<>();
7272
/**
7373
* Allows you to set the maximum size of the ping history. This is initially limited to 100 to avoid memory issues in long-running bots.
7474
* If the array exceeds the limit, the oldest ping will be removed.
@@ -106,7 +106,7 @@ private void connectionFlow() {
106106
gatewayUrl = appendGatewayQueryParams(gatewayUrl);
107107
if (bot.isDebug()) logger.info("[Gateway - Connection Flow] Gateway URL with query params: " + gatewayUrl);
108108

109-
socket = new WebSocket(gatewayUrl, bot.isDebug());
109+
socket = new WebSocket(gatewayUrl, bot.isDebug(), bot);
110110
setupDisconnectedSocket(socket);
111111
connectToSocket(socket, false);
112112

@@ -154,7 +154,7 @@ private void resumeFlow() {
154154

155155
String connectUrl = appendGatewayQueryParams(resumeInfo.url());
156156
if (bot.isDebug()) logger.info("[Gateway - Resume Flow] Resume URL: " + connectUrl);
157-
socket = new WebSocket(connectUrl, bot.isDebug());
157+
socket = new WebSocket(connectUrl, bot.isDebug(), bot);
158158
setupDisconnectedSocket(socket);
159159
connectToSocket(socket, true);
160160

@@ -303,7 +303,7 @@ private void handleHello(@NotNull JSONObject payload) {
303303
heartbeatManager.startCycle();
304304
return;
305305
}
306-
heartbeatManager = new HeartLogic(socket, payload.getJSONObject("d").getInt("heartbeat_interval"));
306+
heartbeatManager = new HeartLogic(socket, payload.getJSONObject("d").getInt("heartbeat_interval"), this);
307307
heartbeatManager.start();
308308
}
309309

@@ -553,15 +553,15 @@ public ReconnectInfo getResumeInfo() {
553553
* Returns when the last heartbeat was sent, or null if none were sent yet.
554554
*/
555555
@Nullable
556-
public static Date getLastHeartbeatSent() {
556+
public Date getLastHeartbeatSent() {
557557
return lastHeartbeatSent;
558558
}
559559

560560
/**
561561
* Returns an array of estimated ping times in milliseconds based on heartbeat ACKs.
562562
*/
563563
@NotNull
564-
public static List<Long> getPingHistoryMs() {
564+
public List<Long> getPingHistoryMs() {
565565
return pingHistoryMs;
566566
}
567567

src/main/java/com/seailz/discordjar/gateway/events/DispatchedEvents.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,10 @@ public enum DispatchedEvents {
256256

257257
switch (CommandType.fromCode(p.getJSONObject("d").getJSONObject("data").getInt("type"))) {
258258
case SLASH_COMMAND ->
259-
event = new SlashCommandInteractionEvent(d, Gateway.lastSequenceNumber, p);
260-
case USER -> event = new UserContextCommandInteractionEvent(d, Gateway.lastSequenceNumber, p);
259+
event = new SlashCommandInteractionEvent(d, d.getGateway().lastSequenceNumber, p);
260+
case USER -> event = new UserContextCommandInteractionEvent(d, d.getGateway().lastSequenceNumber, p);
261261
case MESSAGE ->
262-
event = new MessageContextCommandInteractionEvent(d, Gateway.lastSequenceNumber, p);
262+
event = new MessageContextCommandInteractionEvent(d, d.getGateway().lastSequenceNumber, p);
263263
}
264264

265265
d.getCommandDispatcher().dispatch(p.getJSONObject("d").getJSONObject("data").getString("name"),

src/main/java/com/seailz/discordjar/gateway/heartbeat/HeartLogic.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@ public class HeartLogic {
2323
private long lastSequence = -1;
2424
private final Map<UUID, Boolean> isInstanceStillRunning = new HashMap<>();
2525
boolean running = true;
26+
private final Gateway gateway;
2627

27-
public HeartLogic(WebSocket socket, long interval) {
28+
public HeartLogic(WebSocket socket, long interval, Gateway gateway) {
2829
this.interval = interval;
2930
this.socket = socket;
31+
this.gateway = gateway;
3032
}
3133

32-
public HeartLogic(WebSocket socket) {
34+
public HeartLogic(WebSocket socket, Gateway gateway) {
3335
this.socket = socket;
36+
this.gateway = gateway;
3437
}
3538

3639
public void setInterval(long interval) {
@@ -79,7 +82,7 @@ public void start() {
7982
socket.send(
8083
WSPayloads.HEARBEAT.fill(lastSequence == -1 ? JSONObject.NULL : lastSequence).toString()
8184
);
82-
Gateway.lastHeartbeatSent = new Date();
85+
gateway.lastHeartbeatSent = new Date();
8386
Thread.sleep(interval);
8487
} catch (InterruptedException e) {
8588
e.printStackTrace();

src/main/java/com/seailz/discordjar/http/HttpOnlyManager.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ public ResponseEntity<String> get(HttpServletRequest request) throws IOException
7979

8080
switch (CommandType.fromCode(new JSONObject(interaction.raw()).getJSONObject("data").getInt("type"))) {
8181
case SLASH_COMMAND -> {
82-
event = new SlashCommandInteractionEvent(discordJar, Gateway.lastSequenceNumber, new JSONObject().put("d", new JSONObject(body)));
82+
event = new SlashCommandInteractionEvent(discordJar, discordJar.getGateway().lastSequenceNumber, new JSONObject().put("d", new JSONObject(body)));
8383
}
8484
case USER ->
85-
event = new UserContextCommandInteractionEvent(discordJar, Gateway.lastSequenceNumber, new JSONObject().put("d", new JSONObject(body)));
85+
event = new UserContextCommandInteractionEvent(discordJar, discordJar.getGateway().lastSequenceNumber, new JSONObject().put("d", new JSONObject(body)));
8686
case MESSAGE ->
87-
event = new MessageContextCommandInteractionEvent(discordJar, Gateway.lastSequenceNumber, new JSONObject().put("d", new JSONObject(body)));
87+
event = new MessageContextCommandInteractionEvent(discordJar, discordJar.getGateway().lastSequenceNumber, new JSONObject().put("d", new JSONObject(body)));
8888
}
8989

9090
discordJar.getCommandDispatcher().dispatch(new JSONObject(interaction.raw()).getJSONObject("data").getString("name"), event);

src/main/java/com/seailz/discordjar/ws/WebSocket.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.seailz.discordjar.ws;
22

3+
import com.seailz.discordjar.DiscordJar;
34
import okhttp3.OkHttpClient;
45
import okhttp3.Request;
56
import okhttp3.Response;
@@ -17,6 +18,7 @@
1718
import java.nio.charset.StandardCharsets;
1819
import java.util.ArrayList;
1920
import java.util.Arrays;
21+
import java.util.HashMap;
2022
import java.util.List;
2123
import java.util.concurrent.CompletableFuture;
2224
import java.util.concurrent.ExecutionException;
@@ -39,20 +41,21 @@ public class WebSocket extends WebSocketListener {
3941
private final List<Consumer<CloseStatus>> onDisconnectConsumers = new ArrayList<>();
4042
private final List<Runnable> onConnectConsumers = new ArrayList<>();
4143
private Function<CloseStatus, Boolean> reEstablishConnection = (e) -> true;
42-
private static final byte[] ZLIB_SUFFIX = new byte[] { 0, 0, (byte) 0xff, (byte) 0xff };
43-
private static byte[] buffer = {};
44-
private static final Inflater inflator = new Inflater();
44+
private final byte[] ZLIB_SUFFIX = new byte[] { 0, 0, (byte) 0xff, (byte) 0xff };
45+
private byte[] buffer = {};
46+
private final Inflater inflator = new Inflater();
4547
private boolean open = false;
46-
private static final List<WebSocket> webSockets = new ArrayList<>();
48+
private static final HashMap<DiscordJar, List<WebSocket>> webSockets = new HashMap<>();
4749

48-
public WebSocket(String url, boolean debug) {
50+
public WebSocket(String url, boolean debug, DiscordJar jar) {
4951
this.url = url;
5052
this.debug = debug;
5153
if (webSockets.size() > 1) {
5254
// Close all other websockets
53-
webSockets.forEach(WebSocket::disconnect);
55+
webSockets.get(jar).forEach(WebSocket::disconnect);
5456
}
55-
webSockets.add(this);
57+
// Add websockets to the list
58+
webSockets.put(jar, new ArrayList<>(Arrays.asList(this)));
5659
}
5760

5861
public WebsocketAction<Void> connect() {

0 commit comments

Comments
 (0)