110 lines
2.4 KiB
JavaScript
110 lines
2.4 KiB
JavaScript
import D from 'debug';
|
|
import SocketIoServer from 'socket.io';
|
|
|
|
import {compose, EventEmitter} from '@avocado/core';
|
|
|
|
import * as SocketIoParser from '../packet/socket.io-parser';
|
|
|
|
const debug = D('@avocado/net:socket');
|
|
|
|
const decorateServer = compose(
|
|
EventEmitter,
|
|
);
|
|
|
|
export class SocketServer extends decorateServer(class {}) {
|
|
|
|
constructor(httpServer, options) {
|
|
super();
|
|
this.onConnect = this.onConnect.bind(this);
|
|
if (httpServer) {
|
|
this.open(httpServer, options);
|
|
}
|
|
}
|
|
|
|
close(fn) {
|
|
this.io.removeListener('connect', this.onConnect);
|
|
this.io.close(fn);
|
|
}
|
|
|
|
of(nsp) {
|
|
return this.io.of(nsp);
|
|
}
|
|
|
|
onConnect(socket) {
|
|
this.emit('connect', new ServerSocket(socket));
|
|
}
|
|
|
|
open(httpServer, options = {}) {
|
|
this.io = new SocketIoServer(httpServer, {
|
|
...options,
|
|
parser: SocketIoParser,
|
|
path: '/avocado',
|
|
perMessageDeflate: false,
|
|
serveClient: false,
|
|
});
|
|
this.io.on('connect', this.onConnect);
|
|
}
|
|
|
|
send(packet, channel = '/') {
|
|
const {idFrom} = require('../packet/registrar');
|
|
const id = idFrom(packet.constructor);
|
|
this.io.sockets.to(channel).binary(true).emit(id, packet.data);
|
|
}
|
|
|
|
}
|
|
|
|
const decorateSocket = compose(
|
|
EventEmitter,
|
|
);
|
|
|
|
class ServerSocket extends decorateSocket(class {}) {
|
|
|
|
constructor(socket) {
|
|
super();
|
|
this.socket = socket;
|
|
const {all, idFrom} = require('../packet/packets.scwp');
|
|
const entries = Object.entries(all());
|
|
for (let i = 0; i < entries.length; i++) {
|
|
const [, M] = entries[i];
|
|
const {default: Packet} = M;
|
|
const id = idFrom(M);
|
|
this.socket.on(id, (data, fn) => {
|
|
const packet = new Packet(data);
|
|
debug('recieved packet %o', packet);
|
|
this.emit('packet', packet, fn);
|
|
});
|
|
}
|
|
this.socket.on('disconnect', (...args) => {
|
|
this.emit('disconnect', ...args);
|
|
});
|
|
}
|
|
|
|
disconnect() {
|
|
this.socket.disconnect(true);
|
|
}
|
|
|
|
get id() {
|
|
return this.socket ? this.socket.id : undefined;
|
|
}
|
|
|
|
leave(channel) {
|
|
this.socket.leave(channel);
|
|
}
|
|
|
|
join(channel) {
|
|
this.socket.join(channel);
|
|
}
|
|
|
|
send(packet, fn) {
|
|
debug('sending packet %o', packet);
|
|
const {idFrom} = require('../packet/registrar');
|
|
const id = idFrom(packet.constructor);
|
|
this.socket.binary(true).emit(id, packet.data, fn);
|
|
}
|
|
|
|
get session() {
|
|
return this.socket.handshake.session;
|
|
}
|
|
|
|
}
|