mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00
fix: temporally using ws
This commit is contained in:
parent
a337862938
commit
983043f9c3
@ -22,7 +22,8 @@
|
|||||||
"author": "MARCROCK22",
|
"author": "MARCROCK22",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"magic-bytes.js": "^1.10.0"
|
"magic-bytes.js": "^1.10.0",
|
||||||
|
"ws": "^8.18.0"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.ts": [
|
"*.ts": [
|
||||||
@ -34,6 +35,7 @@
|
|||||||
"@commitlint/cli": "^19.3.0",
|
"@commitlint/cli": "^19.3.0",
|
||||||
"@commitlint/config-conventional": "^19.2.2",
|
"@commitlint/config-conventional": "^19.2.2",
|
||||||
"@types/node": "^20.14.11",
|
"@types/node": "^20.14.11",
|
||||||
|
"@types/ws": "^8.5.12",
|
||||||
"husky": "^9.1.1",
|
"husky": "^9.1.1",
|
||||||
"lint-staged": "^15.2.7",
|
"lint-staged": "^15.2.7",
|
||||||
"rimraf": "5.0.9",
|
"rimraf": "5.0.9",
|
||||||
|
27
pnpm-lock.yaml
generated
27
pnpm-lock.yaml
generated
@ -11,6 +11,9 @@ importers:
|
|||||||
magic-bytes.js:
|
magic-bytes.js:
|
||||||
specifier: ^1.10.0
|
specifier: ^1.10.0
|
||||||
version: 1.10.0
|
version: 1.10.0
|
||||||
|
ws:
|
||||||
|
specifier: ^8.18.0
|
||||||
|
version: 8.18.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
chokidar:
|
chokidar:
|
||||||
specifier: ^3.6.0
|
specifier: ^3.6.0
|
||||||
@ -37,6 +40,9 @@ importers:
|
|||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20.14.11
|
specifier: ^20.14.11
|
||||||
version: 20.14.11
|
version: 20.14.11
|
||||||
|
'@types/ws':
|
||||||
|
specifier: ^8.5.12
|
||||||
|
version: 8.5.12
|
||||||
husky:
|
husky:
|
||||||
specifier: ^9.1.1
|
specifier: ^9.1.1
|
||||||
version: 9.1.1
|
version: 9.1.1
|
||||||
@ -203,6 +209,9 @@ packages:
|
|||||||
'@types/node@20.14.11':
|
'@types/node@20.14.11':
|
||||||
resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==}
|
resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==}
|
||||||
|
|
||||||
|
'@types/ws@8.5.12':
|
||||||
|
resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==}
|
||||||
|
|
||||||
JSONStream@1.3.5:
|
JSONStream@1.3.5:
|
||||||
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
|
resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -865,6 +874,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
|
resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
|
||||||
engines: {node: '>=18'}
|
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:
|
y18n@5.0.8:
|
||||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -1071,6 +1092,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 5.26.5
|
undici-types: 5.26.5
|
||||||
|
|
||||||
|
'@types/ws@8.5.12':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 20.14.11
|
||||||
|
|
||||||
JSONStream@1.3.5:
|
JSONStream@1.3.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
jsonparse: 1.3.1
|
jsonparse: 1.3.1
|
||||||
@ -1682,6 +1707,8 @@ snapshots:
|
|||||||
string-width: 7.2.0
|
string-width: 7.2.0
|
||||||
strip-ansi: 7.1.0
|
strip-ansi: 7.1.0
|
||||||
|
|
||||||
|
ws@8.18.0: {}
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|
||||||
yaml@2.4.5: {}
|
yaml@2.4.5: {}
|
||||||
|
@ -1,58 +1,60 @@
|
|||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import { SeyfertWebSocket } from './socket/custom';
|
// import { SeyfertWebSocket } from './socket/custom';
|
||||||
|
import { WebSocket as NodeJSWebSocket } from 'ws';
|
||||||
|
|
||||||
export class BaseSocket {
|
export class BaseSocket {
|
||||||
private internal: SeyfertWebSocket | WebSocket;
|
private internal: NodeJSWebSocket | WebSocket;
|
||||||
|
|
||||||
ping?: () => Promise<number>;
|
ping?: () => Promise<number>;
|
||||||
|
|
||||||
constructor(kind: 'ws' | 'bun', url: string) {
|
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') {
|
// if (kind === 'ws') {
|
||||||
const ws = this.internal as SeyfertWebSocket;
|
// const ws = this.internal as NodeJSWebSocket;
|
||||||
this.ping = ws.waitPing.bind(ws);
|
// this.ping = ws.waitPing.bind(ws);
|
||||||
ws.onpong = data => {
|
// ws.onpong = data => {
|
||||||
const promise = ws.__promises.get(data);
|
// const promise = ws.__promises.get(data);
|
||||||
if (promise) {
|
// if (promise) {
|
||||||
ws.__promises.delete(data);
|
// ws.__promises.delete(data);
|
||||||
promise?.resolve();
|
// promise?.resolve();
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
} else {
|
// } else {
|
||||||
const ws = this.internal as WebSocket;
|
const ws = this.internal as WebSocket;
|
||||||
this.ping = () => {
|
this.ping = () => {
|
||||||
return new Promise<number>(res => {
|
return new Promise<number>(res => {
|
||||||
const nonce = randomUUID();
|
const nonce = randomUUID();
|
||||||
const start = performance.now();
|
const start = performance.now();
|
||||||
const listener = (data: Buffer) => {
|
const listener = (data: Buffer) => {
|
||||||
if (data.toString() !== nonce) return;
|
if (data.toString() !== nonce) return;
|
||||||
//@ts-expect-error bun support
|
|
||||||
ws.removeListener('pong', listener);
|
|
||||||
res(performance.now() - start);
|
|
||||||
};
|
|
||||||
//@ts-expect-error bun support
|
//@ts-expect-error bun support
|
||||||
ws.on('pong', listener);
|
ws.removeListener('pong', listener);
|
||||||
//@ts-expect-error bun support
|
res(performance.now() - start);
|
||||||
ws.ping(nonce);
|
};
|
||||||
});
|
//@ts-expect-error bun support
|
||||||
};
|
ws.on('pong', listener);
|
||||||
}
|
//@ts-expect-error bun support
|
||||||
|
ws.ping(nonce);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
set onopen(callback: SeyfertWebSocket['onopen']) {
|
set onopen(callback: NodeJSWebSocket['onopen']) {
|
||||||
this.internal.onopen = callback;
|
this.internal.onopen = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
set onmessage(callback: SeyfertWebSocket['onmessage']) {
|
set onmessage(callback: NodeJSWebSocket['onmessage']) {
|
||||||
this.internal.onmessage = callback;
|
this.internal.onmessage = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
set onclose(callback: SeyfertWebSocket['onclose']) {
|
set onclose(callback: NodeJSWebSocket['onclose']) {
|
||||||
this.internal.onclose = callback;
|
this.internal.onclose = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
set onerror(callback: SeyfertWebSocket['onerror']) {
|
set onerror(callback: NodeJSWebSocket['onerror']) {
|
||||||
this.internal.onerror = callback;
|
this.internal.onerror = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +62,8 @@ export class BaseSocket {
|
|||||||
return this.internal.send(data);
|
return this.internal.send(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(...args: Parameters<SeyfertWebSocket['close']>) {
|
close(...args: Parameters<NodeJSWebSocket['close']>) {
|
||||||
|
//@ts-expect-error
|
||||||
return this.internal.close(...args);
|
return this.internal.close(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ export interface ShardHeart {
|
|||||||
export class Shard {
|
export class Shard {
|
||||||
debugger?: Logger;
|
debugger?: Logger;
|
||||||
data: Partial<ShardData> | ShardData = {
|
data: Partial<ShardData> | ShardData = {
|
||||||
resumeSeq: null,
|
resume_seq: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
websocket: BaseSocket | null = null;
|
websocket: BaseSocket | null = null;
|
||||||
@ -95,18 +95,20 @@ export class Shard {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearTimeout(this.heart.nodeInterval);
|
||||||
|
|
||||||
this.debugger?.debug(`[Shard #${this.id}] Connecting to ${this.currentGatewayURL}`);
|
this.debugger?.debug(`[Shard #${this.id}] Connecting to ${this.currentGatewayURL}`);
|
||||||
|
|
||||||
// @ts-expect-error @types/bun cause erros in compile
|
// @ts-expect-error @types/bun cause erros in compile
|
||||||
// biome-ignore lint/correctness/noUndeclaredVariables: /\ bun lol
|
// biome-ignore lint/correctness/noUndeclaredVariables: /\ bun lol
|
||||||
this.websocket = new BaseSocket(typeof Bun === 'undefined' ? 'ws' : 'bun', this.currentGatewayURL);
|
this.websocket = new BaseSocket(typeof Bun === 'undefined' ? 'ws' : 'bun', this.currentGatewayURL);
|
||||||
|
//@ts-expect-error
|
||||||
this.websocket!.onmessage = ({ data }: { data: string | Buffer }) => {
|
this.websocket!.onmessage = ({ data }: { data: string | Buffer }) => {
|
||||||
this.handleMessage(data);
|
this.handleMessage(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.websocket!.onclose = (event: { code: number; reason: string }) => this.handleClosed(event);
|
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!.onerror = (event: ErrorEvent) => this.debugger?.error(event);
|
||||||
|
|
||||||
this.websocket!.onopen = () => {
|
this.websocket!.onopen = () => {
|
||||||
@ -150,14 +152,14 @@ export class Shard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get resumable() {
|
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() {
|
async resume() {
|
||||||
await this.send(true, {
|
await this.send(true, {
|
||||||
op: GatewayOpcodes.Resume,
|
op: GatewayOpcodes.Resume,
|
||||||
d: {
|
d: {
|
||||||
seq: this.data.resumeSeq!,
|
seq: this.data.resume_seq!,
|
||||||
session_id: this.data.session_id!,
|
session_id: this.data.session_id!,
|
||||||
token: `Bot ${this.options.token}`,
|
token: `Bot ${this.options.token}`,
|
||||||
},
|
},
|
||||||
@ -181,7 +183,7 @@ export class Shard {
|
|||||||
this.websocket!.send(
|
this.websocket!.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
op: GatewayOpcodes.Heartbeat,
|
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) {
|
async onpacket(packet: GatewayReceivePayload) {
|
||||||
if (packet.s !== null) {
|
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) {
|
switch (packet.op) {
|
||||||
case GatewayOpcodes.Hello:
|
case GatewayOpcodes.Hello:
|
||||||
@ -237,7 +239,7 @@ export class Shard {
|
|||||||
}
|
}
|
||||||
await this.resume();
|
await this.resume();
|
||||||
} else {
|
} else {
|
||||||
this.data.resumeSeq = 0;
|
this.data.resume_seq = 0;
|
||||||
this.data.session_id = undefined;
|
this.data.session_id = undefined;
|
||||||
await this.identify();
|
await this.identify();
|
||||||
}
|
}
|
||||||
@ -277,17 +279,22 @@ export class Shard {
|
|||||||
//Force disconnect, ignore
|
//Force disconnect, ignore
|
||||||
break;
|
break;
|
||||||
case 1000:
|
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 1001:
|
||||||
case 1006:
|
case 1006:
|
||||||
case ShardSocketCloseCodes.ZombiedConnection:
|
case ShardSocketCloseCodes.ZombiedConnection:
|
||||||
case GatewayCloseCodes.UnknownError:
|
case GatewayCloseCodes.UnknownError:
|
||||||
case GatewayCloseCodes.UnknownOpcode:
|
|
||||||
case GatewayCloseCodes.DecodeError:
|
case GatewayCloseCodes.DecodeError:
|
||||||
case GatewayCloseCodes.NotAuthenticated:
|
case GatewayCloseCodes.NotAuthenticated:
|
||||||
case GatewayCloseCodes.AlreadyAuthenticated:
|
case GatewayCloseCodes.AlreadyAuthenticated:
|
||||||
case GatewayCloseCodes.InvalidSeq:
|
|
||||||
case GatewayCloseCodes.RateLimited:
|
case GatewayCloseCodes.RateLimited:
|
||||||
case GatewayCloseCodes.SessionTimedOut:
|
|
||||||
this.debugger?.info(`[Shard #${this.id}] Trying to reconnect`);
|
this.debugger?.info(`[Shard #${this.id}] Trying to reconnect`);
|
||||||
await this.reconnect();
|
await this.reconnect();
|
||||||
break;
|
break;
|
||||||
|
@ -66,7 +66,7 @@ export interface WorkerManagerOptions extends Omit<ShardManagerOptions, 'handleP
|
|||||||
|
|
||||||
export interface ShardData {
|
export interface ShardData {
|
||||||
/** resume seq to resume connections */
|
/** resume seq to resume connections */
|
||||||
resumeSeq: number | null;
|
resume_seq: number | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* resume_gateway_url is the url to resume the connection
|
* resume_gateway_url is the url to resume the connection
|
||||||
|
@ -15,6 +15,10 @@ export class SeyfertWebSocket {
|
|||||||
reject: (reason?: any) => void;
|
reject: (reason?: any) => void;
|
||||||
}
|
}
|
||||||
>();
|
>();
|
||||||
|
__lastError: null | {
|
||||||
|
code: number;
|
||||||
|
reason: string;
|
||||||
|
} = null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
url: string,
|
url: string,
|
||||||
@ -55,6 +59,10 @@ export class SeyfertWebSocket {
|
|||||||
this.handleReadable();
|
this.handleReadable();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('close', () => {
|
||||||
|
this.handleClose();
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('error', err => {
|
socket.on('error', err => {
|
||||||
this.onerror(err);
|
this.onerror(err);
|
||||||
});
|
});
|
||||||
@ -135,15 +143,21 @@ export class SeyfertWebSocket {
|
|||||||
break;
|
break;
|
||||||
// close
|
// close
|
||||||
case 0x8:
|
case 0x8:
|
||||||
{
|
this.__lastError = {
|
||||||
const code = body.readUInt16BE(0);
|
code: body.readUInt16BE(0),
|
||||||
const reason = body.subarray(2).toString();
|
reason: body.subarray(2).toString(),
|
||||||
this.onclose({ code, reason });
|
};
|
||||||
}
|
this.socket?.destroy();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleClose() {
|
||||||
|
if (!this.__lastError) return this.connect();
|
||||||
|
this.onclose(this.__lastError);
|
||||||
|
this.__lastError = null;
|
||||||
|
}
|
||||||
|
|
||||||
send(data: string) {
|
send(data: string) {
|
||||||
this._write(Buffer.from(data), 1);
|
this._write(Buffer.from(data), 1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user