From 7ddf80b7216fc18537f8b6bf6856c20b8e87758a Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Wed, 22 Apr 2015 07:58:48 +0200 Subject: Add persistance of users and lobbies --- .gitignore | 3 +- chatserver.js | 88 +++++++++++++++++++++++++++++++++++++++++++++-------------- package.json | 30 ++++++++++++++++++++ 3 files changed, 100 insertions(+), 21 deletions(-) create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 3c3629e..6477552 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules +node_modules/ +persist/ diff --git a/chatserver.js b/chatserver.js index a263d62..69ee637 100755 --- a/chatserver.js +++ b/chatserver.js @@ -2,7 +2,8 @@ var fs=require("fs"), http=require("http"), WebSocketServer=require("ws").Server, - CircularBuffer=require("circular-buffer"); + CircularBuffer=require("circular-buffer"), + Persist=require("node-persist"); var HTTPPORT=81,WSPORT=8000; @@ -13,14 +14,43 @@ function uniqid(){ return uniqid.$++; } -var users=[]; -var lobbies=[]; - function lobby_create(lname){ lobbies.push({id:uniqid(),name:lname,users:[],history:new CircularBuffer(10)}); } -["a_lobby","lobby_2"].forEach(lobby_create); +var __do_persist_users_timeout=null; +function do_persist_users(){ + if(__do_persist_users_timeout)return; + __do_persist_users_timeout=setTimeout(function(){ + __do_persist_users_timeout=null; + Persist.setItem("users",users); + },10*1000); +} +var __do_persist_lobbies_timeout=null; +function do_persist_lobbies(){ + if(__do_persist_lobbies_timeout)return; + __do_persist_lobbies_timeout=setTimeout(function(){ + __do_persist_lobbies_timeout=null; + Persist.setItem("lobbies",lobbies); + },10*1000); +} + + +Persist.initSync({}); +users=Persist.getItemSync("users"); +if(!users){ + users=[]; +} +lobbies=Persist.getItemSync("lobbies"); +if(!lobbies){ + lobbies=[]; + ["lobby_1","lobby_2"].forEach(lobby_create); +} else { + lobbies=lobbies.forEach(function(l){ + l.history=new CircularBuffer(l.history); + }); +} + new WebSocketServer({port:WSPORT}).on("connection",function(ws){ var uobj; @@ -40,21 +70,13 @@ new WebSocketServer({port:WSPORT}).on("connection",function(ws){ return; } ws.send("#lobby "+which); - if(uobj.lob!=null){ - oldlobidx=flob(uobj.lob); - lobbies[oldlobidx].users.splice(lobfuser(lobbies[oldlobidx],uobj.id),1); - lobbysend(lobbies[oldlobidx],"#part "+uobj.nick); - lobbies[oldlobidx].history.push(["part",uobj.nick]); - } - uobj.lob=which; - lobbies[lobidx].users.push(uobj.id); - lobbysend(lobbies[lobidx],"#join "+uobj.nick); - lobbies[lobidx].history.push(["join",uobj.nick]); - uobj.ws.send("#historystart"); - lobbies[lobidx].history.toarray().forEach(function(h){ - uobj.ws.send("#history "+h.join(" ")); - }); - uobj.ws.send("#historyend"); + if(uobj.lob!=null)leave_lobby(uobj); + join_lobby(lobidx,uobj); + send_history(lobidx,uobj); + do_persist_lobbies(); + } else if(msg.match(/^#mylobby/)){ + if(uobj.lob==null)ws.send("#mylobby"); + else ws.send("#mylobby "+uobj.lob); } else if(msg.match(/^#nick /)){ var choice=msg.slice(6).replace(/[\x00-\x20\x7F\x80-\xFF]/g,""); //all shitty characters including space (' ') var i; @@ -71,6 +93,8 @@ new WebSocketServer({port:WSPORT}).on("connection",function(ws){ lobbysend(lobbies[flob(uobj.lob)],"#nick "+uobj.nick+" "+choice); } uobj.nick=choice; + do_persist_users(); + do_persist_lobbies(); } else if(msg.match(/^#lobbylist/)){ ws.send("#lobbylist "+lobbies.map(function(lob){return lob.id+":"+lob.name;}).join(" ")); } else if(msg.match(/^#nicklist/)){ @@ -90,6 +114,7 @@ new WebSocketServer({port:WSPORT}).on("connection",function(ws){ lobidx=flob(uobj.lob); lobbysend(lobbies[lobidx],"<"+uobj.nick+" "+msg.slice(1)); lobbies[lobidx].history.push([">",uobj.nick,msg.slice(1)]); + do_persist_lobbies(); } else { ws.send("#error Invalid message starting with \""+msg.slice(0,10)+"\""); return; @@ -104,6 +129,8 @@ new WebSocketServer({port:WSPORT}).on("connection",function(ws){ lobbies[lobidx].users.splice(lobfuser(lobbies[lobidx],uobj.id),1); } users.splice(fuser(uobj.id),1); + do_persist_users(); + do_persist_lobbies(); }); }); console.log("Websocket server started on port "+WSPORT+"."); @@ -146,6 +173,27 @@ function flob(lobid){ return -1; } +function join_lobby(lobidx,uobj){ + var lobid=lobbies[lobidx].id; + uobj.lob=lobid; + lobbies[lobidx].users.push(uobj.id); + lobbysend(lobbies[lobidx],"#join "+uobj.nick); + lobbies[lobidx].history.push(["join",uobj.nick]); +} +function send_history(lobidx,uobj){ + uobj.ws.send("#historystart"); + lobbies[lobidx].history.toarray().forEach(function(h){ + uobj.ws.send("#history "+h.join(" ")); + }); + uobj.ws.send("#historyend"); +} +function leave_lobby(uobj){ + var lobidx=flob(uobj.lob); + lobbies[lobidx].users.splice(lobfuser(lobbies[lobidx],uobj.id),1); + lobbysend(lobbies[lobidx],"#part "+uobj.nick); + lobbies[lobidx].history.push(["part",uobj.nick]); +} + ////////// HTTP ////////// diff --git a/package.json b/package.json new file mode 100644 index 0000000..d359a03 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "chatserver", + "version": "0.0.1", + "description": "A simple NodeJS chat server", + "main": "chatserver.js", + "dependencies": { + "circular-buffer": "0.0.6", + "node-persist": "0.0.3", + "ws": "^0.6.5" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/tomsmeding/chatserver.git" + }, + "keywords": [ + "chat", + "server", + "simple" + ], + "author": "Tom Smeding (http://tomsmeding.com)", + "license": "ISC", + "bugs": { + "url": "https://github.com/tomsmeding/chatserver/issues" + }, + "homepage": "https://github.com/tomsmeding/chatserver" +} -- cgit v1.2.3-70-g09d2