| @@ -0,0 +1 @@ | |||
| node_modules | |||
| @@ -0,0 +1,56 @@ | |||
| (function() { | |||
| function SockSugar(url) { | |||
| this._sock = new WebSocket(url); | |||
| this._cbs = {}; | |||
| this._reqs = []; | |||
| this._requestId = 1; | |||
| this._sock.onopen = function() { | |||
| this.emit("ready"); | |||
| }.bind(this); | |||
| this._sock.onmessage = function(evt) { | |||
| var obj = JSON.parse(evt.data); | |||
| if (obj.err) { | |||
| this._reqs[obj.r](obj.err); | |||
| } else if (obj.r) { | |||
| this._reqs[obj.r](null, obj.d); | |||
| } else if (obj.evt) { | |||
| this.emit(obj.evt, obj.d); | |||
| } else { | |||
| throw new Error("Invalid message."); | |||
| } | |||
| delete this._reqs[obj.r]; | |||
| }.bind(this); | |||
| } | |||
| SockSugar.prototype.send = function(name, data, cb) { | |||
| this._reqs[this._requestId] = cb; | |||
| this._sock.send(JSON.stringify({ | |||
| r: this._requestId++, | |||
| d: data, | |||
| n: name | |||
| })); | |||
| } | |||
| SockSugar.prototype.on = function(name, func) { | |||
| if (this._cbs[name] === undefined) | |||
| this._cbs[name] = []; | |||
| this._cbs[name].push(func); | |||
| } | |||
| SockSugar.prototype.emit = function(name, data) { | |||
| if (this._cbs[name] === undefined) | |||
| return; | |||
| this._cbs[name].forEach(function(cb) { | |||
| cb(data); | |||
| }); | |||
| } | |||
| window.SockSugar = SockSugar; | |||
| })(); | |||
| @@ -0,0 +1,39 @@ | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <head> | |||
| <title>SockSugar</title> | |||
| </head> | |||
| <body> | |||
| <input type="text" id="url" value="ws://localhost:8081"> | |||
| <button id="connect">Connect</button> | |||
| <div id="message"></div> | |||
| <script src="../client.js"></script> | |||
| <script> | |||
| document.getElementById("connect").addEventListener("click", function() { | |||
| var url = document.getElementById("url").value; | |||
| //Create a new SockSugar socket | |||
| window.sock = new SockSugar(url); | |||
| window.sock.on("ready", function() { | |||
| document.getElementById("message").innerHTML = | |||
| "Connected! You can now play with the global "+ | |||
| "'sock' object in a JavaScript console. "+ | |||
| "Try doing <code>sock.send('myMsg', ...)</code>, "+ | |||
| "or typing <code>send</code> in the server's console."; | |||
| //Listen to 'myEvent', which the server emits when you | |||
| //type 'say' in its console | |||
| sock.on("myEvent", function(data) { | |||
| console.log("Received myEvent from server!"); | |||
| console.log(data); | |||
| }); | |||
| }); | |||
| }); | |||
| </script> | |||
| </body> | |||
| </html> | |||
| @@ -0,0 +1,35 @@ | |||
| var SockSugar = require(".."); | |||
| var server = new SockSugar({ | |||
| port: 8081 | |||
| }); | |||
| server.on("connection", function(sock) { | |||
| console.log("connection!"); | |||
| sock.on("myMsg", function(req) { | |||
| console.log(req.data); | |||
| req.reply({ | |||
| foo: "bar" | |||
| }); | |||
| }); | |||
| }); | |||
| process.stdin.on("data", function(data) { | |||
| str = data.toString("utf8"); | |||
| if (str.split(/\s+/)[0] == "send") { | |||
| console.log("Sending myEvent to all connections."); | |||
| server.socks.forEach(function(sock) { | |||
| sock.send("myEvent", { | |||
| msg: str.replace(/^\w+\s+/, "") | |||
| }); | |||
| }); | |||
| } else { | |||
| console.log("Unknown command."); | |||
| } | |||
| }); | |||
| console.log("Running SockSugar on port 8081."); | |||
| @@ -0,0 +1,86 @@ | |||
| var WSServer = require("ws").Server; | |||
| var events = require("events"); | |||
| var util = require("util"); | |||
| //Request { | |||
| function Request(sock, data, requestId) { | |||
| this.data = data; | |||
| this._sock = sock; | |||
| this._requestId = requestId; | |||
| this._replied = false; | |||
| } | |||
| Request.prototype.reply = function(data) { | |||
| if (this._replied) | |||
| throw new Error("Already replied."); | |||
| this._sock._send({ | |||
| r: this._requestId, | |||
| d: data | |||
| }); | |||
| this._replied = true; | |||
| } | |||
| Request.prototype.error = function(msg) { | |||
| if (this._replied) | |||
| throw new Error("Already replied."); | |||
| this._sock._send({ | |||
| r: this._requestId, | |||
| err: msg | |||
| }); | |||
| this._replied = true; | |||
| } | |||
| //} | |||
| //Socket { | |||
| function Socket(websock) { | |||
| this._websock = websock; | |||
| websock.on("message", function(msg) { | |||
| var obj; | |||
| try { | |||
| obj = JSON.parse(msg); | |||
| } catch (err) { | |||
| this.emit("error", err); | |||
| } | |||
| var req = new Request(this, obj.d, obj.r); | |||
| this.emit(obj.n, req); | |||
| }.bind(this)); | |||
| } | |||
| util.inherits(Socket, events.EventEmitter); | |||
| //Generic internal send function | |||
| Socket.prototype._send = function(data) { | |||
| this._websock.send(JSON.stringify(data)); | |||
| } | |||
| //Trigger event on the client | |||
| Socket.prototype.send = function(name, data) { | |||
| this._send({ | |||
| evt: name, | |||
| d: data | |||
| }); | |||
| } | |||
| //} | |||
| //module.exports { | |||
| module.exports = function(options) { | |||
| var wss = new WSServer(options); | |||
| this.socks = []; | |||
| wss.on("connection", function(websock) { | |||
| var sock = new Socket(websock); | |||
| this.socks.push(sock); | |||
| this.emit("connection", sock); | |||
| }.bind(this)); | |||
| } | |||
| util.inherits(module.exports, events.EventEmitter); | |||
| //} | |||
| @@ -0,0 +1,14 @@ | |||
| { | |||
| "name": "socksugar", | |||
| "version": "0.1.0", | |||
| "description": "Websockets with sugar on top.", | |||
| "main": "index.js", | |||
| "scripts": { | |||
| "test": "echo \"Error: no test specified\" && exit 1" | |||
| }, | |||
| "author": "Martin Dørum Nygaard", | |||
| "license": "MIT", | |||
| "dependencies": { | |||
| "ws": "^0.7.2" | |||
| } | |||
| } | |||