Create websockets module
This commit is contained in:
parent
4f6d8d12e0
commit
d4a4f1bd7f
4 changed files with 193 additions and 96 deletions
|
@ -23,6 +23,7 @@
|
|||
<script type="text/javascript" src="js/weechat.js"></script>
|
||||
<script type="text/javascript" src="js/irc-utils.js"></script>
|
||||
<script type="text/javascript" src="js/glowingbear.js"></script>
|
||||
<script type="text/javascript" src="js/websockets.js"></script>
|
||||
<script type="text/javascript" src="js/models.js"></script>
|
||||
<script type="text/javascript" src="js/plugins.js"></script>
|
||||
<script type="text/javascript" src="3rdparty/bindonce.min.js"></script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var weechat = angular.module('weechat', ['ngRoute', 'localStorage', 'weechatModels', 'plugins', 'ngSanitize', 'pasvaz.bindonce']);
|
||||
var weechat = angular.module('weechat', ['ngRoute', 'localStorage', 'weechatModels', 'plugins', 'ngSanitize', 'ngWebsockets', 'pasvaz.bindonce']);
|
||||
|
||||
weechat.filter('toArray', function () {
|
||||
'use strict';
|
||||
|
@ -176,6 +176,14 @@ weechat.factory('handlers', ['$rootScope', 'models', 'plugins', function($rootSc
|
|||
_nicklist_diff: handleNicklistDiff
|
||||
};
|
||||
|
||||
$rootScope.$on('onMessage', function(event, message) {
|
||||
|
||||
if (_.has(eventHandlers, message.id)) {
|
||||
|
||||
eventHandlers[message.id](message);
|
||||
}
|
||||
});
|
||||
|
||||
var handleEvent = function(event) {
|
||||
if (_.has(eventHandlers, event.id)) {
|
||||
eventHandlers[event.id](event);
|
||||
|
@ -191,101 +199,25 @@ weechat.factory('handlers', ['$rootScope', 'models', 'plugins', function($rootSc
|
|||
|
||||
}]);
|
||||
|
||||
weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers', 'models', function($q, $rootScope, $log, storage, handlers, models) {
|
||||
weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers', 'models', 'conn', function($q, $rootScope, $log, storage, handlers, models, conn) {
|
||||
protocol = new weeChat.Protocol();
|
||||
var websocket = null;
|
||||
|
||||
var callbacks = {};
|
||||
var currentCallBackId = 0;
|
||||
|
||||
/*
|
||||
* Returns the current callback id
|
||||
*/
|
||||
var getCurrentCallBackId = function() {
|
||||
|
||||
currentCallBackId += 1;
|
||||
|
||||
if (currentCallBackId > 1000) {
|
||||
currentCallBackId = 0;
|
||||
}
|
||||
|
||||
return currentCallBackId;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a callback, adds it to the callback list
|
||||
* and return it.
|
||||
*/
|
||||
var createCallback = function() {
|
||||
var defer = $q.defer();
|
||||
var cbId = getCurrentCallBackId();
|
||||
|
||||
callbacks[cbId] = {
|
||||
time: new Date(),
|
||||
cb: defer
|
||||
};
|
||||
|
||||
defer.id = cbId;
|
||||
|
||||
return defer;
|
||||
};
|
||||
|
||||
/*
|
||||
* Fails every currently subscribed callback for the
|
||||
* given reason
|
||||
*
|
||||
* @param reason reason for failure
|
||||
*/
|
||||
failCallbacks = function(reason) {
|
||||
for (var i in callbacks) {
|
||||
callbacks[i].cb.reject(reason);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* Send a message to the websocket and returns a promise.
|
||||
* See: http://docs.angularjs.org/api/ng.$q
|
||||
*
|
||||
* @param message message to send
|
||||
* @returns a promise
|
||||
*/
|
||||
var send = function(message) {
|
||||
message.replace(/[\r\n]+$/g, "").split("\n");
|
||||
var cb = createCallback(message);
|
||||
websocket.send("(" + cb.id + ") " + message);
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/*
|
||||
* Send all messages to the websocket and returns a promise that is resolved
|
||||
* when all message are resolved.
|
||||
*
|
||||
* @param messages list of messages
|
||||
* @returns a promise
|
||||
*/
|
||||
var sendAll = function(messages) {
|
||||
var promises = [];
|
||||
for (var i in messages) {
|
||||
var promise = send(messages[i]);
|
||||
promises.push(promise);
|
||||
}
|
||||
return $q.all(promises);
|
||||
};
|
||||
|
||||
// Takes care of the connection and websocket hooks
|
||||
var connect = function (host, port, passwd, ssl, noCompression) {
|
||||
var proto = ssl ? 'wss' : 'ws';
|
||||
websocket = new WebSocket(proto + "://" + host + ':' + port + "/weechat");
|
||||
websocket.binaryType = "arraybuffer";
|
||||
var url = proto + "://" + host + ":" + port + "/weechat";
|
||||
var binaryType = "arraybuffer";
|
||||
|
||||
websocket.onopen = function () {
|
||||
var onopen = function () {
|
||||
|
||||
$log.info("Connected to relay");
|
||||
|
||||
// First command asks for the password and issues
|
||||
// a version command. If it fails, it means the we
|
||||
// did not provide the proper password.
|
||||
sendAll([
|
||||
conn.sendAll([
|
||||
weeChat.Protocol.formatInit({
|
||||
password: passwd,
|
||||
compression: noCompression ? 'off' : 'zlib'
|
||||
|
@ -301,7 +233,7 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers',
|
|||
}
|
||||
);
|
||||
|
||||
send(
|
||||
conn.send(
|
||||
weeChat.Protocol.formatHdata({
|
||||
path: 'buffer:gui_buffers(*)',
|
||||
keys: ['local_variables,notify,number,full_name,short_name,title']
|
||||
|
@ -321,7 +253,7 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers',
|
|||
|
||||
|
||||
// Send all the other commands required for initialization
|
||||
send(
|
||||
conn.send(
|
||||
weeChat.Protocol.formatHdata({
|
||||
path: "buffer:gui_buffers(*)/own_lines/last_line(-"+storage.get('lines')+")/data",
|
||||
keys: []
|
||||
|
@ -330,7 +262,7 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers',
|
|||
handlers.handleLineInfo(lineinfo);
|
||||
});
|
||||
|
||||
send(
|
||||
conn.send(
|
||||
weeChat.Protocol.formatHdata({
|
||||
path: "hotlist:gui_hotlist(*)",
|
||||
keys: []
|
||||
|
@ -340,14 +272,14 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers',
|
|||
});
|
||||
|
||||
|
||||
send(
|
||||
conn.send(
|
||||
weeChat.Protocol.formatNicklist({
|
||||
})
|
||||
).then(function(nicklist) {
|
||||
handlers.handleNicklist(nicklist);
|
||||
});
|
||||
|
||||
send(
|
||||
conn.send(
|
||||
weeChat.Protocol.formatSync({})
|
||||
);
|
||||
|
||||
|
@ -355,14 +287,16 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers',
|
|||
|
||||
};
|
||||
|
||||
websocket.onclose = function () {
|
||||
|
||||
|
||||
var onclose = function () {
|
||||
$log.info("Disconnected from relay");
|
||||
$rootScope.connected = false;
|
||||
failCallbacks('disconnection');
|
||||
$rootScope.$apply();
|
||||
};
|
||||
|
||||
websocket.onmessage = function (evt) {
|
||||
var onmessage = function (evt) {
|
||||
message = protocol.parse(evt.data);
|
||||
if (_.has(callbacks, message.id)) {
|
||||
var promise = callbacks[message.id];
|
||||
|
@ -375,23 +309,36 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers',
|
|||
$rootScope.$apply();
|
||||
};
|
||||
|
||||
websocket.onerror = function (evt) {
|
||||
var onerror = function (evt) {
|
||||
// on error it means the connection problem
|
||||
// come from the relay not from the password.
|
||||
|
||||
if (evt.type === "error" && websocket.readyState !== 1) {
|
||||
if (evt.type === "error" && this.readyState !== 1) {
|
||||
failCallbacks('error');
|
||||
$rootScope.errorMessage = true;
|
||||
}
|
||||
$log.error("Relay error " + evt.data);
|
||||
};
|
||||
|
||||
this.websocket = websocket;
|
||||
protocol.setId = function(id, message) {
|
||||
return '(' + id + ') ' + message;
|
||||
}
|
||||
|
||||
conn.connect(url,
|
||||
protocol,
|
||||
{
|
||||
'binaryType': "arraybuffer",
|
||||
'onopen': onopen,
|
||||
'onclose': onclose,
|
||||
'onmessage': onmessage,
|
||||
'onerror': onerror,
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
var disconnect = function() {
|
||||
/* TODO: Send protocol disconnect */
|
||||
this.websocket.close();
|
||||
conn.disconnect();
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -400,14 +347,14 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers',
|
|||
* @returns the angular promise
|
||||
*/
|
||||
var sendMessage = function(message) {
|
||||
return send(weeChat.Protocol.formatInput({
|
||||
conn.send(weeChat.Protocol.formatInput({
|
||||
buffer: models.getActiveBuffer().fullName,
|
||||
data: message
|
||||
}));
|
||||
};
|
||||
|
||||
var sendCoreCommand = function(command) {
|
||||
send(weeChat.Protocol.formatInput({
|
||||
conn.send(weeChat.Protocol.formatInput({
|
||||
buffer: 'core.weechat',
|
||||
data: command
|
||||
}));
|
||||
|
@ -415,7 +362,7 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers',
|
|||
|
||||
|
||||
return {
|
||||
send: send,
|
||||
// send: send,
|
||||
connect: connect,
|
||||
disconnect: disconnect,
|
||||
sendMessage: sendMessage,
|
||||
|
|
137
js/websockets.js
Normal file
137
js/websockets.js
Normal file
|
@ -0,0 +1,137 @@
|
|||
var websockets = angular.module('ngWebsockets', []);
|
||||
|
||||
websockets.factory('conn',
|
||||
['$rootScope','$q',
|
||||
function($rootScope, $q) {
|
||||
|
||||
|
||||
var ws = null;
|
||||
this.protocol = null;
|
||||
var callbacks = {};
|
||||
var currentCallBackId = 0;
|
||||
|
||||
/*
|
||||
* Fails every currently subscribed callback for the
|
||||
* given reason
|
||||
*
|
||||
* @param reason reason for failure
|
||||
*/
|
||||
failCallbacks = function(reason) {
|
||||
for (var i in callbacks) {
|
||||
callbacks[i].cb.reject(reason);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns the current callback id
|
||||
*/
|
||||
var getCurrentCallBackId = function() {
|
||||
|
||||
currentCallBackId += 1;
|
||||
|
||||
if (currentCallBackId > 1000) {
|
||||
currentCallBackId = 0;
|
||||
}
|
||||
|
||||
return currentCallBackId;
|
||||
};
|
||||
|
||||
|
||||
/* Send a message to the websocket and returns a promise.
|
||||
* See: http://docs.angularjs.org/api/ng.$q
|
||||
*
|
||||
* @param message message to send
|
||||
* @returns a promise
|
||||
*/
|
||||
var send = function(message) {
|
||||
|
||||
var cb = createCallback(message);
|
||||
|
||||
message = protocol.setId(cb.id,
|
||||
message);
|
||||
|
||||
ws.send(message);
|
||||
return cb.promise;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a callback, adds it to the callback list
|
||||
* and return it.
|
||||
*/
|
||||
var createCallback = function() {
|
||||
var defer = $q.defer();
|
||||
var cbId = getCurrentCallBackId();
|
||||
|
||||
callbacks[cbId] = {
|
||||
time: new Date(),
|
||||
cb: defer
|
||||
};
|
||||
|
||||
defer.id = cbId;
|
||||
|
||||
return defer;
|
||||
};
|
||||
|
||||
/*
|
||||
* Send all messages to the websocket and returns a promise that is resolved
|
||||
* when all message are resolved.
|
||||
*
|
||||
* @param messages list of messages
|
||||
* @returns a promise
|
||||
*/
|
||||
var sendAll = function(messages) {
|
||||
var promises = [];
|
||||
for (var i in messages) {
|
||||
var promise = send(messages[i]);
|
||||
promises.push(promise);
|
||||
}
|
||||
return $q.all(promises);
|
||||
};
|
||||
|
||||
|
||||
var onmessage = function (evt) {
|
||||
/*
|
||||
* Receives a message on the websocket
|
||||
*/
|
||||
var message = protocol.parse(evt.data)
|
||||
if (_.has(callbacks, message.id)) {
|
||||
// see if it's bound to one of the callbacks
|
||||
var promise = callbacks[message.id];
|
||||
promise.cb.resolve(message)
|
||||
delete(callbacks[message.id]);
|
||||
} else {
|
||||
// otherwise emit it
|
||||
$rootScope.$emit('onMessage', message)
|
||||
//handlers.handleEvent(message);
|
||||
}
|
||||
$rootScope.commands.push("RECV: " + evt.data + " TYPE:" + evt.type);
|
||||
$rootScope.$apply();
|
||||
|
||||
}
|
||||
|
||||
var connect = function(url,
|
||||
protocol,
|
||||
properties) {
|
||||
|
||||
ws = new WebSocket(url);
|
||||
protocol = protocol;
|
||||
for (var property in properties) {
|
||||
ws[property] = properties[property];
|
||||
}
|
||||
|
||||
ws.onmessage = onmessage;
|
||||
}
|
||||
|
||||
var disconnect = function() {
|
||||
ws.close();
|
||||
}
|
||||
|
||||
return {
|
||||
send: send,
|
||||
sendAll: sendAll,
|
||||
connect: connect,
|
||||
disconnect: disconnect
|
||||
}
|
||||
}]);
|
|
@ -596,6 +596,16 @@
|
|||
return defaults;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the ID to the previously formatted command
|
||||
*
|
||||
* @param id Command ID
|
||||
* @param command previously formatted command
|
||||
*/
|
||||
WeeChatProtocol.setId = function(id, command) {
|
||||
return '(' + id + ') ' + command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a command.
|
||||
*
|
||||
|
@ -614,6 +624,8 @@
|
|||
cmd = parts.join(' ');
|
||||
cmd += '\n';
|
||||
|
||||
cmd.replace(/[\r\n]+$/g, "").split("\n");
|
||||
|
||||
return cmd;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue