mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-01 00:10:07 +00:00
I prefer semicolors, they also help avoiding certain pitfalls in JavaScript/TypeScript, such as the following code sample: ```js const xyz = "test" (something.else as string) = "another" ``` This results in a TypeError: "test" is not a function, this is because js thinks we are trying to call the string "test" as a function. To fix this it requires a `;` somewhere before the `(`, such as `;(something ... ` which in my opinion is ugly and less clean overall.
92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import { type DiscordGatewayPayload, GatewayOpcodes } from '@discordeno/types';
|
|
import { type WebSocket, WebSocketServer } from 'ws';
|
|
|
|
/**
|
|
* This value needs to be AT LEAST `1017`
|
|
*
|
|
* The reason for this is because the calculation in Shard.calculateSafeRequests will return 0 not allowing any sort of message to the websocket server.
|
|
* Discord uses a way higher number for this value, but during this test we lower it since it would be annoying and useless make the test last 40+ seconds to test the heartbeat, but to make this work it needs to be at least 1017 so that calculateSafeRequests return 2 allowing for the shard to send messages.
|
|
*/
|
|
export const heartbeatInterval = 1017;
|
|
|
|
export function creatWSServer(options: CreateWsServerOptions) {
|
|
// Port 0 according to the node:http docs is for requesting the OS a random unused port
|
|
const server = new WebSocketServer({ port: 0 });
|
|
|
|
const address = server.address();
|
|
if (typeof address !== 'object' || !address) {
|
|
throw new TypeError('The address of the WebSocketServer should be an non-null object');
|
|
}
|
|
|
|
server.on('connection', (socket) => {
|
|
send(socket, {
|
|
op: GatewayOpcodes.Hello,
|
|
s: null,
|
|
d: {
|
|
heartbeat_interval: heartbeatInterval,
|
|
},
|
|
});
|
|
|
|
options.onOpen?.();
|
|
|
|
socket.on('message', (data) => {
|
|
const msg = JSON.parse(data.toString('utf-8'));
|
|
options.onMessage?.(msg);
|
|
|
|
switch (msg.op) {
|
|
case GatewayOpcodes.Heartbeat: {
|
|
send(socket, {
|
|
op: GatewayOpcodes.HeartbeatACK,
|
|
s: null,
|
|
});
|
|
|
|
break;
|
|
}
|
|
|
|
case GatewayOpcodes.Identify: {
|
|
send(socket, {
|
|
op: GatewayOpcodes.Dispatch,
|
|
t: 'READY',
|
|
s: 1,
|
|
d: {
|
|
v: 10,
|
|
user: {
|
|
id: '0',
|
|
username: 'test',
|
|
discriminator: '0',
|
|
global_name: 'test',
|
|
avatar: null,
|
|
bot: true,
|
|
verified: true,
|
|
email: null,
|
|
flags: 0,
|
|
},
|
|
shard: [0, 1],
|
|
session_id: '0',
|
|
resume_gateway_url: `ws://localhost:${address.port}`,
|
|
guilds: [],
|
|
application: { id: '0', flags: 0 },
|
|
},
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
return {
|
|
port: address.port,
|
|
close: () => server.close(),
|
|
};
|
|
}
|
|
|
|
export interface CreateWsServerOptions {
|
|
onOpen?: () => any;
|
|
onMessage?: (message: DiscordGatewayPayload) => any;
|
|
}
|
|
|
|
function send(ws: WebSocket, payload: object) {
|
|
ws.send(JSON.stringify(payload));
|
|
}
|