fix: temporally using ws

This commit is contained in:
MARCROCK22 2024-08-09 16:18:27 +00:00
parent a337862938
commit 983043f9c3
6 changed files with 108 additions and 55 deletions

View File

@ -22,7 +22,8 @@
"author": "MARCROCK22",
"license": "Apache-2.0",
"dependencies": {
"magic-bytes.js": "^1.10.0"
"magic-bytes.js": "^1.10.0",
"ws": "^8.18.0"
},
"lint-staged": {
"*.ts": [
@ -34,6 +35,7 @@
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@types/node": "^20.14.11",
"@types/ws": "^8.5.12",
"husky": "^9.1.1",
"lint-staged": "^15.2.7",
"rimraf": "5.0.9",

27
pnpm-lock.yaml generated
View File

@ -11,6 +11,9 @@ importers:
magic-bytes.js:
specifier: ^1.10.0
version: 1.10.0
ws:
specifier: ^8.18.0
version: 8.18.0
optionalDependencies:
chokidar:
specifier: ^3.6.0
@ -37,6 +40,9 @@ importers:
'@types/node':
specifier: ^20.14.11
version: 20.14.11
'@types/ws':
specifier: ^8.5.12
version: 8.5.12
husky:
specifier: ^9.1.1
version: 9.1.1
@ -203,6 +209,9 @@ packages:
'@types/node@20.14.11':
resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==}
'@types/ws@8.5.12':
resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==}
JSONStream@1.3.5:
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
hasBin: true
@ -865,6 +874,18 @@ packages:
resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
engines: {node: '>=18'}
ws@8.18.0:
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@ -1071,6 +1092,10 @@ snapshots:
dependencies:
undici-types: 5.26.5
'@types/ws@8.5.12':
dependencies:
'@types/node': 20.14.11
JSONStream@1.3.5:
dependencies:
jsonparse: 1.3.1
@ -1682,6 +1707,8 @@ snapshots:
string-width: 7.2.0
strip-ansi: 7.1.0
ws@8.18.0: {}
y18n@5.0.8: {}
yaml@2.4.5: {}

View File

@ -1,25 +1,27 @@
import { randomUUID } from 'node:crypto';
import { SeyfertWebSocket } from './socket/custom';
// import { SeyfertWebSocket } from './socket/custom';
import { WebSocket as NodeJSWebSocket } from 'ws';
export class BaseSocket {
private internal: SeyfertWebSocket | WebSocket;
private internal: NodeJSWebSocket | WebSocket;
ping?: () => Promise<number>;
constructor(kind: 'ws' | 'bun', url: string) {
this.internal = kind === 'ws' ? new SeyfertWebSocket(url) : new WebSocket(url);
this.internal = kind === 'ws' ? new NodeJSWebSocket(url) : new WebSocket(url);
// this.internal = kind === 'ws' ? new SeyfertWebSocket(url) : new WebSocket(url);
if (kind === 'ws') {
const ws = this.internal as SeyfertWebSocket;
this.ping = ws.waitPing.bind(ws);
ws.onpong = data => {
const promise = ws.__promises.get(data);
if (promise) {
ws.__promises.delete(data);
promise?.resolve();
}
};
} else {
// if (kind === 'ws') {
// const ws = this.internal as NodeJSWebSocket;
// this.ping = ws.waitPing.bind(ws);
// ws.onpong = data => {
// const promise = ws.__promises.get(data);
// if (promise) {
// ws.__promises.delete(data);
// promise?.resolve();
// }
// };
// } else {
const ws = this.internal as WebSocket;
this.ping = () => {
return new Promise<number>(res => {
@ -37,22 +39,22 @@ export class BaseSocket {
ws.ping(nonce);
});
};
}
// }
}
set onopen(callback: SeyfertWebSocket['onopen']) {
set onopen(callback: NodeJSWebSocket['onopen']) {
this.internal.onopen = callback;
}
set onmessage(callback: SeyfertWebSocket['onmessage']) {
set onmessage(callback: NodeJSWebSocket['onmessage']) {
this.internal.onmessage = callback;
}
set onclose(callback: SeyfertWebSocket['onclose']) {
set onclose(callback: NodeJSWebSocket['onclose']) {
this.internal.onclose = callback;
}
set onerror(callback: SeyfertWebSocket['onerror']) {
set onerror(callback: NodeJSWebSocket['onerror']) {
this.internal.onerror = callback;
}
@ -60,7 +62,8 @@ export class BaseSocket {
return this.internal.send(data);
}
close(...args: Parameters<SeyfertWebSocket['close']>) {
close(...args: Parameters<NodeJSWebSocket['close']>) {
//@ts-expect-error
return this.internal.close(...args);
}

View File

@ -25,7 +25,7 @@ export interface ShardHeart {
export class Shard {
debugger?: Logger;
data: Partial<ShardData> | ShardData = {
resumeSeq: null,
resume_seq: null,
};
websocket: BaseSocket | null = null;
@ -95,18 +95,20 @@ export class Shard {
return;
}
clearTimeout(this.heart.nodeInterval);
this.debugger?.debug(`[Shard #${this.id}] Connecting to ${this.currentGatewayURL}`);
// @ts-expect-error @types/bun cause erros in compile
// biome-ignore lint/correctness/noUndeclaredVariables: /\ bun lol
this.websocket = new BaseSocket(typeof Bun === 'undefined' ? 'ws' : 'bun', this.currentGatewayURL);
//@ts-expect-error
this.websocket!.onmessage = ({ data }: { data: string | Buffer }) => {
this.handleMessage(data);
};
this.websocket!.onclose = (event: { code: number; reason: string }) => this.handleClosed(event);
//@ts-expect-error
this.websocket!.onerror = (event: ErrorEvent) => this.debugger?.error(event);
this.websocket!.onopen = () => {
@ -150,14 +152,14 @@ export class Shard {
}
get resumable() {
return !!(this.data.resume_gateway_url && this.data.session_id && this.data.resumeSeq !== null);
return !!(this.data.resume_gateway_url && this.data.session_id && this.data.resume_seq !== null);
}
async resume() {
await this.send(true, {
op: GatewayOpcodes.Resume,
d: {
seq: this.data.resumeSeq!,
seq: this.data.resume_seq!,
session_id: this.data.session_id!,
token: `Bot ${this.options.token}`,
},
@ -181,7 +183,7 @@ export class Shard {
this.websocket!.send(
JSON.stringify({
op: GatewayOpcodes.Heartbeat,
d: this.data.resumeSeq ?? null,
d: this.data.resume_seq ?? null,
}),
);
}
@ -199,10 +201,10 @@ export class Shard {
async onpacket(packet: GatewayReceivePayload) {
if (packet.s !== null) {
this.data.resumeSeq = packet.s;
this.data.resume_seq = packet.s;
}
this.debugger?.debug(`[Shard #${this.id}]`, packet.t ? packet.t : GatewayOpcodes[packet.op], this.data.resumeSeq);
this.debugger?.debug(`[Shard #${this.id}]`, packet.t ? packet.t : GatewayOpcodes[packet.op], this.data.resume_seq);
switch (packet.op) {
case GatewayOpcodes.Hello:
@ -237,7 +239,7 @@ export class Shard {
}
await this.resume();
} else {
this.data.resumeSeq = 0;
this.data.resume_seq = 0;
this.data.session_id = undefined;
await this.identify();
}
@ -277,17 +279,22 @@ export class Shard {
//Force disconnect, ignore
break;
case 1000:
case GatewayCloseCodes.UnknownOpcode:
case GatewayCloseCodes.InvalidSeq:
case GatewayCloseCodes.SessionTimedOut:
this.data.resume_seq = 0;
this.data.session_id = undefined;
this.data.resume_gateway_url = undefined;
await this.reconnect();
break;
case 1001:
case 1006:
case ShardSocketCloseCodes.ZombiedConnection:
case GatewayCloseCodes.UnknownError:
case GatewayCloseCodes.UnknownOpcode:
case GatewayCloseCodes.DecodeError:
case GatewayCloseCodes.NotAuthenticated:
case GatewayCloseCodes.AlreadyAuthenticated:
case GatewayCloseCodes.InvalidSeq:
case GatewayCloseCodes.RateLimited:
case GatewayCloseCodes.SessionTimedOut:
this.debugger?.info(`[Shard #${this.id}] Trying to reconnect`);
await this.reconnect();
break;

View File

@ -66,7 +66,7 @@ export interface WorkerManagerOptions extends Omit<ShardManagerOptions, 'handleP
export interface ShardData {
/** resume seq to resume connections */
resumeSeq: number | null;
resume_seq: number | null;
/**
* resume_gateway_url is the url to resume the connection

View File

@ -15,6 +15,10 @@ export class SeyfertWebSocket {
reject: (reason?: any) => void;
}
>();
__lastError: null | {
code: number;
reason: string;
} = null;
constructor(
url: string,
@ -55,6 +59,10 @@ export class SeyfertWebSocket {
this.handleReadable();
});
socket.on('close', () => {
this.handleClose();
});
socket.on('error', err => {
this.onerror(err);
});
@ -135,15 +143,21 @@ export class SeyfertWebSocket {
break;
// close
case 0x8:
{
const code = body.readUInt16BE(0);
const reason = body.subarray(2).toString();
this.onclose({ code, reason });
}
this.__lastError = {
code: body.readUInt16BE(0),
reason: body.subarray(2).toString(),
};
this.socket?.destroy();
break;
}
}
handleClose() {
if (!this.__lastError) return this.connect();
this.onclose(this.__lastError);
this.__lastError = null;
}
send(data: string) {
this._write(Buffer.from(data), 1);
}