xie-cn
v1.0.7
Published
贤主之用人也,犹巧工之制木也,大者以为舟航、柱梁,小者以为楫、楔。
Downloads
12
Readme
楔
物联网应用模块的最小化平台支撑(基于KOA实现)
1 概要说明
本框架意在实现为最小化的物联网应用模块提供容器,并提供简单易用的网络交互方式与高性能的实时数据更新
2 方法及使用
(1) skyframe
说明:窗体,我们将符合物联网平台规范的应用模块包含于独立的窗体,这个窗体提供最大化/最小化/关闭/重叠/透明/拖拽等常用功能
使用:
var frame = new skyframe(); //获取对象
frame.init({ //初始化
id:"headFrame",
container:$("#headDiv"),
engine:"login"
});
其中:init方法接受一个option参数,配置如下:
var option = {
id:"", //为窗体设置一个ID
container:$("body"), //设置窗体的容器(jquery对象)
engine:"", //指定模块(规定:每个模块名称在项目中唯一)
closeable:false, //设置窗体是否可关闭,默认为false
maximizeable:false, //设置窗体是否可最大化,默认为false
minimizeable:false, //设置窗体是否可以最小化,默认为false
moveable:false, //设置窗体是否可以拖拽,默认为false
resizeable:false //设置窗体是否可以改变大小,默认为false(如果设置为true,则鼠标可以拖动边框来改变窗体大小并触发窗体的resize事件)
}
公共方法:
frame.flush();//刷新模块
frame.bind(evname,callback); //绑定事件,支持click,close,max,min,move,reset事件
frame.close(callback); //关闭窗体
frame.maximize(callback); //最大化窗体
frame.minimize(callback); //最小化窗体
frame.resetFrame(callback); //恢复最初的大小和位置
/**
* 移动到
* @param top 绝对定位
* @param left 绝对定位
* @param callback 回调函数
*/
frame.moveTo(top,left,callback);
/**
* 设置宽高
* @param width 宽度
* @param height 高度
* @param callback 回调函数
*/
frame.chengeTo(width,height,callback);
frame.setStyle(key,style); //设置窗口的样式
frame.setStyleObj(obj); //设置窗口的样式
(2) netclient
说明:通讯模块,对于每一个符合物联网平台规范的应用模块,前端页面都会有此内置 net 对象,此对象提供非常灵活的前后台交互方法与实时的数据推送功能等,同样的在server端有一个net的global对象与其配合使用
数据链(dataline): netclient对象内置一个data属性,此属性具有前后台实时数据同步的能力,对此属性进行赋值或者修改等操作时,前后台都能够获取data的最新结果
例如,web端有如下操作:
net.data.a={"name":"小明"};
则后台可以获取这个属性,代码如下:
console.dir(net.data.a); //{"name":"小明"}
同理,后台也可以如上赋值被web端直接读取
公共方法: on(eventname,callback):绑定侦听事件,对应服务器端的emit方法,这里需要注意call dataline initserver connect disconnect这几个事件为内置事件,禁止侦听
web端写法
net.on("myevent",function(data){
console.dir(data);
});
这样当对应的服务端有如下代码执行时,将打印data数据
var data = {a:12};
net.emit("myevent",data); //触发前台的myevent事件
emit(eventname,data,callback):触发服务器端绑定的事件,对应于服务器端的on方法,同样注意 call dataline initserver connect disconnect这几个事件为内置事件,禁止侦听
web端写法
net.emit("testEmit",{a:1},function(res){
console.dir(res);
});
这样当对应的服务端有如下代码时,则触发执行并触发前台的callback
var data = {a:12};
//由前台的emit方法触发
net.on("testEmit",function(obj,callback){
console.dir(obj); //前台传过来的数据对象
callback&callback(data); //前台的callback会打印出{a:12}
});
call(funcname,data,callback):调用服务端的方法
web端写法
net.call("test",{a:1},function(data){
console.dir(data);
});
当对应的服务端有如下方法,将会执行并触发前台的callback
this.test = function(data,callback){
console.dir(data);
callback&callback(1); //前台将打印1
}
getAjaxURL();获取Ajax的路径给第三方的插件用,需要配合getAjaxData方法使用,才能正常发起一个Ajax请求
var url = net.getAjaxURL();
getAjaxData(method,parms);由于后台过滤,发起Ajax必须要带一些参数,配合getAjaxURL才能正常的发起一个Ajax;method对应后台的方法名称,parms为传入后台的参数
var data = net.getAjaxData("testmethod",parms);//这样 后台的testmethod方法就可以被ajax调用,并且穿过去parms参数供业务使用
getView(method, parms, callback):经对应的服务器端method得到ejs,注意:如果method等于getEjs的话,则parms参数必须为有效的ejs路径字符串,此种情况直接返回parms指定的模版
web端写法
net.getView("testRender",'',function(res){
$("body").html(res);
});
对应的服务器端写法
this.testRender = async function(ctx,parms){
console.dir(parms);
return ctx.render("engine/example/web/sonejs/student.ejs",{});
}
getData(method, parms, callback):向后台请求获取数据,方法使用同getView相同,只是对应的后台写法res.render应改为res.body
我们可能是后台自启动的服务推送给前台数据,为了适应这样的场景,添加如下两个方法:
/**
* 根据服务名称获取所有已经开启的socketIO客户端信息
* @param service
* @returns [{"key":"socketid","value":{net:{},service:""}},{}......]
*/
var clients = net.getSockets(service);
getSockets方法会获得对应service的模块的所有打开着的客户端,返回一个形如[{"key":"socketid","value":{net:{},service:""}},{}......]的一个数组对象 通过遍历这个对象可以获取每一个net,然后就可以向指定的前台推送数据了
第二个方法如下:
//获取所有的socket信息
var property = net.getAllSocket();
这个方法用一个特定的数据结构进行存储,结构如下:
{
service:[
{"key":"socketid","value":{net:{},service:""}},
{"key":"socketid","value":{net:{},service:""}},
...
],
...
}
它会获取所有的客户端,也就意味着它可以向其他任何一个模块推送数据,这将会增加模块的耦合,导致业务的混乱,增加代码的复杂度,增加维护难度.总之,不推荐使用
(3) 数据联动
说明:借助于数据链(dataline),应用Vue.js使数据变动绑定到dom元素上,实现数据链对页面元素的实时控制,包括文本、样式、显示/隐藏、元素填充等
公共方法: datachange(id,option);初始化数据绑定 示例:
例如存在如下HTML片段:
<div id="realData">
<span>{{message}}</span>
<span v-bind:title="title">
绑定title属性
</span>
<p v-if="seen">显示与隐藏</p>
</div>
使用datachange方法初始化数据绑定,如下:
var vue = net.datachange("realData"); //"realData"为需要数据绑定的元素ID,此方法返回一个Vue实例
当数据链(dataline)的message、title、seen属性值发生变动时,页面元素则同时发生变化(显示message的值、title属性被动态赋值、显示与隐藏)
比如:
当net.data.message="hello world"时,页面`<span>{{message}}</span>`则相应的变为`<span>hello world</span>`
当net.data.title = "测试标题"时,页面`<span v-bind:title="title">绑定title属性</span>`则相应的变为`<span v-bind:title="测试标题">绑定title属性</span>`
当net.data.seen = true时,`<p v-if="seen">显示与隐藏</p>`会显示
当net.data.seen = false时,`<p v-if="seen">显示与隐藏</p>`会隐藏掉
更多功能与效果请参见 Vue.js官网:https://cn.vuejs.org/
(4) 规范
(1) 所有独立业务模块必须放在 /engine 文件夹下;模块名称为文件夹名称,文件夹包含 src与web两个文件夹,src存放服务端代码,web存放页面、js、css、图片等前端静态文件,web下的文件都能够被浏览器直接访问到
--src文件夹下必须包含service.js(必须叫这个名字)文件作为后台逻辑的统一入口,结构如下:
--业务模块必须包含README.MD文件,说明模块的用途与注意事项等
service.js
const jwt = require('jsonwebtoken');
function service(){
//内置方法,实现此方法,则当模块调用时先执行此方法的逻辑
this.init = function(ctx,parms){
return ctx.render("engine/login/web/login/login.ejs",{});
}
//可被前台getView调用的方法
//ctx为KOA2框架的上下文
//parms为前台传送的参数
this.login = async function(ctx,parms){
var data = JSON.parse(parms);
const token = jwt.sign({user: data.username}, sysconfig.jwt.option.secret);
var res = {flag:"success",data:token};
return ctx.body=JSON.stringify(res);
}
}
module.exports = service;