mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-02 04:56:07 +00:00
fix: socket (#253)
* fix: socket * fix: name * fix: use logger and debugger
This commit is contained in:
parent
330b840b10
commit
8c4a13264e
@ -1,5 +1,5 @@
|
||||
import { inflateSync } from 'node:zlib';
|
||||
import { type MakeRequired, MergeOptions, type Logger } from '../../common';
|
||||
import { Logger, LogLevels, type MakeRequired, MergeOptions } from '../../common';
|
||||
import { properties } from '../constants';
|
||||
import { DynamicBucket } from '../structures';
|
||||
import { ConnectTimeout } from '../structures/timeout';
|
||||
@ -23,6 +23,7 @@ export interface ShardHeart {
|
||||
}
|
||||
|
||||
export class Shard {
|
||||
logger: Logger;
|
||||
debugger?: Logger;
|
||||
data: Partial<ShardData> | ShardData = {
|
||||
resume_seq: null,
|
||||
@ -52,6 +53,11 @@ export class Shard {
|
||||
},
|
||||
} as ShardOptions);
|
||||
|
||||
this.logger = new Logger({
|
||||
name: `[Shard #${id}]`,
|
||||
logLevel: LogLevels.Info,
|
||||
});
|
||||
|
||||
if (options.debugger) this.debugger = options.debugger;
|
||||
|
||||
const safe = this.calculateSafeRequests();
|
||||
@ -91,7 +97,7 @@ export class Shard {
|
||||
async connect() {
|
||||
await this.connectTimeout.wait();
|
||||
if (this.isOpen) {
|
||||
this.debugger?.debug(`[Shard #${this.id}] attempted to connect while open`);
|
||||
this.debugger?.debug(`[Shard #${this.id}] Attempted to connect while open`);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -109,7 +115,7 @@ export class Shard {
|
||||
|
||||
this.websocket.onclose = (event: { code: number; reason: string }) => this.handleClosed(event);
|
||||
|
||||
this.websocket.onerror = (event: ErrorEvent) => this.debugger?.error(event);
|
||||
this.websocket.onerror = (event: ErrorEvent) => this.logger.error(event);
|
||||
|
||||
this.websocket.onopen = () => {
|
||||
this.heart.ack = true;
|
||||
@ -235,7 +241,7 @@ export class Shard {
|
||||
case GatewayOpcodes.InvalidSession:
|
||||
if (packet.d) {
|
||||
if (!this.resumable) {
|
||||
return this.debugger?.fatal(`[Shard #${this.id}] This is a completely unexpected error message.`);
|
||||
return this.logger.fatal(`This is a completely unexpected error message.`);
|
||||
}
|
||||
await this.resume();
|
||||
} else {
|
||||
@ -269,8 +275,8 @@ export class Shard {
|
||||
|
||||
protected async handleClosed(close: { code: number; reason: string }) {
|
||||
clearInterval(this.heart.nodeInterval);
|
||||
this.debugger?.warn(
|
||||
`[Shard #${this.id}] ${ShardSocketCloseCodes[close.code] ?? GatewayCloseCodes[close.code] ?? close.code} (${close.code})`,
|
||||
this.logger.warn(
|
||||
`${ShardSocketCloseCodes[close.code] ?? GatewayCloseCodes[close.code] ?? close.code} (${close.code})`,
|
||||
close.reason,
|
||||
);
|
||||
|
||||
@ -295,7 +301,7 @@ export class Shard {
|
||||
case GatewayCloseCodes.NotAuthenticated:
|
||||
case GatewayCloseCodes.AlreadyAuthenticated:
|
||||
case GatewayCloseCodes.RateLimited:
|
||||
this.debugger?.info(`[Shard #${this.id}] Trying to reconnect`);
|
||||
this.logger.info(`Trying to reconnect`);
|
||||
await this.reconnect();
|
||||
break;
|
||||
|
||||
@ -305,11 +311,11 @@ export class Shard {
|
||||
case GatewayCloseCodes.InvalidIntents:
|
||||
case GatewayCloseCodes.InvalidShard:
|
||||
case GatewayCloseCodes.ShardingRequired:
|
||||
this.debugger?.fatal(`[Shard #${this.id}] cannot reconnect`);
|
||||
this.logger.fatal(`Cannot reconnect`);
|
||||
break;
|
||||
|
||||
default:
|
||||
this.debugger?.warn(`[Shard #${this.id}] Unknown close code, trying to reconnect anyways`);
|
||||
this.logger.warn(`Unknown close code, trying to reconnect anyways`);
|
||||
await this.reconnect();
|
||||
break;
|
||||
}
|
||||
@ -324,10 +330,17 @@ export class Shard {
|
||||
}
|
||||
|
||||
protected handleMessage(data: string | Buffer) {
|
||||
if (data instanceof Buffer) {
|
||||
data = inflateSync(data);
|
||||
let packet;
|
||||
try {
|
||||
if (data instanceof Buffer) {
|
||||
data = inflateSync(data);
|
||||
}
|
||||
packet = JSON.parse(data as string);
|
||||
} catch (e) {
|
||||
this.logger.error(e);
|
||||
return;
|
||||
}
|
||||
return this.onpacket(JSON.parse(data as string));
|
||||
return this.onpacket(packet);
|
||||
}
|
||||
|
||||
checkOffline(force: boolean) {
|
||||
|
@ -28,45 +28,57 @@ export class SeyfertWebSocket {
|
||||
this.connect();
|
||||
}
|
||||
|
||||
private connect() {
|
||||
const key = randomBytes(16).toString('base64');
|
||||
const req = request({
|
||||
//discord gateway hostname
|
||||
hostname: this.hostname,
|
||||
path: this.path,
|
||||
headers: {
|
||||
Connection: 'Upgrade',
|
||||
Upgrade: 'websocket',
|
||||
'Sec-WebSocket-Key': key,
|
||||
'Sec-WebSocket-Version': '13',
|
||||
},
|
||||
private connect(retries = 0) {
|
||||
return new Promise<void>((resolve, rej) => {
|
||||
const key = randomBytes(16).toString('base64');
|
||||
const req = request({
|
||||
//discord gateway hostname
|
||||
hostname: this.hostname,
|
||||
path: this.path,
|
||||
headers: {
|
||||
Connection: 'Upgrade',
|
||||
Upgrade: 'websocket',
|
||||
'Sec-WebSocket-Key': key,
|
||||
'Sec-WebSocket-Version': '13',
|
||||
},
|
||||
});
|
||||
|
||||
req.on('upgrade', (res, socket) => {
|
||||
const hash = createHash('sha1').update(`${key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`).digest('base64');
|
||||
const accept = res.headers['sec-websocket-accept'];
|
||||
if (accept !== hash) {
|
||||
socket.end(() => {
|
||||
rej(new Error('Invalid sec-websocket-accept header'));
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.socket = socket;
|
||||
|
||||
socket.on('readable', this.handleReadable.bind(this));
|
||||
|
||||
socket.on('close', this.handleClose.bind(this));
|
||||
|
||||
socket.on('error', err => this.onerror(err));
|
||||
resolve();
|
||||
this.onopen();
|
||||
});
|
||||
|
||||
req.on('close', () => {
|
||||
req.removeAllListeners();
|
||||
});
|
||||
|
||||
req.on('error', e => {
|
||||
if (retries < 5) {
|
||||
setTimeout(() => {
|
||||
resolve(this.connect(retries + 1));
|
||||
}, 500);
|
||||
} else {
|
||||
rej(e);
|
||||
}
|
||||
});
|
||||
|
||||
req.end();
|
||||
});
|
||||
|
||||
req.on('upgrade', (res, socket) => {
|
||||
const hash = createHash('sha1').update(`${key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`).digest('base64');
|
||||
const accept = res.headers['sec-websocket-accept'];
|
||||
if (accept !== hash) {
|
||||
socket.end(() => {
|
||||
this.onerror(new Error('Invalid sec-websocket-accept header'));
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.socket = socket;
|
||||
|
||||
socket.on('readable', this.handleReadable.bind(this));
|
||||
|
||||
socket.on('close', this.handleClose.bind(this));
|
||||
|
||||
socket.on('error', err => this.onerror(err));
|
||||
|
||||
this.onopen();
|
||||
});
|
||||
|
||||
req.on('close', () => {
|
||||
req.removeAllListeners();
|
||||
});
|
||||
|
||||
req.end();
|
||||
}
|
||||
|
||||
handleReadable() {
|
||||
@ -148,7 +160,7 @@ export class SeyfertWebSocket {
|
||||
}
|
||||
}
|
||||
|
||||
handleClose() {
|
||||
async handleClose() {
|
||||
this.socket?.removeAllListeners();
|
||||
this.socket?.destroy();
|
||||
this.socket = undefined;
|
||||
|
Loading…
x
Reference in New Issue
Block a user