UNPKG

landers.angular

Version:

landers.angular

180 lines (157 loc) 7.38 kB
;angular.module('Landers.angular') // 建立web socket连接,对象存在rootScope下,方便全局调用 // 监听web socket发来的消息,由rootScope进行广播 .provider('GWebSocket', function(){ var provider = this; this.connections = null; this.showLog = false; this.onOpen = null; // 初始化超时时间 var initialTimeout = 1500; // 设置是否断开自动重连 var reconnectIfNotNormalClose = true; // 所有的连接 var connections = {}; // var is_api_result = function(rspn) { // if ( !angular.isObject(rspn)) return false; // return 'success' in rspn && // 'message' in rspn && // 'status_code' in rspn && // 'response_code' in rspn && // ('data' in rspn || 'errors' in rspn); // }; this.$get = ['$rootScope','$websocket', function($rootScope, $websocket) { if (!provider.connections) { return; }; var build_event = function(connection, cmd){ return [connection, cmd].join(':'); }; var initWs = function(connection, ws_url){ var ws = $websocket(ws_url); // 设置断开自动重连 ws.reconnectIfNotNormalClose = reconnectIfNotNormalClose; // 设置初始化连接超时时间 ws.initialTimeout = initialTimeout; // 设置创建连接时的回调函数,发送认证信息到服务器 ws.onOpen(function () { provider.onOpen && provider.onOpen(); }); // 设置回调函数,收到消息后向全局广播 ws.onMessage(function (msg) { if (msg && msg.data) { var result = angular.fromJson(msg.data); var handler = result.cmd || result.handler; var data = result.data; var event = build_event(connection, handler); show_log('receive message:', event, data); // 广播至各个scope $rootScope.$broadcast(event, data); } }); ws.onClose(function() { show_log('websocket ' + connection + ' is closed', '', ''); }); return ws; }; var watcher = { key: '$WebsocketListers', init: function(scope, connection){ if (!scope.hasOwnProperty(this.key)) { scope[this.key] = {}; } if (!scope[this.key][connection]) { scope[this.key][connection] = {}; } }, get: function(scope, connection, cmd) { this.init(scope, connection); return scope[this.key][connection][cmd]; }, add: function(scope, connection, cmd, on_result) { this.init(scope, connection); scope[this.key][connection][cmd] = on_result; }, remove: function(scope, connection, cmd) { this.init(scope, connection); delete scope[this.key][connection][cmd]; } }; var send = function(connection, scope, cmd_handler, data, lisener){ //cmd:命令格式统一为类名_方法名,例如user_login //handler:命令格式统一为类名_方法名,例如user_login //data:json对象包 var pack = { cmd: cmd_handler, data: data, handler: cmd_handler }; if ( lisener && !watcher.get(scope, connection, cmd_handler)) { var event = build_event(connection, cmd_handler); var ret = scope.$on(event, lisener); watcher.add(scope, connection, cmd_handler, ret); } return connections[connection].ws.send(angular.toJson(pack)); }; var show_log = function(msg, cmd, data) { if (provider.showLog) { console.log(msg, cmd, data); } }; for (var connection in provider.connections) { connections[connection] = connections[connection] || (function(url){ var ws_protocol = window.location.protocol.substring(0,5) == 'https' ? 'wss' : 'ws'; var ws_url = ws_protocol + '://' + url; return { ws: initWs(connection, ws_url), authed: false, onOpen: null }; })(provider.connections[connection]); } return { // 发送请求到服务端 send: function(connection, scope, cmd, data, lisener){ if (!scope) return; if ( connections[connection].authed || true) { send(connection, scope, cmd, data, lisener) .then(function () { show_log('success to send message:', cmd, data); }, function () { // 发送失败的消息会被push到ws对象的sendQueue数组中 show_log('failed to send message:', cmd, data); }); } else { var self = arguments.callee; setTimeout(function(){ self(connection, scope, cmd, data, lisener); }, 500); } }, cancel: function(connection, scope, cmd){ var destroyWatch = watcher.get(scope, connection, cmd); if ( destroyWatch ) { destroyWatch(); watcher.remove(scope, connection, cmd); } }, auth : function(connection, handler, ws_token, callback) { if ('authed' in connections[connection]) { connections[connection].onOpen = function(){ send(connection, $rootScope, handler, {token: ws_token}, function(event, response){ connections[connection].authed = response.success; callback && callback(); }); } } ['user_need_login', 'need_auth'].map(function(item){ var event = build_event(connection, item); $rootScope.$on(event, function(){ connections[connection].onOpen(); }); }); connections[connection].onOpen(); } }; }]; });