主要记录在开发中使用angular-websocket的学习心得,如有错误请批评指正。
最近一直在学习开发一款物联网项目。(项目地址:https://blog.csdn.net/u013480581/article/details/80931778 )通过后端管理平台,可以将设备的信息反馈到用户端,并实时控制。后端用的workerman+websocket技术,可以实现长连接,双向通信。
主要是通信协议和指令的设计。设备端和用户端先在PC端模拟,demo通过JavaFX基本实现。因为考虑可以通过多种终端控制设备,初步想法是设计一款移动版web的前端。
web端的开发自己还是小白一枚。调研到angular+jqweui还挺符合自己的简单需求,可以实现单页web应用、仿微信UI。
由于JavaScript中提供websocket API,我们不需要操心数据的封装和发送。只需要关心自己的业务逻辑(设计指令实现功能),和与UI的交互。业务逻辑的设计不再啰嗦。
由于刚开始学习angulajs,发现将基于websocket的业务逻辑(主要就是①接收反馈后解析,②封装不同的指令发送)写在js文件后,可以实现②,但没有办法实现异步UI的刷新。
我们知道angularjs的优点就是可以实现UI(html)和业务(js)的分离,类似与软件UI开发中MVC的思想。但是软件UI中通常是通过多线程异步更新UI的,并且API都封装好了。
AngularJS 教程 | 菜鸟教程中可以通过$http读取远程服务器的数据并异步更新UI,是对http数据的支持。但是websocket呢?
通过调用angular-websocket,可以将websocket业务逻辑直接写在factory模块中。
factory服务的原理,其实就是注入服务,用来返回对象给$scope的,参考:深究AngularJS——自定义服务详解(factory、service、provider)。
其中,angular-websocket的回调函数onMessage最为重要了,就是用来接收websocket消息,并且可以实现UI的异步刷新。文档的说明在此:
Register a callback to be fired on every message received from the websocket, or optionally just when the message’s data property matches the filter provided in the options object. Each message handled will safely call r o o t S c o p e . rootScope. rootScope.digest() unless autoApply is set to `false in the options. Callback gets called with a MessageEvent object.
综上,注入factory服务,其中最重要的是实现onMessage,根据不同的业务逻辑功能,其流程:接收到反馈消息——>定义成一个对象——>在factory中return对象——>对象要与UI中$scope变量对应——>异步刷新UI的scope。
注意:factory返回的对象组,①只能是数组和方法。②并且都需要在scope中声明,要不然咋刷新呢。由于官方的demo很简单,演示下自己的demo:
app.factory('Messages', Messages);
app.controller('mainController', function($scope, $rootScope, Messages) {
//连接websocket
$rootScope.Messages = Messages;
});
//反馈数据,需要异步刷新到UI中
var dataA, dataB = null;
var dataB = [];
function Messages($websocket) {
ws = $websocket("ws://"+document.domain+":8282");
ws.onMessage(onmessage);
ws.onError(function(event) {
console.log("连接异常");
});
ws.onClose(function(event) {
console.log("连接关闭");
});
ws.onOpen(function() {
console.log("连接中..");
});
// setTimeout(function() {
// ws.close();
// }, 500)
return {
getdataA: function() {
return dataA;
},
getdataB: function() {
return dataB;
},
dataC: dataC
}
// 服务端发来消息时
function onmessage(e)
{
console.log('接受到的数据:' + e.data);
var data = JSON.parse(e.data);
switch(data['type']){
// 服务端ping客户端
case xxx:
parsedataA(data);
break;
case 'xxx':
parsedataB(data);
break;
case 'xxx':
parsedataC(data);
break;
}
}
//解析反馈A
function parsedataA(data){
dataA = xxx;
}
//解析反馈B
function parsedataA(data){
dataB = xxx;
}
//解析反馈c
function parsedataA(data){
datac = [xxx];
}
//发送指令A
function sendA(pid){
console.log('发送消息A');
send(xxx, xxx);
}
//发送指令B
function sendB(){
console.log('发送消息C');
send(xxx, xxx);
}
...
//发送指令消息
function send(type, content){
var json_data = '{"type":"'+ type +'","content":'+ content +'}';
ws.send(json_data);
console.log("发送的数据: "+ json_data + "\n");
}