import SocketIoServer from 'socket.io'; import {compose, EventEmitter} from '@avocado/core'; import {SocketIoParser, allPackets, idFromPacket} from '../packet'; const decorateServer = compose( EventEmitter, ); export class SocketServer extends decorateServer(class {}) { constructor() { super(); this.onConnect = this.onConnect.bind(this); } close(fn) { this.io.removeListener('connect', this.onConnect); this.io.close(fn); } onConnect(socket) { this.emit('connect', new ServerSocket(socket)); } open(httpServer) { this.io = new SocketIoServer(httpServer, { parser: SocketIoParser, path: '/avocado', perMessageDeflate: false, serveClient: false, }); this.io.on('connect', this.onConnect); } } const decorateSocket = compose( EventEmitter, ); class ServerSocket extends decorateSocket(class {}) { constructor(socket) { super(); this.socket = socket; for (const Packet of allPackets()) { const id = idFromPacket(Packet); this.socket.on(id, (data) => { this.emit('packet', new Packet(data)); }); } this.socket.on('disconnect', (...args) => { this.emit('disconnect', ...args); }); } disconnect() { this.socket.disconnect(true); } send(packet) { const id = idFromPacket(packet.constructor); this.socket.binary(true).emit(id, packet.data); } }