Browse Source

initial commit

master
mortie 8 years ago
commit
eb851af98d
5 changed files with 271 additions and 0 deletions
  1. 39
    0
      README.md
  2. 84
    0
      client.js
  3. 77
    0
      index.js
  4. 11
    0
      package.json
  5. 60
    0
      test.js

+ 39
- 0
README.md View File

@@ -0,0 +1,39 @@
# WebEvents

This library provides an easy way to send events to a web browser (or any other
client) over HTTP.

## Usage

See the `test.js` file for an example application.

### Server

```
var http = require("http");
var WebEvents = require("webevnts");

var events = WebEvents();

http.createServer(function(req, res) {
/*
* Whatever else your app does on each request
*/

events.handle(req, res);
});

// Emit whatever events you need
events.emit("someevent", { some: "parameters" });
```

### Client

```
var events = WebEvents();

// Listen to events
events.on("someevent", function(evt) {
// evt -> { some: "parameters" }
});
```

+ 84
- 0
client.js View File

@@ -0,0 +1,84 @@
(function() {
function post(url, cb) {
var xhr = new XMLHttpRequest();

xhr.addEventListener("load", function() {
var obj = JSON.parse(xhr.responseText);

if (obj.error) {
cb(obj.error);
} else {
cb(null, obj);
}
});

xhr.addEventListener("error", function(err) {
cb(err);
});

xhr.open("POST", url);
xhr.send();
}

window.WebEvents = function() {
var self = {};

var cbs = {};
var key = null;

function emit(name, args) {
if (!cbs[name])
return;

cbs[name].forEach(function(cb) {
cb(args);
});
}

function init(time) {
post("/webevents/register", function(err, res) {

// Retry on error
if (err) {
console.error(err);
time = time || 1000;
setTimeout(function() { init(time * 2) }, time);
return;
}

key = res.key;
await();
});
}

function await(time) {
post("/webevents/await/"+key, function(err, res) {

// Retry registering on error
if (err) {
console.error(err);
time = time || 1000;
setTimeout(function() { init(time * 2) }, time);
return;
}

res.forEach(function(evt) {
emit(evt.name, evt.args);
});

await();
});
}

self.on = function(name, cb) {
if (!cbs[name])
cbs[name] = [];

cbs[name].push(cb);
};

init();

return self;
}
})();

+ 77
- 0
index.js View File

@@ -0,0 +1,77 @@
var crypto = require("crypto");

function Listener() {
var self = {}

var key = crypto.randomBytes(16).toString("hex");
self.key = key;

var events = [];
var waiter = null;

function respond() {
waiter.end(JSON.stringify(events));
waiter = null;
events = [];
}

self.emit = function(name, args) {
events.push({ name: name, args: args });

if (waiter != null) {
respond();
}
}

self.handle = function(res) {
waiter = res;

if (events.length > 0) {
respond();
}
}

return self;
}

function WebEvents() {
var self = {}

var listeners = {};

self.emit = function(name, args) {
for (var i in listeners) {
listeners[i].emit(name, args);
}
}

self.handle = function(req, res) {
var parts = req.url.substring(1).split("/");

if (parts[0] !== "webevents")
return;

res.writeHead(200, { "content-type": "application/json" });

if (parts[1] === "register") {
var listener = Listener();
listeners[listener.key] = listener;
res.end(JSON.stringify({ key: listener.key }));

} else if (parts[1] === "await") {
var listener = listeners[parts[2]];
if (!listener) {
res.end(JSON.stringify({
error: "Listener "+parts[2]+" not registered"
}));
return;
}

listener.handle(res);
}
}

return self
}

module.exports = WebEvents;

+ 11
- 0
package.json View File

@@ -0,0 +1,11 @@
{
"name": "webevents",
"version": "1.0.0",
"description": "A simple library for sending events from the server to the client.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Martin Dørum Nygaard <martid0311@gmail.com> (https://www.mort.coffee)",
"license": "ISC"
}

+ 60
- 0
test.js View File

@@ -0,0 +1,60 @@
var http = require("http");
var Eventer = require(".");
var fs = require("fs");

var html =
"<!DOCTYPE html>"+
"<html>"+
"<head>"+
"<title>WebEvents</title>"+
"</head>"+
"<body>"+
"<div "+
"id='thing' "+
"style='position: absolute; width: 30px; height: 30px; background: blue;'></div>"+
"<script src='/client.js'></script>"+
"<script>"+
"var events = WebEvents();"+
"events.on('move', function(evt) {"+
"var elem = document.getElementById('thing');"+
"elem.style.top = evt.y+'px';"+
"elem.style.left = evt.x+'px';"+
"});"+
"</script>"+
"</body>"+
"</html>";

var eventer = Eventer();

http.createServer(function(req, res) {
if (req.url == "/") {
res.end(html);
} else if (req.url == "/client.js") {
fs.createReadStream("client.js")
.pipe(res)
.on("error", err => res.end(err.toString()));
} else if (req.url.indexOf("/webevents") === 0) {
eventer.handle(req, res);
}
}).listen(8080);

// Just keep track of some coordinates to send to the client as events
var x = 0;
var y = 0;
var vx = 30;
var vy = 30;
setInterval(() => {
if (x < 0)
vx = Math.abs(vx);
else if (x > 1000)
vx = -Math.abs(vx);
if (y < 0)
vy = Math.abs(vy);
else if (y > 600)
vy = -Math.abs(vy);

x += vx;
y += vy;

eventer.emit("move", { x: x, y: y });
}, 100);

Loading…
Cancel
Save