websocket protocol support event

master
MaysWind 2016-06-29 00:18:17 +08:00
parent 9d9a9a83c3
commit 6c7adfe235
9 changed files with 205 additions and 40 deletions

View File

@ -100,7 +100,9 @@
"Your browser does not support loading file!": "您的浏览器不支持加载文件!",
"The selected file type is invalid!": "选择的文件类型无效!",
"Failed to load file!": "加载文件失败!",
"More Options": "更多选项",
"Download Completed": "下载完成",
"BT Download Completed": "BT 下载完成",
"Download Error": "下载出错",
"Language": "语言",
"Page Title": "页面标题",
"Page Title Refresh Interval": "页面标题刷新间隔",

View File

@ -104,7 +104,9 @@
'Your browser does not support loading file!': 'Your browser does not support loading file!',
'The selected file type is invalid': 'The selected file type is invalid',
'Failed to load file!': 'Failed to load file!',
'More Options': 'More Options',
'Download Completed': 'Download Completed',
'BT Download Completed': 'BT Download Completed',
'Download Error': 'Download Error',
'Language': 'Language',
'Page Title': 'Page Title',
'Page Title Refresh Interval': 'Page Title Refresh Interval',

View File

@ -1,7 +1,7 @@
(function () {
'use strict';
angular.module('ariaNg').run(['$rootScope', '$location', '$document', 'SweetAlert', function ($rootScope, $location, $document, SweetAlert) {
angular.module('ariaNg').run(['$rootScope', '$location', '$document', 'SweetAlert', 'ariaNgNotificationService', 'aria2TaskService', function ($rootScope, $location, $document, SweetAlert, ariaNgNotificationService, aria2TaskService) {
var isUrlMatchUrl2 = function (url, url2) {
if (url === url2) {
return true;
@ -142,6 +142,18 @@
}
};
aria2TaskService.onTaskCompleted(function (event) {
ariaNgNotificationService.notifyTaskComplete(event.task);
});
aria2TaskService.onBtTaskCompleted(function (event) {
ariaNgNotificationService.notifyBtTaskComplete(event.task);
});
aria2TaskService.onTaskErrorOccur(function (event) {
ariaNgNotificationService.notifyTaskError(event.task);
});
$rootScope.$on('$locationChangeStart', function (event) {
SweetAlert.close();

View File

@ -33,6 +33,9 @@
context.errorCallback(data.id, data.error);
}
});
},
on: function (eventName, callback) {
//Not implement
}
};
}]);

View File

@ -2,9 +2,16 @@
'use strict';
angular.module('ariaNg').factory('aria2RpcService', ['$q', 'aria2RpcConstants', 'aria2RpcErrors', 'ariaNgCommonService', 'ariaNgSettingService', 'aria2HttpRpcService', 'aria2WebSocketRpcService', function ($q, aria2RpcConstants, aria2RpcErrors, ariaNgCommonService, ariaNgSettingService, aria2HttpRpcService, aria2WebSocketRpcService) {
var protocol = ariaNgSettingService.getProtocol();
var rpcImplementService = ariaNgSettingService.isUseWebSocket() ? aria2WebSocketRpcService : aria2HttpRpcService;
var secret = ariaNgSettingService.getSecret();
var onDownloadStartCallbacks = [];
var onDownloadPauseCallbacks = [];
var onDownloadStopCallbacks = [];
var onDownloadCompleteCallbacks = [];
var onDownloadErrorCallbacks = [];
var onBtDownloadCompleteCallbacks = [];
var checkIsSystemMethod = function (methodName) {
return methodName.indexOf(aria2RpcConstants.rpcSystemServiceName + '.') == 0;
};
@ -13,6 +20,10 @@
return aria2RpcConstants.rpcServiceName + '.' + methodName;
};
var getAria2EventFullName = function (eventName) {
return getAria2MethodFullName(eventName);
};
var invoke = function (context) {
var uniqueId = ariaNgCommonService.generateUniqueId();
@ -30,11 +41,22 @@
errorCallback: context.errorCallback
};
if (protocol == 'ws' || protocol == 'wss') {
return aria2WebSocketRpcService.request(requestContext);
} else {
return aria2HttpRpcService.request(requestContext);
}
return rpcImplementService.request(requestContext);
};
var registerEvent = function (eventName, callbacks) {
var fullEventName = getAria2EventFullName(eventName);
rpcImplementService.on(fullEventName, function (context) {
if (!angular.isArray(callbacks) || callbacks.length < 1) {
return;
}
for (var i = 0; i < callbacks.length; i++) {
var callback = callbacks[i];
callback(context);
}
});
};
var invokeMulti = function (methodFunc, contexts, callback) {
@ -141,6 +163,15 @@
return context;
};
(function () {
registerEvent('onDownloadStart', onDownloadStartCallbacks);
registerEvent('onDownloadPause', onDownloadPauseCallbacks);
registerEvent('onDownloadStop', onDownloadStopCallbacks);
registerEvent('onDownloadComplete', onDownloadCompleteCallbacks);
registerEvent('onDownloadError', onDownloadErrorCallbacks);
registerEvent('onBtDownloadComplete', onBtDownloadCompleteCallbacks);
})();
return {
getBasicTaskParams: function () {
return [
@ -361,6 +392,24 @@
},
listMethods: function (context) {
return invoke(buildRequestContext('system.listMethods', context));
},
onDownloadStart: function (context) {
onDownloadStartCallbacks.push(context.callback);
},
onDownloadPause: function (context) {
onDownloadPauseCallbacks.push(context.callback);
},
onDownloadStop: function (context) {
onDownloadStopCallbacks.push(context.callback);
},
onDownloadComplete: function (context) {
onDownloadCompleteCallbacks.push(context.callback);
},
onDownloadError: function (context) {
onDownloadErrorCallbacks.push(context.callback);
},
onBtDownloadComplete: function (context) {
onBtDownloadCompleteCallbacks.push(context.callback);
}
};
}]);

View File

@ -144,6 +144,24 @@
return combinedPieces;
};
var createEventCallback = function (getTaskStatusFunc, callback, type) {
return function (event) {
var context = {
type: type,
task: null
};
if (event && event.gid) {
getTaskStatusFunc(event.gid, function (response) {
context.task = (response.success ? response.data : null);
callback(context);
}, true);
} else {
callback(context);
}
}
};
var createLocalPeerFromTask = function (task) {
return {
local: true,
@ -385,6 +403,33 @@
callback: callback
});
},
onTaskCompleted: function (callback) {
if (!callback) {
return;
}
aria2RpcService.onDownloadComplete({
callback: createEventCallback(this.getTaskStatus, callback, 'completed')
});
},
onBtTaskCompleted: function (callback) {
if (!callback) {
return;
}
aria2RpcService.onBtDownloadComplete({
callback: createEventCallback(this.getTaskStatus, callback, 'btcompleted')
});
},
onTaskErrorOccur: function (callback) {
if (!callback) {
return;
}
aria2RpcService.onDownloadError({
callback: createEventCallback(this.getTaskStatus, callback, 'error')
});
},
processDownloadTasks: function (tasks) {
if (!angular.isArray(tasks)) {
return;

View File

@ -4,7 +4,60 @@
angular.module('ariaNg').factory('aria2WebSocketRpcService', ['$q', '$websocket', 'ariaNgSettingService', function ($q, $websocket, ariaNgSettingService) {
var rpcUrl = ariaNgSettingService.getJsonRpcUrl();
var socketClient = null;
var sendIdStates = {};
var eventCallbacks = {};
var processMethodCallback = function (content) {
var uniqueId = content.id;
if (!uniqueId) {
return;
}
var state = sendIdStates[uniqueId];
if (!state) {
return;
}
var context = state.context;
state.deferred.resolve({
success: true,
context: context
});
if (content.result && context.successCallback) {
context.successCallback(context.id, content.result);
}
if (content.error && context.errorCallback) {
context.errorCallback(context.id, content.error);
}
delete sendIdStates[uniqueId];
};
var processEventCallback = function (content) {
var method = content.method;
if (!method) {
return;
}
var callbacks = eventCallbacks[method];
if (!angular.isArray(callbacks) || callbacks.length < 1) {
return;
}
for (var i = 0; i < callbacks.length; i++) {
var callback = callbacks[i];
var context = (angular.isArray(content.params) && content.params.length > 0 ? content.params[0] : null);
callback(context);
}
};
var getSocketClient = function () {
if (socketClient == null) {
@ -17,38 +70,15 @@
var content = angular.fromJson(message.data);
if (!content || !content.id) {
if (!content) {
return;
}
var uniqueId = content.id;
if (!sendIdStates[uniqueId]) {
return;
if (content.id) {
processMethodCallback(content);
} else if (content.method) {
processEventCallback(content);
}
var state = sendIdStates[uniqueId];
if (!state) {
return;
}
var context = state.context;
state.deferred.resolve({
success: true,
context: context
});
if (content.result && context.successCallback) {
context.successCallback(context.id, content.result);
}
if (content.error && context.errorCallback) {
context.errorCallback(context.id, content.error);
}
delete sendIdStates[uniqueId];
});
}
@ -75,6 +105,15 @@
client.send(requestBody);
return deferred.promise;
},
on: function (eventName, callback) {
var callbacks = eventCallbacks[eventName];
if (!angular.isArray(callbacks)) {
callbacks = eventCallbacks[eventName] = [];
}
callbacks.push(callback);
}
};
}]);

View File

@ -1,7 +1,7 @@
(function () {
'use strict';
angular.module('ariaNg').factory('ariaNgNotificationService', ['$notification', 'ariaNgSettingService', function ($notification, ariaNgSettingService) {
angular.module('ariaNg').factory('ariaNgNotificationService', ['$notification', '$translate', 'ariaNgSettingService', function ($notification, $translate, ariaNgSettingService) {
var isSupportBrowserNotification = $notification.isSupported;
var isPermissionGranted = function (permission) {
@ -39,10 +39,19 @@
},
notify: function (title, content) {
if (isSupportBrowserNotification && ariaNgSettingService.getBrowserNotification()) {
$notification(title, {
body: content
$notification($translate.instant(title), {
body: $translate.instant(content)
});
}
},
notifyTaskComplete: function (task) {
this.notify('Download Completed', (task && task.taskName ? task.taskName : ''));
},
notifyBtTaskComplete: function (task) {
this.notify('BT Download Completed', (task && task.taskName ? task.taskName : ''));
},
notifyTaskError: function (task) {
this.notify('Download Error', (task && task.taskName ? task.taskName : ''));
}
}
}]);

View File

@ -132,6 +132,10 @@
setProtocol: function (value) {
setOption('protocol', value);
},
isUseWebSocket: function () {
var protocol = this.getProtocol();
return protocol == 'ws' || protocol == 'wss';
},
getSecret: function () {
var value = getOption('secret');
return (value ? base64.decode(value) : value);