140 lines
3.2 KiB
JavaScript
140 lines
3.2 KiB
JavaScript
"use strict";
|
|
|
|
import EventEmitter from 'events';
|
|
import WebSocket from 'ws';
|
|
|
|
class PPfunSocket extends EventEmitter {
|
|
constructor(url, apisocketkey) {
|
|
super();
|
|
this.url = url;
|
|
this.apisocketkey = apisocketkey;
|
|
this.timeConnected = null;
|
|
this.isConnected = false;
|
|
this.flagMap = new Map();
|
|
this.flagMap.set(null , 'yy');
|
|
this.ws;
|
|
this.onWsClose = this.onWsClose.bind(this);
|
|
console.log('PPfunSocket: Connecting to WebSocket')
|
|
|
|
this.on('sendChatMessage', (name, uid, msg, cid) => {
|
|
if (this.isConnected) {
|
|
const flag = (name.endsWith('berg') || name.endsWith('stein'))
|
|
? 'il' : this.getFlag(uid);
|
|
const pack = ['chat', name, uid, msg, flag, cid];
|
|
this.ws.send(JSON.stringify(pack));
|
|
}
|
|
});
|
|
}
|
|
|
|
getFlag(uid) {
|
|
let flag = this.flagMap.get(uid);
|
|
if (!flag) {
|
|
if (flag !== null) {
|
|
this.flagMap.set(uid, null);
|
|
this.ws.send(`["getflag", ${uid}]`);
|
|
}
|
|
return 'yy';
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
run() {
|
|
return new Promise((resolve) => {
|
|
this.connect();
|
|
this.once('open', () => {
|
|
resolve();
|
|
})
|
|
});
|
|
}
|
|
|
|
connect() {
|
|
if (this.ws) {
|
|
console.log('PPfunSocket: WebSocket already open, not starting');
|
|
}
|
|
|
|
this.timeConnected = Date.now();
|
|
|
|
const ws = new WebSocket(this.url, {
|
|
headers: {
|
|
'authorization': `Bearer ${this.apisocketkey}`,
|
|
},
|
|
});
|
|
this.ws = ws;
|
|
|
|
ws.on('open', () => {
|
|
this.isConnected = true;
|
|
this.reqChannels();
|
|
this.emit('open');
|
|
console.log('PPfunSocket: Connected to WebSocket');
|
|
});
|
|
|
|
ws.on('message', (data, isBinary) => {
|
|
if (!isBinary) {
|
|
const message = data.toString();
|
|
this.onTextMessage(message);
|
|
}
|
|
});
|
|
|
|
ws.on('error', (e) => {
|
|
console.warn(
|
|
'PPfunSocket: Socket encountered error, closing socket',
|
|
e.toString(),
|
|
);
|
|
ws.close;
|
|
});
|
|
|
|
ws.on('close', this.onWsClose);
|
|
}
|
|
|
|
reqChannels() {
|
|
if (this.isConnected) {
|
|
this.ws.send('["sub","chat"]');
|
|
}
|
|
}
|
|
|
|
onWsClose() {
|
|
this.emit('close');
|
|
this.ws = null;
|
|
this.isConnected = false;
|
|
// reconnect in 1s if last connect was longer than 7s ago, else 5s
|
|
const timeout = this.timeConnected < Date.now() - 7000 ? 1000 : 5000;
|
|
console.warn(
|
|
`PPfunSocket: Socket is closed. Reconnect will be attempted in ${timeout} ms.`,
|
|
);
|
|
setTimeout(() => this.connect(), 5000);
|
|
}
|
|
|
|
onTextMessage(message) {
|
|
try {
|
|
const data = JSON.parse(message);
|
|
const msgEvent = data[0];
|
|
data.shift();
|
|
switch(msgEvent) {
|
|
case 'chans':
|
|
this.emit('chanList', data);
|
|
break;
|
|
case 'msg': {
|
|
const [name, uid, msg,, cid] = data;
|
|
this.emit('chatMessage', name, uid, msg, cid);
|
|
break;
|
|
}
|
|
case 'flag': {
|
|
const [uid, flag] = data;
|
|
console.log(`PPfunSocket: Got flag ${flag} for user ${uid}`);
|
|
this.flagMap.set(uid, flag);
|
|
break;
|
|
}
|
|
default:
|
|
// nothing
|
|
}
|
|
} catch (e) {
|
|
console.warn(
|
|
`PPfunSocket: An error occured while parsing websocket text message`,
|
|
e.toString(),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
export default PPfunSocket;
|