diff --git a/src/core/ChatProvider.js b/src/core/ChatProvider.js index 0e652d2..d7b045b 100644 --- a/src/core/ChatProvider.js +++ b/src/core/ChatProvider.js @@ -3,12 +3,12 @@ import { Op } from 'sequelize'; import logger from './logger'; import redis from '../data/redis'; import User from '../data/models/User'; -import webSockets from '../socket/websockets'; import RateLimiter from '../utils/RateLimiter'; import { Channel, RegUser, UserChannel, Message, } from '../data/models'; import ChatMessageBuffer from './ChatMessageBuffer'; +import socketEvents from '../socket/SocketEvents'; import { cheapDetector } from './isProxy'; import { DailyCron } from '../utils/cron'; import ttags from './ttag'; @@ -51,6 +51,18 @@ export class ChatProvider { this.mutedCountries = []; this.chatMessageBuffer = new ChatMessageBuffer(); this.clearOldMessages = this.clearOldMessages.bind(this); + + socketEvents.on('recvChatMessage', (user, message, channelId) => { + const errorMsg = this.sendMessage(user, message, channelId); + if (errorMsg) { + this.broadcastChatMessage( + 'info', + errorMsg, + channelId, + this.infoUserId, + ); + } + }); } async clearOldMessages() { @@ -174,7 +186,7 @@ export class ChatProvider { }); if (created) { - webSockets.broadcastAddChatChannel( + socketEvents.broadcastAddChatChannel( userId, channelId, channelArray, @@ -430,7 +442,7 @@ export class ChatProvider { id, country, ); - webSockets.broadcastChatMessage( + socketEvents.broadcastChatMessage( name, message, channelId, @@ -497,5 +509,4 @@ export class ChatProvider { } } -const chatProvider = new ChatProvider(); -export default chatProvider; +export default new ChatProvider(); diff --git a/src/core/PixelCache.js b/src/core/PixelCache.js index a19a4e7..78e407c 100644 --- a/src/core/PixelCache.js +++ b/src/core/PixelCache.js @@ -4,7 +4,7 @@ * @flow */ -import webSockets from '../socket/websockets'; +import socketEvents from '../socket/SocketEvents'; class PixelCache { PXL_CACHE: Map; @@ -56,7 +56,7 @@ class PixelCache { cache.forEach((pxls, chunkCanvasId) => { const canvasId = (chunkCanvasId & 0xFF0000) >> 16; const chunkId = chunkCanvasId & 0x00FFFF; - webSockets.broadcastPixels(canvasId, chunkId, pxls); + socketEvents.broadcastPixels(canvasId, chunkId, pxls); }); } } diff --git a/src/core/Void.js b/src/core/Void.js index 2970201..9663b36 100644 --- a/src/core/Void.js +++ b/src/core/Void.js @@ -6,8 +6,7 @@ * * @flow */ -import webSockets from '../socket/websockets'; -import WebSocketEvents from '../socket/WebSocketEvents'; +import socketEvents from '../socket/SocketEvents'; import PixelUpdate from '../socket/packets/PixelUpdateServer'; import { setPixelByOffset } from './setPixel'; import { TILE_SIZE } from './constants'; @@ -19,7 +18,7 @@ const TARGET_RADIUS = 62; const EVENT_DURATION_MIN = 10; // const EVENT_DURATION_MIN = 1; -class Void extends WebSocketEvents { +class Void { i: number; j: number; maxClr: number; @@ -33,7 +32,6 @@ class Void extends WebSocketEvents { ended: boolean; constructor(centerCell) { - super(); // chunk coordinates const [i, j] = centerCell; this.i = i; @@ -41,7 +39,7 @@ class Void extends WebSocketEvents { this.ended = false; this.maxClr = canvases[CANVAS_ID].colors.length; const area = TARGET_RADIUS ** 2 * Math.PI; - const online = webSockets.onlineCounter; + const online = socketEvents.onlineCounter; // require an average of 0.25 px / min / user const requiredSpeed = Math.floor(online / 1.8); const ppm = Math.ceil(area / EVENT_DURATION_MIN + requiredSpeed); @@ -60,7 +58,7 @@ class Void extends WebSocketEvents { this.cancel = this.cancel.bind(this); this.checkStatus = this.checkStatus.bind(this); this.broadcastPixelBuffer = this.broadcastPixelBuffer.bind(this); - webSockets.addListener(this); + socketEvents.addListener('pixelUpdate', this.broadcastPixelBuffer); this.voidLoop(); } @@ -162,13 +160,13 @@ class Void extends WebSocketEvents { } cancel() { - webSockets.remListener(this); + socketEvents.removeListener('pixelUpdate', this.broadcastPixelBuffer); this.ended = true; } checkStatus() { if (this.ended) { - webSockets.remListener(this); + socketEvents.removeListener('pixelUpdate', this.broadcastPixelBuffer); return 100; } return Math.floor(this.curRadius * 100 / TARGET_RADIUS); diff --git a/src/routes/api/auth/change_name.js b/src/routes/api/auth/change_name.js index f3ee2db..7db6f81 100644 --- a/src/routes/api/auth/change_name.js +++ b/src/routes/api/auth/change_name.js @@ -6,7 +6,7 @@ import type { Request, Response } from 'express'; -import webSockets from '../../../socket/websockets'; +import socketEvents from '../../../socket/SocketEvents'; import { RegUser } from '../../../data/models'; import { validateName } from '../../../utils/validation'; @@ -46,7 +46,7 @@ export default async (req: Request, res: Response) => { await user.regUser.update({ name }); - webSockets.reloadUser(oldname); + socketEvents.reloadUser(oldname); res.json({ success: true, diff --git a/src/routes/api/auth/verify.js b/src/routes/api/auth/verify.js index 601070e..2e22c45 100644 --- a/src/routes/api/auth/verify.js +++ b/src/routes/api/auth/verify.js @@ -5,7 +5,7 @@ import type { Request, Response } from 'express'; -import webSockets from '../../../socket/websockets'; +import socketEvents from '../../../socket/SocketEvents'; import getHtml from '../../../ssr-components/RedirectionPage'; import { getHostFromRequest } from '../../../utils/ip'; import mailProvider from '../../../core/mail'; @@ -19,7 +19,7 @@ export default async (req: Request, res: Response) => { if (name) { // notify websoecket to reconnect user // thats a bit counter productive because it directly links to the websocket - webSockets.reloadUser(name); + socketEvents.reloadUser(name); // --- const index = getHtml( t`Mail verification`, diff --git a/src/routes/api/block.js b/src/routes/api/block.js index 3fc97f7..e8ac252 100644 --- a/src/routes/api/block.js +++ b/src/routes/api/block.js @@ -8,7 +8,7 @@ import type { Request, Response } from 'express'; import logger from '../../core/logger'; -import webSockets from '../../socket/websockets'; +import socketEvents from '../../socket/SocketEvents'; import { RegUser, UserBlock, Channel } from '../../data/models'; async function block(req: Request, res: Response) { @@ -108,8 +108,8 @@ async function block(req: Request, res: Response) { if (channel) { const channelId = channel.id; channel.destroy(); - webSockets.broadcastRemoveChatChannel(user.id, channelId); - webSockets.broadcastRemoveChatChannel(userId, channelId); + socketEvents.broadcastRemoveChatChannel(user.id, channelId); + socketEvents.broadcastRemoveChatChannel(userId, channelId); } if (ret) { diff --git a/src/routes/api/blockdm.js b/src/routes/api/blockdm.js index 3677baf..410b205 100644 --- a/src/routes/api/blockdm.js +++ b/src/routes/api/blockdm.js @@ -8,7 +8,7 @@ import type { Request, Response } from 'express'; import logger from '../../core/logger'; -import webSockets from '../../socket/websockets'; +import socketEvents from '../../socket/SocketEvents'; async function blockdm(req: Request, res: Response) { const { block } = req.body; @@ -47,8 +47,8 @@ async function blockdm(req: Request, res: Response) { const channelId = channel.id; const { dmu1id, dmu2id } = channel; channel.destroy(); - webSockets.broadcastRemoveChatChannel(dmu1id, channelId); - webSockets.broadcastRemoveChatChannel(dmu2id, channelId); + socketEvents.broadcastRemoveChatChannel(dmu1id, channelId); + socketEvents.broadcastRemoveChatChannel(dmu2id, channelId); } } diff --git a/src/routes/api/leavechan.js b/src/routes/api/leavechan.js index 59070d5..b0b1aac 100644 --- a/src/routes/api/leavechan.js +++ b/src/routes/api/leavechan.js @@ -8,7 +8,7 @@ import type { Request, Response } from 'express'; import logger from '../../core/logger'; -import webSockets from '../../socket/websockets'; +import socketEvents from '../../socket/SocketEvents'; async function leaveChan(req: Request, res: Response) { const channelId = parseInt(req.body.channelId, 10); @@ -65,7 +65,7 @@ async function leaveChan(req: Request, res: Response) { user.regUser.removeChannel(channel); - webSockets.broadcastRemoveChatChannel(user.id, channelId); + socketEvents.broadcastRemoveChatChannel(user.id, channelId); res.json({ status: 'ok', diff --git a/src/socket/APISocketServer.js b/src/socket/APISocketServer.js index 46d43c5..80b587a 100644 --- a/src/socket/APISocketServer.js +++ b/src/socket/APISocketServer.js @@ -10,14 +10,11 @@ import WebSocket from 'ws'; - -import WebSocketEvents from './WebSocketEvents'; -import webSockets from './websockets'; +import socketEvents from './SocketEvents'; import { getIPFromRequest } from '../utils/ip'; import { setPixelByCoords } from '../core/setPixel'; import logger from '../core/logger'; import { APISOCKET_KEY } from '../core/config'; -import chatProvider from '../core/ChatProvider'; function heartbeat() { this.isAlive = true; @@ -38,13 +35,11 @@ async function verifyClient(info, done) { } -class APISocketServer extends WebSocketEvents { +class APISocketServer { wss: WebSocket.Server; constructor() { - super(); logger.info('Starting API websocket server'); - webSockets.addListener(this); const wss = new WebSocket.Server({ perMessageDeflate: false, @@ -75,7 +70,15 @@ class APISocketServer extends WebSocketEvents { }); }); + this.broadcast = this.broadcast.bind(this); + this.broadcastPixelBuffer = this.broadcastPixelBuffer.bind(this); this.ping = this.ping.bind(this); + this.broadcastChatMessage = this.broadcastChatMessage.bind(this); + + socketEvents.on('broadcast', this.broadcast); + socketEvents.on('pixelUpdate', this.broadcastPixelBuffer); + socketEvents.on('chatMessage', this.broadcastChatMessage); + setInterval(this.ping, 45 * 1000); } @@ -100,26 +103,34 @@ class APISocketServer extends WebSocketEvents { }); } - broadcastOnlineCounter(buffer) { - const frame = WebSocket.Sender.frame(buffer, { - readOnly: true, - mask: false, - rsv1: false, - opcode: 2, - fin: true, - }); - this.wss.clients.forEach((client) => { - if (client.subOnline && client.readyState === WebSocket.OPEN) { - frame.forEach((data) => { - try { - // eslint-disable-next-line no-underscore-dangle - client._socket.write(data); - } catch (error) { - logger.error('(!) Catched error on write apisocket:', error); - } - }); - } - }); + broadcast(data) { + if (typeof data === 'string') { + this.wss.clients.forEach((ws) => { + if (ws.readyState === WebSocket.OPEN) { + ws.send(data); + } + }); + } else { + const frame = WebSocket.Sender.frame(data, { + readOnly: true, + mask: false, + rsv1: false, + opcode: 2, + fin: true, + }); + this.wss.clients.forEach((ws) => { + if (ws.readyState === WebSocket.OPEN) { + frame.forEach((buffer) => { + try { + // eslint-disable-next-line no-underscore-dangle + ws._socket.write(buffer); + } catch (error) { + logger.error(`WebSocket broadcast error: ${error.message}`); + } + }); + } + }); + } } broadcastPixelBuffer(canvasId, chunkid, buffer) { @@ -181,11 +192,17 @@ class APISocketServer extends WebSocketEvents { logger.info(`APISocket message ${message}`); if (command === 'chat') { const [name, msg, country, channelId] = packet; - chatProvider.broadcastChatMessage( + /* + * do not send message back up ws that sent it + * TODO: user id should not be hardcoded, + * consider it whenever this actually gets used and + * becomes an issue. + */ + socketEvents.broadcastChatMessage( name, msg, channelId, - chatProvider.infoUserId, + 1, country, false, ); @@ -193,7 +210,7 @@ class APISocketServer extends WebSocketEvents { name, msg, channelId, - chatProvider.infoUserId, + 1, country, true, ws, diff --git a/src/socket/websockets.js b/src/socket/SocketEvents.js similarity index 59% rename from src/socket/websockets.js rename to src/socket/SocketEvents.js index 84f7599..5e85d9e 100644 --- a/src/socket/websockets.js +++ b/src/socket/SocketEvents.js @@ -1,42 +1,25 @@ /* @flow * - * Serverside communication with websockets. - * In general all values that get broadcasted here have to be sanitized already. - * + * Events for WebSockets */ +import EventEmitter from 'events'; import OnlineCounter from './packets/OnlineCounter'; import PixelUpdate from './packets/PixelUpdateServer'; -class WebSockets { - listeners: Array; - onlineCounter: number; - +class SocketEvents extends EventEmitter { constructor() { - this.listeners = []; + super(); this.onlineCounter = 0; } - addListener(listener) { - this.listeners.push(listener); - } - - remListener(listener) { - const index = this.listeners.indexOf(listener); - if (index > -1) { - this.listeners.splice(index, 1); - } - } - /* * broadcast message via websocket * @param message Message to send */ broadcast(message: Buffer) { - this.listeners.forEach( - (listener) => listener.broadcast(message), - ); + this.emit('broadcast', message); } /* @@ -51,9 +34,21 @@ class WebSockets { pixels: Buffer, ) { const buffer = PixelUpdate.dehydrate(chunkId, pixels); - this.listeners.forEach( - (listener) => listener.broadcastPixelBuffer(canvasId, chunkId, buffer), - ); + this.emit('pixelUpdate', canvasId, chunkId, buffer); + } + + /* + * received Chat message on own websocket + * @param user User Instance that sent the message + * @param message text message + * @param channelId numerical channel id + */ + recvChatMessage( + user: Object, + message: string, + channelId: number, + ) { + this.emit('recvChatMessage', user, message, channelId); } /* @@ -71,16 +66,14 @@ class WebSockets { country: string = 'xx', sendapi: boolean = true, ) { - country = country || 'xx'; - this.listeners.forEach( - (listener) => listener.broadcastChatMessage( - name, - message, - channelId, - id, - country, - sendapi, - ), + this.emit( + 'chatMessage', + name, + message, + channelId, + id, + country || 'xx', + sendapi, ); } @@ -95,12 +88,11 @@ class WebSockets { channelId: number, channelArray: Array, ) { - this.listeners.forEach( - (listener) => listener.broadcastAddChatChannel( - userId, - channelId, - channelArray, - ), + this.emit( + 'addChatChannel', + userId, + channelId, + channelArray, ); } @@ -114,21 +106,14 @@ class WebSockets { userId: number, channelId: number, ) { - this.listeners.forEach( - (listener) => listener.broadcastRemoveChatChannel( - userId, - channelId, - ), - ); + this.emit('remChatChannel', userId, channelId); } /* * reload user on websocket to get changes */ reloadUser(name: string) { - this.listeners.forEach( - (listener) => listener.reloadUser(name), - ); + this.emit('reloadUser', name); } /* @@ -138,11 +123,8 @@ class WebSockets { broadcastOnlineCounter(online: number) { this.onlineCounter = online; const buffer = OnlineCounter.dehydrate({ online }); - this.listeners.forEach( - (listener) => listener.broadcastOnlineCounter(buffer), - ); + this.emit('broadcast', buffer); } } -const webSockets = new WebSockets(); -export default webSockets; +export default new SocketEvents(); diff --git a/src/socket/SocketServer.js b/src/socket/SocketServer.js index fd4b5bf..0f35c92 100644 --- a/src/socket/SocketServer.js +++ b/src/socket/SocketServer.js @@ -18,10 +18,9 @@ import DeRegisterMultipleChunks from './packets/DeRegisterMultipleChunks'; import ChangedMe from './packets/ChangedMe'; import OnlineCounter from './packets/OnlineCounter'; +import socketEvents from './SocketEvents'; import chatProvider, { ChatProvider } from '../core/ChatProvider'; import authenticateClient from './verifyClient'; -import WebSocketEvents from './WebSocketEvents'; -import webSockets from './websockets'; import { drawSafeByOffsets } from '../core/draw'; import { needCaptcha } from '../utils/captcha'; import { cheapDetector } from '../core/isProxy'; @@ -50,16 +49,14 @@ async function verifyClient(info, done) { } -class SocketServer extends WebSocketEvents { +class SocketServer { wss: WebSocket.Server; CHUNK_CLIENTS: Map; // constructor(server: http.Server) { constructor() { - super(); this.CHUNK_CLIENTS = new Map(); logger.info('Starting websocket server'); - webSockets.addListener(this); const wss = new WebSocket.Server({ perMessageDeflate: false, @@ -80,7 +77,6 @@ class SocketServer extends WebSocketEvents { ws.isAlive = true; ws.canvasId = null; ws.startDate = Date.now(); - ws.on('pong', heartbeat); const user = await authenticateClient(req); ws.user = user; ws.name = user.getName(); @@ -91,15 +87,20 @@ class SocketServer extends WebSocketEvents { })); const ip = getIPFromRequest(req); + ws.on('error', (e) => { logger.error(`WebSocket Client Error for ${ws.name}: ${e.message}`); }); + + ws.on('pong', heartbeat); + ws.on('close', () => { // is close called on terminate? // possible memory leak? ipCounter.delete(ip); this.deleteAllChunks(ws); }); + ws.on('message', (message) => { if (typeof message === 'string') { this.onTextMessage(message, ws); @@ -109,18 +110,53 @@ class SocketServer extends WebSocketEvents { }); }); + this.broadcast = this.broadcast.bind(this); + this.broadcastPixelBuffer = this.broadcastPixelBuffer.bind(this); + this.reloadUser = this.reloadUser.bind(this); this.ping = this.ping.bind(this); - /* - * i don't tink that we really need that, it just stresses the server - * with lots of reconnects at once, the overhead of having a few idle - * connections isn't too bad in comparison - */ - // this.killOld = this.killOld.bind(this); - // setInterval(this.killOld, 10 * 60 * 1000); + socketEvents.on('broadcast', this.broadcast); + socketEvents.on('pixelUpdate', this.broadcastPixelBuffer); + socketEvents.on('reloadUser', this.reloadUser); + + socketEvents.on('chatMessage', ( + name, + message, + channelId, + id, + country, + ) => { + const text = JSON.stringify([name, message, country, channelId, id]); + this.wss.clients.forEach((ws) => { + if (ws.readyState === WebSocket.OPEN) { + if (chatProvider.userHasChannelAccess(ws.user, channelId)) { + ws.send(text); + } + } + }); + }); + + socketEvents.on('addChatChannel', (userId, channelId, channelArray) => { + this.findAllWsByUerId(userId).forEach((ws) => { + ws.user.addChannel(channelId, channelArray); + const text = JSON.stringify([ + 'addch', { + [channelId]: channelArray, + }, + ]); + ws.send(text); + }); + }); + + socketEvents.on('remChatChannel', (userId, channelId) => { + this.findAllWsByUerId(userId).forEach((ws) => { + ws.user.removeChannel(channelId); + const text = JSON.stringify(['remch', channelId]); + ws.send(text); + }); + }); setInterval(SocketServer.onlineCounterBroadcast, 10 * 1000); - // https://github.com/websockets/ws#how-to-detect-and-close-broken-connections setInterval(this.ping, 45 * 1000); } @@ -129,47 +165,34 @@ class SocketServer extends WebSocketEvents { * https://github.com/websockets/ws/issues/617 * @param data */ - broadcast(data: Buffer) { - const frame = WebSocket.Sender.frame(data, { - readOnly: true, - mask: false, - rsv1: false, - opcode: 2, - fin: true, - }); - this.wss.clients.forEach((ws) => { - if (ws.readyState === WebSocket.OPEN) { - frame.forEach((buffer) => { - try { - // eslint-disable-next-line no-underscore-dangle - ws._socket.write(buffer); - } catch (error) { - logger.error(`WebSocket broadcast error: ${error.message}`); - } - }); - } - }); - } - - broadcastOnlineCounter(buffer: Buffer) { - this.broadcast(buffer); - } - - broadcastChatMessage( - name: string, - message: string, - channelId: number, - id: number, - country: string, - ) { - const text = JSON.stringify([name, message, country, channelId, id]); - this.wss.clients.forEach((ws) => { - if (ws.readyState === WebSocket.OPEN) { - if (chatProvider.userHasChannelAccess(ws.user, channelId)) { - ws.send(text); + broadcast(data) { + if (typeof data === 'string') { + this.wss.clients.forEach((ws) => { + if (ws.readyState === WebSocket.OPEN) { + ws.send(data); } - } - }); + }); + } else { + const frame = WebSocket.Sender.frame(data, { + readOnly: true, + mask: false, + rsv1: false, + opcode: 2, + fin: true, + }); + this.wss.clients.forEach((ws) => { + if (ws.readyState === WebSocket.OPEN) { + frame.forEach((buffer) => { + try { + // eslint-disable-next-line no-underscore-dangle + ws._socket.write(buffer); + } catch (error) { + logger.error(`WebSocket broadcast error: ${error.message}`); + } + }); + } + }); + } } /* @@ -189,35 +212,18 @@ class SocketServer extends WebSocketEvents { return null; } - broadcastAddChatChannel( - userId: number, - channelId: number, - channelArray: Array, - ) { - this.wss.clients.forEach((ws) => { + findAllWsByUerId(userId) { + const clients = []; + const it = this.wss.clients.keys(); + let client = it.next(); + while (!client.done) { + const ws = client.value; if (ws.user.id === userId && ws.readyState === WebSocket.OPEN) { - ws.user.addChannel(channelId, channelArray); - const text = JSON.stringify([ - 'addch', { - [channelId]: channelArray, - }, - ]); - ws.send(text); + clients.push(ws); } - }); - } - - broadcastRemoveChatChannel( - userId: number, - channelId: number, - ) { - this.wss.clients.forEach((ws) => { - if (ws.user.id === userId && ws.readyState === WebSocket.OPEN) { - ws.user.removeChannel(channelId); - const text = JSON.stringify(['remch', channelId]); - ws.send(text); - } - }); + client = it.next(); + } + return clients; } broadcastPixelBuffer(canvasId: number, chunkid, data: Buffer) { @@ -263,14 +269,6 @@ class SocketServer extends WebSocketEvents { }); } - killOld() { - const now = Date.now(); - this.wss.clients.forEach((ws) => { - const lifetime = now - ws.startDate; - if (lifetime > 30 * 60 * 1000 && Math.random() < 0.3) ws.terminate(); - }); - } - ping() { this.wss.clients.forEach((ws) => { if (!ws.isAlive) { @@ -284,7 +282,7 @@ class SocketServer extends WebSocketEvents { static onlineCounterBroadcast() { const online = ipCounter.amount() || 0; - webSockets.broadcastOnlineCounter(online); + socketEvents.broadcastOnlineCounter(online); } async onTextMessage(text, ws) { @@ -319,6 +317,9 @@ class SocketServer extends WebSocketEvents { * if DM channel, make sure that other user has DM open * (needed because we allow user to leave one-sided * and auto-join on message) + * TODO: if we scale and have multiple websocket servers at some point + * this might be an issue. We would hve to make a shared list of online + * users and act based on that on 'chatMessage' event */ const dmUserId = chatProvider.checkIfDm(user, channelId); if (dmUserId) { @@ -337,20 +338,11 @@ class SocketServer extends WebSocketEvents { /* * send chat message */ - const errorMsg = await chatProvider.sendMessage( + socketEvents.recvChatMessage( user, message, channelId, ); - if (errorMsg) { - ws.send(JSON.stringify([ - 'info', - errorMsg, - 'il', - channelId, - chatProvider.infoUserId, - ])); - } } else { logger.info('Got empty message or message from unidentified ws'); } diff --git a/src/socket/WebSocketEvents.js b/src/socket/WebSocketEvents.js deleted file mode 100644 index 9a06262..0000000 --- a/src/socket/WebSocketEvents.js +++ /dev/null @@ -1,44 +0,0 @@ -/* @flow - * - * Parent class for socket servers - * - */ - -/* eslint-disable no-unused-vars */ -/* eslint-disable class-methods-use-this */ - -class WebSocketEvents { - broadcast(message: Buffer) { - } - - broadcastPixelBuffer(canvasId: number, chunkid: number, buffer: Buffer) { - } - - broadcastChatMessage( - name: string, - message: string, - channelId: number, - userId: number, - ) {} - - broadcastAddChatChannel( - userId: number, - channelId: number, - channelArray: Array, - ) { - } - - broadcastRemoveChatChannel( - userId: number, - channelId: number, - ) { - } - - reloadUser(name: string) { - } - - broadcastOnlineCounter(data: Buffer) { - } -} - -export default WebSocketEvents; diff --git a/src/web.js b/src/web.js index 02c1743..cb52820 100644 --- a/src/web.js +++ b/src/web.js @@ -194,9 +194,9 @@ const promise = models.sync({ alter: { drop: false } }) // const promise = models.sync() .catch((err) => logger.error(err.stack)); promise.then(() => { + rankings.updateRanking(); + chatProvider.initialize(); server.listen(PORT, HOST, () => { - rankings.updateRanking(); - chatProvider.initialize(); const address = server.address(); logger.log( 'info',