|
|
@@ -0,0 +1,91 @@
|
|
|
+const { App, DEDICATED_COMPRESSOR_256KB } = require('uWebSockets.js')
|
|
|
+const ROOMS = {}
|
|
|
+
|
|
|
+// 日志配置
|
|
|
+const log4js = require("log4js");
|
|
|
+log4js.configure({
|
|
|
+ appenders: { socket: { type: "file", filename: "./socket.log" } },
|
|
|
+ categories: { default: { appenders: ["socket"], level: "debug" } }
|
|
|
+});
|
|
|
+const logger = log4js.getLogger('socket');
|
|
|
+
|
|
|
+App().ws('/*', {
|
|
|
+ compression: DEDICATED_COMPRESSOR_256KB,
|
|
|
+ idleTimeout: 12,
|
|
|
+ sendPingsAutomatically: true,
|
|
|
+ upgrade: (res, req, context) => {
|
|
|
+ const url = req.getUrl()
|
|
|
+ const secWebSocketKey = req.getHeader('sec-websocket-key');
|
|
|
+ const secWebSocketProtocol = req.getHeader('sec-websocket-protocol');
|
|
|
+ const secWebSocketExtensions = req.getHeader('sec-websocket-extensions');
|
|
|
+ const prams = url.split('/')
|
|
|
+ if (prams.length > 1 && prams.length <= 3) {
|
|
|
+ const ID = prams[1]
|
|
|
+ const Name = prams[2]
|
|
|
+ const isTrue = ROOMS[ID]
|
|
|
+ if (isTrue) {
|
|
|
+ // 有房间
|
|
|
+ if (isTrue.length >= 2) {
|
|
|
+ // 房间满
|
|
|
+ res.close()
|
|
|
+ } else {
|
|
|
+ ROOMS[ID].push(Name)
|
|
|
+ // 建立连接
|
|
|
+ res.upgrade({ url: url }, secWebSocketKey, secWebSocketProtocol, secWebSocketExtensions, context)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 无房间
|
|
|
+ ROOMS[ID] = []
|
|
|
+ ROOMS[ID].push(Name)
|
|
|
+ // 建立连接
|
|
|
+ res.upgrade({ url: url }, secWebSocketKey, secWebSocketProtocol, secWebSocketExtensions, context)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ res.close()
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ /* 处理程序 */
|
|
|
+ open: (socket) => {
|
|
|
+ /* 订阅主题 */
|
|
|
+ const { url } = socket
|
|
|
+ if (!url) return
|
|
|
+ const prams = url.split('/')
|
|
|
+ const room = prams[1]
|
|
|
+ const name = prams[2]
|
|
|
+ socket.subscribe(`/${room}`)
|
|
|
+ logger.debug(`${name}加入${room}号房间,人数:${ROOMS[room].length}`);
|
|
|
+ },
|
|
|
+ message: (socket, message,isBinary) => {
|
|
|
+ // 转发消息
|
|
|
+ const { url } = socket
|
|
|
+ if (!url) return
|
|
|
+ const room = url.split('/')[1]
|
|
|
+ socket.publish(`/${room}`, message,isBinary);
|
|
|
+
|
|
|
+ // buffer | string | blob
|
|
|
+ // const txt = Buffer.from(message).toString()
|
|
|
+ // console.log('接受消息',message,isBinary);
|
|
|
+ // socket.send(message,isBinary)
|
|
|
+ },
|
|
|
+ close: (socket, code) => {
|
|
|
+ // 连接关闭
|
|
|
+ const { url } = socket
|
|
|
+ if (url) {
|
|
|
+ const prams = url.split('/')
|
|
|
+ if (prams.length <= 1) return
|
|
|
+ // 移除
|
|
|
+ const ID = prams[1]
|
|
|
+ const Name = prams[2]
|
|
|
+ const isHave = ROOMS[ID].indexOf(Name)
|
|
|
+ if (isHave != -1) {
|
|
|
+ ROOMS[ID].splice(isHave, 1)
|
|
|
+ if (!ROOMS[ID].length) delete ROOMS[ID]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log('断开',ROOMS);
|
|
|
+ logger.debug(`所有房间:${JSON.stringify(ROOMS)}`);
|
|
|
+ }
|
|
|
+}).listen(49800, token => {
|
|
|
+ token ? logger.debug(`socket服务启动:49800`) : logger.debug(`socket服务启动失败`);
|
|
|
+})
|