UNPKG

kcola

Version:

一个基于koa2,小而美的RESTful API+MVC的web开发框架!

95 lines (84 loc) 2.48 kB
/* eslint-disable no-unused-vars */ const url = require('url'); const WebSocket = require('ws'); const EventEmitter = require('events').EventEmitter; const {getClientIp} = require('../../utils'); const eventEmitter = new EventEmitter(); module.exports = (server, router) => { console.log('* enable websocket server'); const wssDic = new Map(); Object.keys(router).forEach((key) => { wssDic[key] = createWSServer(router[key]); }); server.on('upgrade', (request, socket, head) => { // todo 权限校验, 这儿 or 中间件? const namespace = parseControllerName(`/${request.url.replace(/^\/|\/$/g, '')}/`); const wss = wssDic[namespace]; if (wss) { wss.handleUpgrade(request, socket, head, (ws) => { wss.emit('connection', ws, request); }); } else { socket.destroy(); } }); }; /** * *通过url解析出Controller名称 * @param {string} urlStr * @return {string} controllername */ function parseControllerName(urlStr) { if (!urlStr) { return ''; } const {pathname} = url.parse(urlStr); return pathname; } /** * 创建Websocket服务 * 并初始化controller的动作 * @param {*} actions * @return {WebSocket.Server} */ function createWSServer(actions) { const wss = new WebSocket.Server({noServer: true}); // 创建完全与HTTP服务器分离的Websocket服务器 wss.on('connection', (ws, request) => { const ip = getClientIp(request); console.log('[kcola websocket server] 连接成功-', ip, request.url); ws.on('message', (packet) => { console.log('[kcola websocket server] packet:', packet); let packetObj = null; try { packetObj = JSON.parse(packet); } catch (error) { console.log(error); return; } if (!packetObj || !packetObj.action) { // message 格式校验 return; } // console.log(wss.url); const action = actions[packetObj.action]; if (action) { const result = action.apply(ws, [wss.clients, packetObj.data]); if (result && result instanceof Promise) { result.then(function(data) { if (data) { ws.send(JSON.stringify(data), () => { console.log('发送完成'); }); } }); } else { ws.send(JSON.stringify(result), () => { console.log('发送完成'); }); } } }); }); return wss; }