Skip to content

Instantly share code, notes, and snippets.

@tylertreat-wf
Created September 20, 2014 00:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tylertreat-wf/462a8dbe803f4804cbda to your computer and use it in GitHub Desktop.
Save tylertreat-wf/462a8dbe803f4804cbda to your computer and use it in GitHub Desktop.
vessel.js
{
"name": "w-message-client",
"version": "0.0.1",
"dependencies": {
"sockjs-client": "~0.3.4",
"requirejs": "~2.1.15"
}
}
require.config({
paths: {
sockjs: 'http://cdn.sockjs.org/sockjs-0.3.2.min'
}
});
require([
'vessel',
], function(Vessel) {
'use strict';
var vessel = new Vessel('http://localhost:8081/vessel', {debug: true});
var input = document.getElementById("input");
var send = document.getElementById("submit");
send.onclick = function() {
if (input.value == 'test') {
vessel.send('foo', input.value, function(channel, message) {
console.log(channel + ': ' + message);
});
} else {
vessel.send('foo', input.value);
}
};
vessel.addChannelCallback("baz", function(message) {
alert(message);
});
});
<html>
<head>
<script data-main="main" src="../bower_components/requirejs/require.js"></script>
</head>
<body>
<h1>Test</h1>
<input id="input" type="text" />
<button id="submit">Send</button>
</body>
</html>
define([
'sockjs',
], function(SockJS) {
'use strict';
// Create a new Vessel client for sending and receiving messages.
function Vessel(host, options) {
if (!(this instanceof Vessel)) {
// Make `new` optional.
return new Vessel(host, options);
}
var self = this;
options = options || {};
this._debug = 'debug' in options ? options.debug : false;
this._host = host;
this._msgCallbacks = {};
this._chanCallbacks = {};
this._transport = new SockJS(host);
this._transport.onmessage = function(e) {
self._log('Recv: ' + e.data);
var payload = JSON.parse(e.data);
if (self._recvCallback) {
self._recvCallback(payload.channel, payload.body);
}
if (payload.id in self._msgCallbacks) {
self._msgCallbacks[payload.id](payload.channel, payload.body);
delete self._msgCallbacks[payload.id];
}
if (payload.channel in self._chanCallbacks) {
self._chanCallbacks[payload.channel](payload.body);
}
};
}
// Log the message if debug is enabled.
Vessel.prototype._log = function(msg) {
if (this._debug) {
console.log(msg);
}
};
// Return the next unique message identifier.
Vessel.prototype._nextId = function() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + s4() + s4() + s4() + s4() + s4() + s4();
};
// Send a message on the given channel. If a callback is provided, it will
// be invoked when a response is received. If the channel has a callback
// registered, both callbacks will be invoked. Message callbacks are only
// invoked the first time a message response is received.
Vessel.prototype.send = function(channel, msg, callback) {
var id = this._nextId();
var payload = JSON.stringify({
id: id,
channel: channel,
body: msg,
});
if (callback) {
this._msgCallbacks[id] = callback;
}
this._log('Send: ' + payload);
this._transport.send(payload);
};
// Set a callback to be invoked on every received message. This will be
// invoked in addition to any channel and message callbacks.
Vessel.prototype.onMessage = function(callback) {
this._recvCallback = callback;
};
// Add a callback to the given channel. This callback will be invoked
// whenever a message is received on the channel. If a response on the
// channel is associated with a sent message which has a callback, both
// callbacks will be invoked.
Vessel.prototype.addChannelCallback = function(channel, callback) {
this._chanCallbacks[channel] = callback;
};
// Remove a channel callback. Has no effect if the channel has no callback.
Vessel.prototype.removeChannelCallback = function(channel) {
delete this._chanCallbacks[channel];
};
return Vessel;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment