Last active
June 25, 2020 17:52
-
-
Save crosstyan/8036093d1dbdc1106352a435e95466a3 to your computer and use it in GitHub Desktop.
A websocket based multiroom chat with node.js.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import WebSocket from 'ws' | |
import mongodb, { ObjectID } from 'mongodb' | |
import * as querystring from 'querystring' | |
import {v4 as uuid} from 'uuid' | |
//Connect to ws://127.0.0.1:8081/thread?name=yourGroupname | |
//to test the server | |
interface WsSessionGroup{ | |
id?: ObjectID | |
name?:string | |
wsSessions: WebSocket[] | |
//Or use a map with uuid | |
//wsSessions:Record<string,WebSocket> | |
} | |
class WsHub{ | |
wsSessionGroupMap: Record<string, WsSessionGroup> = {} | |
//wsSessionGroupMap:Map<string,WsSessionGroup> = new Map | |
addSession(groupName:string,session:WebSocket) { | |
if (this.wsSessionGroupMap[groupName]==undefined){ | |
const sessionGroup = new ThreadSessionGroup | |
sessionGroup.name = groupName | |
sessionGroup.wsSessions.push(session) | |
this.wsSessionGroupMap[groupName] = sessionGroup | |
//If you wanna use uuid map | |
// const uid = uuid() | |
// this.wsSessionGroupMap[groupName].wsSessions[uid]=session | |
console.log(`New group "${groupName}" created`) | |
} | |
else { | |
this.wsSessionGroupMap[groupName].wsSessions.push(session) | |
console.log(`Old group "${groupName}" connected`) | |
} | |
} | |
deleteSession(groupName:string,session:WebSocket) { | |
const sessionList = this.wsSessionGroupMap[groupName].wsSessions | |
sessionList.splice(sessionList.indexOf(session), 1) | |
console.log(`A member from group "${groupName}" disconnected`) | |
if (sessionList.length == 0) { | |
delete this.wsSessionGroupMap[groupName] | |
console.log(`Delete empty group "${groupName}"`) | |
} | |
} | |
broadcastGroup(groupName:string, message: WebSocket.Data):void { | |
const targetGroup = this.wsSessionGroupMap[groupName] | |
targetGroup?.wsSessions.forEach((session) => { | |
if (session.readyState === WebSocket.OPEN) { | |
session.send(message) | |
} | |
}) | |
console.log(`"${message}" from "${groupName}"`) | |
} | |
} | |
class ThreadSessionGroup implements WsSessionGroup{ | |
id?: ObjectID | |
name?:string | |
wsSessions: WebSocket[] =[] | |
} | |
const threadHub = new WsHub | |
const threadWs = new WebSocket.Server({ | |
port: 8081, | |
path: "/thread", | |
}) | |
threadWs.on('connection', (socket, req) => { | |
const reParam=req.url?.match(/(?<=\?).+/) | |
const urlParam = querystring.decode(reParam![0]) | |
const sessionNameInURL = urlParam.name?.toString()! | |
if ('name' in urlParam) { | |
threadHub.addSession(sessionNameInURL,socket) | |
} | |
else { | |
socket.close(4001,"Params aren't correct. ") | |
} | |
socket.on('message', (message) => { | |
threadHub.broadcastGroup(sessionNameInURL,message) | |
}) | |
socket.on('close', () => { | |
threadHub.deleteSession(sessionNameInURL, socket) | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment