thor.io ( working title )
thor.io ( working title ) - a tiny experimental realtime framework for nodeJS. Influenced by XSockets.NET. The purpose of the project is to experiment with the concepts of the brilliant XSockets.NET framework in general in a node.js environment. I strongly recommend you all to have a closer look at XSockets.NET on (http://xsockets.net).
Introduction
See https://github.com/MagnusThor/thorio/wiki for more info
Depencencies
package.json
"dependencies": {
"express": "^4.13.4",
"express-ws": "^1.0.0"
}
Serve using express & express-ws (node.js)
Set up a ThorIO.Engine
server.js
var express = require("express"); app = express();
var ThorIO = require("./thor-io.js").ThorIO;
var myControllers = require("./Controllers/Controllers.js").MyControllers
var thorIO = new ThorIO.Engine([{ alias: "foo", instance: myControllers.FooController }]);
var expressWs = require("express-ws")(app);
app.use('/test', express.static('test'));
app.ws("/", function (ws, req) {
thorIO.addConnection(ws);
});
app.listen(process.env.port || 1337);
Controllers.js
A simple ThorIO.Controller
var MyControllers = {};
MyControllers.FooController = (function () {
var fooController = function (client) {
this.alias = "foo"; // mandatory member
this.client = client; // mandatory member
this.age = 1;
}
// optional memmber
fooController.prototype.onclose = function (timestamp) {
this.invoke({ message: "onclose fired on foo", created: timestamp.toString(), age: this.age }, "say", this.alias);
},
// optional member
fooController.prototype.onopen = function (timestamp) {
this.invoke({ message: "onopen fired on foo", created: timestamp.toString(), age: this.age }, "say", this.alias);
},
// send a message to all clients connected to foo
fooController.prototype.all = function (data, controller, topic) {
this.invokeToAll({ message: data.message, created: data.created, age: this.age }, "say", this.alias);
};
// send a message to callee
fooController.prototype.say = function (data, controller, topic) {
this.invoke({ message: data.message, created: data.created, age: this.age }, "say", this.alias);
};
// send to all clients with an .age greater or equal to 10
fooController.prototype.sayTo = function (data, controller, topic) {
var expression = function (pre) {
return pre.foo.age >= 10;
};
this.invokeTo(expression,
{ message: data.message, created: data.created, age: this.age }, "say", this.alias);
this.publishToAll({ a:1 }, "bar", this.alias);
};
return fooController;
})();
// exports
exports.MyControllers = MyControllers;
Connect and use using the ThorIO.Client JavaScript API
Make sure you got this file referenced
https://github.com/MagnusThor/thorio/blob/master/src/client/thorio.client.latest.js
client.js
Create a connection to an endpoint and a controller (controller.js above) using the ThorIOClient.Factory
& ThorIO.Channel
, send, recieve and more....
var doc = document;
var client;
var addMessage = function(message) {
var li = doc.createElement("li");
var mark = doc.createElement("mark");
mark.textContent = message.created;
var span = doc.createElement("span");
span.textContent = message.message;
li.appendChild(mark);
li.appendChild(span);
doc.querySelector("#messages").appendChild(li);
};
doc.addEventListener("DOMContentLoaded", function() {
client = new ThorIOClient.Factory("ws://localhost:1337", ["foo"]);
client.onopen = function(foo) {
doc.querySelector("#close").addEventListener("click", function() {
foo.close();
});
addMessage({
message: "Connected to endpoint...",
created: new Date()
});
foo.connect();
foo.onclose = function(message) {
addMessage({
message: "Disconnected to fooController",
created: new Date()
});
};
foo.onopen = function(message) {
addMessage({
message: "Connected to fooController",
created: new Date()
});
addMessage({
message: "adding a subscription to 'bar'.",
created: new Date()
});
foo.subscribe("bar", function() {
addMessage({
message: "got a message on bar...",
created: new Date()
});
});
foo.setProperty("age", 11);
addMessage({
message: "Setting .age to 11 using setProperty ( see code ) ",
created: new Date()
});
};
doc.querySelector("#unsubscribe").addEventListener("click", function() {
foo.unsubscribe("bar");
addMessage({
message: "removing subscription to 'bar'.",
created: new Date()
});
});
doc.querySelector("#age").addEventListener("input", function() {
if (!Number.isInteger(parseInt(this.value))) return;
foo.setProperty("age", parseInt(this.value));
});
doc.querySelector("#message").addEventListener("keydown", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
foo.invoke("sayTo", {
message: this.value,
created: new Date()
});
this.value = "";
};
});
foo.on("say", function(message) {
addMessage(message);
});
};
});
index.html
<h1>Example</h1>
<hr />
<div>
<input type="text" id="message" placeholder="Say something..."
/>
<input type="number" id="age" min="1" max="99"
value="11" /> * if age ( number field )
is less than 10 message will be filtered
away, as the server controller just sends
to clients where age >= 10 ..
</div>
<ul id="messages"></ul>
<button id="close">Close connection to 'foo'</button>
<button id="unsubscribe">Unsubscribe topic 'bar'</button>
Example
There is a running example on http://thorio.azurewebsites.net/test , you will find the code (client) in the test folder of the repo
Documentation
There is a first version of the dox available here - https://github.com/MagnusThor/thorio/wiki