天天看點

angularJS socket

項目Controller檔案中加載Service層socket.js.頁面進入該controller所在頁面時連接配接socket(也可一進入項目就連接配接,看需求),細節還需繼續優化,寫下來以防忘了~
           
Service層:socket.js
           
/*************************************************************
******************Angular Websocket Service******************
******************author:ristal******************************
******************created:2014-04-01**************************/
angular.module('websocketService', [])
	.service('sWSocket', ['$timeout', function ($timeout) {
	    var self = this;
	  	var callbackPool = []; //onMessage分類處理函數
	    var delayPool = []; //延遲處理請求
	    var registerPool = [];//已注冊的方法
	    var data = {};
	    var ws = null;
	    var connected = false;

	    function newWebSocket() {
		// var wsURL = "ws://10.188.199.4:8080/YIXUN_1.5_WEB/websocket/";
		    var wsURL = "ws://10.188.192.200:8000/websocket/";
		    var wsTmp = new WebSocket(wsURL);
		    wsTmp.onopen = function (evnt) {
			    onOpen(evnt)
		    };
		    wsTmp.onmessage = function (evnt) {
			    onMessage(evnt)
		    };
		    wsTmp.onclose = function (evnt) {
			    onclose(evnt)
		    };
		    wsTmp.onerror = function (evnt) {
			    onError(evnt)
		    };
		    return wsTmp;
	    }

	    ws = newWebSocket();

	    function onOpen() {
		    ws.readyState = true;
		    updateStatus("onOpen : " + (connected ? 'TTRRUUEE' : 'FFAALLESS'));

		    //緩存池中存在請求
		    while (delayPool.length > 0) {

			    var popData = delayPool.shift();
			    if (popData.isReg == 1) {
				    self.register(popData.appId, popData.methodId, popData.scope, popData.callbackFuns);
			    } else if(popData.isReg == 0){
				    self.unRegister(popData.appId, popData.methodId, popData.scope, popData.callbackFuns);
			    }else {
				    self.send(popData.appId, popData.methodId, popData.content);
			    }
		    }
	    }

	    function onclose() {
		    ws.readyState = false;
		    updateStatus("onClosed : " + (connected ? 'TTRRUUEE' : 'FFAALLESS'));
		    $timeout(function () {
			    console.log('Reconnecting to server...')
			    newWebSocket();
		    }, 3000);
	    }

	    function onMessage(evnt) {
		    //這裡處理接收資料
		    var evenData = JSON.parse(evnt.data);
		    console.log("Received data from websocket: ", evenData);

			//		    //傳回處理
			//		    if(evenData.appId === 'register')
			//		    {
			//			    if(evenData.methodId === 'unRegister'){
			//				    //方法傳回成功,加入方法池
			//				    if(evenData.content.status == 'SUCCEED'){
			//						//registerPool.push({appId: evenData.content.appId, methodId: evenData.content.methodId});
			//					    console.log("registerPool:", registerPool);
			//				    }else{//方法傳回失敗,重新發送請求
			//
			//				    }
			//			    }
			//		    }

			//執行回調函數
			//傳回後端實時推送的資料
		   <span style="color:#ff0000;"> angular.forEach(callbackPool,function(value){
			    if(value.appId === evenData.appId && value.methodId === evenData.methodId){
				    value.callback(evenData.content);
			    }
		    });</span>
	    }

	    function onError(evnt) {
		    ws.readyState = false;
		    console.log('ERROR: ', evnt);
		    $timeout(function () {
			    console.log('Reconnecting to server...')
			    newWebSocket();
		    }, 3000);
	    }

	    function updateStatus(status) {
		    console.log(status);
	    }

	    //注冊方法
	    //注冊成功後會一直監聽後端推送的相應部分的資料
	    //直到登出此方法
	    self.register = function (appId, methodId, callbackFuns) {

		    var webSocketRe = {};
		    webSocketRe.appId = 'register';
		    webSocketRe.methodId = 'register';
		    webSocketRe.content = {
			    appId: appId,
			    methodId: methodId
		    };

		    if (ws.readyState != true){//websocket服務未打開
			    webSocketRe.isReg = 1;//register
			    webSocketRe.appId = appId;
			    webSocketRe.methodId = methodId;
			    webSocketRe.callbackFuns = callbackFuns;
			    delayPool.push(webSocketRe);
			    console.log("register-delayPool:", delayPool);
			    console.log("sending is delay.");
			    return "sending is delay.";
		    } else {
			    callbackPool.push({appId:appId,methodId:methodId,callback:callbackFuns});
			    console.log("callbackPool:",callbackPool);
			    return doSend(webSocketRe);
		    }
	    }

	    //登出方法
	    //通知後端不再推送相應資料
	    self.unregister = function (appId, methodId,callbackFuns) {
		    console.log("unregister");
		    var webSocketRe = {};
		    webSocketRe.appId = 'register';
		    webSocketRe.methodId = 'unRegister';
		    webSocketRe.content = {
			    appId: appId,
			    methodId: methodId
		    };

		    //websocket服務未開啟
		    if (ws.readyState != true){
			    webSocketVo.isReg = 0;//unRegister
			    delayPool.push(webSocketRe);//
			    console.log("unregister is delay.");
			    return "unregister is delay.";
		    } else {
			    console.log("sending unregister.");
		        var num = 0;

		        //循環檢查回調函數池
			    angular.forEach(callbackPool,function(value,key){
				    if(value.appId === appId && value.methodId === methodId){
						num += 1;
					    if(value.callback === callbackFuns){
						    delete callbackPool[key];
						    num -=1;
				        }
				    }
			    });
			    console.log("num:",num);
			    console.log("callbackpool:",callbackPool);

			    //回調函數池中已經不存在此方法才真正發送websocket請求
			    //通知後端不再推送相應資料
			    if(num === 0 ){
				    doSend(webSocketRe);
			    }
		    }
	    }

	    //實際發送websocket請求
	    function doSend(webSocketVo) {
		    return ws.send(JSON.stringify(webSocketVo));
	    }

	    self.send = function (appId, methodId, content) {
		    var webSocketVo = {};
		    webSocketVo.appId = appId;
		    webSocketVo.methodId = methodId;
		    webSocketVo.content = content;
		    if (ws.readyState == 0) {
			   // webSocketVo.isReg = false;//不需要注冊
			    delayPool.push(webSocketVo);
			    console.log("sending is delay.");
			    return "sending is delay.";
		    } else {
			    console.log("sending is doing.");
			    console.log("webSocketVo:",webSocketVo);
			    return doSend(webSocketVo);
		    }
	    }
	    return self;
    }]);
           
Controller層:
           
<pre name="code" class="javascript">/*************************************************************
******************Angular Websocket Controller****************
******************author:ristal******************************
******************created:2014-04-01**************************/

angular.module('websocketControllers')
	.controller('loginCtrl', function ($scope,loginFactory,sWSocket,toaster,$location,$timeout) {
	  	console.log("loginCtrl");

		$scope.status;

		var appId = 'heartBeat';
		var methodId = 'heartBeat';
		  var callback = function(evendata){
			  console.log("callback:",evendata);
			  $scope.menu = evendata;
			  $scope.$apply();
			  console.log($scope.menu);
		  }
		  var callback1 =  function(evendata){
			  console.log("callback1:",evendata);
			  $scope.menu = evendata;
			  $scope.$apply();
			  console.log($scope.menu);
		  }


	  $scope.doLogin = function(user){
	    loginFactory.doLogin(user)
	      .success(function (success) {
	          if(success.resultCode == 200){

	            $scope.status = '登入成功';
	            console.log("doLogin");
	            $location.path('/home');

		          var content2 = {
			          userName:'hmm',
			          userPassword:'111'
		          };
		         //websocket登陸
		        sWSocket.send('login', 'doLogin', content2);

		        //考慮極端情況,一個頁面有多個子產品監聽同一個方法
		        //但展示在頁面的資料需對接收的實時監聽的資料做不同處理

		        //登陸後注冊方法heartBeat,回調函數callback
		        //頁面切換時(也就是登出scope時)才登出此方法
		        sWSocket.register(appId,methodId,callback);
				
				//登陸後也注冊方法heartBeat,回調函數callback1
				//3s後立即登出此方法
		        sWSocket.register(appId,methodId, callback1);
		          $timeout(function () {
			          console.log("unregister callback1");
			          sWSocket.unregister(appId,methodId,callback1);
		          }, 3000);
		        

	          }else if (success.resultCode == 102) {
		          toaster.pop('error', "操作失敗", success.resultReason);
		          $scope.status = success.resultReason;
	          };

	      })
	      .error(function (error) {
	          $scope.status = '登入失敗: ' + error.message;
	      });
	  };

	  $scope.logout = function(){
	      loginFactory.logout()
	        .success(function () {
	            $scope.status = '退出成功';
	            console.log("logout");
	        })
	        .error(function (error) {
	            $scope.status = '退出失敗: ' + error.message;
	        });
	  };

	  //登出scope時登出方法heartBeat,回調函數callback
	  $scope.$on("$destroy",function(){
		  console.log("on-destroy");
		  sWSocket.unregister(appId,methodId,callback);
	  });

  });
           

繼續閱讀