一个简单嵌入式WEB业务应用设计
来源:互联网 发布:java 就业班 编辑:程序博客网 时间:2024/06/04 18:46
一个简单嵌入式WEB业务应用设计
主要是针对之前产品中WEB应用的设计的重构,把业务与一些东西分离出来,方便维护,本身比较简单, 注意这个不是说写WEB服务程序的。
工具
goahead
json-c
jquery
数据交互
WEB服务与主应用交互
WEB服务进程同应用进程在同一个嵌入式系统中,两个进程的交互使用UNIX域UDP方试通讯,主要的是数据是,WEB前端的数据请求,数据的提交或控制命令,数据都用json的格式传输。
WEB服务与WEB前端交互
WEB前端的HTML请求都通过goahead处理了,在数据上面,我们用AJAX传输JSON的方式,goahead通过UDP服务转给主应用,主应用处理后返回进goahead,再回应给WEB前端。
之所以用UNIX域UDP通信,一个是速度,也可靠,JSON交换的数据也不是太大,双向通信,简单,包与包之前不用再去分隔了。
WEB服务端
Web服务使用开源的goahead这个工具,它相对于WEB前端来说是一个服务端,在与我们的主应用来说又是一个UNIX域UDP客户端。
WEB服务端的初始化
Goahead的初始化可以参见它的例子中,其实我对这个工具也不太熟悉,在它提供的例子里来改一下,它的初始化操作中有一个initWebs 的过程,这里面设置了一些必要的参数,如默认的网页,比如我的设置的是 index.html 是一个宏定义的:
#define WEBS_DEFAULT_HOME T("index.html")/* Default home page */
#define WEBS_DEFAULT_PORT 80 /* Default HTTPport */
#defineWEBS_DEFAULT_SSL_PORT 433 /* Default HTTPSport */
分别定义了默认的主页,端口。
因为要与主应用中通讯,使用的是UNIX的域UDP方式,所以在goahead里我们要初始创建一个socket的来与主应用交互。
在一个合适的地方,定义一个Web_Client_init,它的作用就是初始化创建一个UNIX的域UDP socket而已,所以在initWebs中调用过程: Web_Client_init()。
在一个合适的地方,定义一个 int Web_Client_Send(char* buf, int len, char* recvbuf, int* maxlen), 用它来把WEB前端的数据转发给主应用,同时接收主应用的回应。
在goahead里接收WEB前端过来的AJAX 请求json数据,做如下的动作:
设置一个URL请求的处理过程:
websUrlHandlerDefine(T("/ajax/json_data"),NULL, 0, ajax_json_data, 0);
这果 URL 为 http://xxxx/ajax/json_data 这样的URL过来的数据,都传给ajax_json_data处理了。如我的如下的处理,
#define RECV_BUF_LEN 2048
static charRECV_BUF[RECV_BUF_LEN];
int ajax_json_data(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
char_t *url, char_t *path, char_t *query)
{
int ret;
char* data = websGetVar(wp,T("data"),"");
int len =strlen(data);
//ret = WebMsg_Send(data, len);
//char recvbuf[1024] = {0};
int recvlen = RECV_BUF_LEN;
RECV_BUF[0]= 0;
ret= Web_Client_Send(data, len, RECV_BUF, &recvlen);
if(ret == 0)
{
if(recvlen == 0)
{
websWrite(wp,T("{status:'failed', data:'Server nodata!'}"));
}else{
websWrite(wp,RECV_BUF);
}
}else{
websWrite(wp,T("{status:'failed'}"));
}
websDone(wp,200);
return 1;
}
一般JSON的请求数据都不大太,注意空间的分配,上面的过程就是调用 Web_Client_Send 把数据发给主应用,主应用处理完后,同样返回的是JSON格式的应答,获取主应用的应答后通过websWrite写回给WEB前端,注意 websGetVar 获取数据的方式,找的是名为”data”的,这个是在WEB网页中JS里定义的,原因是我们的JS代码是这样写的:
functionajaxActionWrap(actionData, callback)
{
$.post(URL_AJAX_ACTION,
{
data: actionData,
},
function(data, status){
if(callback)
callback(data, status)
}
);
}
这样完成后,我们的WEB服务端的事就完成了,它的作用就是负责传输数据,把它同业务分它了。
主应用
主应用的一个任务是要接收WEB服务传过来的WEB前端请求。
创建一个UNIX域UDP服务。比如我们在一个合适的地方创建一个初始化启动服务的方法: Web_Server_Init(),这样就能接收到WEB的请求了。
另一个任务就是对WEB的AJAX JSON请求的处理回应了。
不同的JSON调用,针对不同的业务,所以我们定义一个记录不同业务处理过程的结构:
比如:
typedef int (*JsonActionProc)(char* data, void* jsonobj,AjaxActionProcCallBack cb);
typedef struct _WebAjaxAction{
char*actionName;
JsonActionProc actionProc;
}WebAjaxAction;
actionName是对应处理方法的标识,如WEB前端传一个这样的JSON数据过来:
{"action":"wifi_status","data":{"p1":1,"p2":2}}
那么 wifi_status 就是对应actionName.
记录注册每一个json里的action调用过程,如:
static WebAjaxActionwebAjaxActionList[] = {
{"wifi_status",wifi_status},
{"wifi_scan",wifi_scan},
{"wifi_get_aplist",wif_get_aplist},
{"wifi_conn",wifi_conn},
{"wifi_getAplist",wifi_getAplist},
};
像wifi_status,wifi_scan… 这些都是调用方法的标识,这个要与WEB前端协商好,保持一致。
actionProc 参数就是对应的调用方法了。
上面的过程,也就是如 WEB 传一个JSON数据过来,它里面有对应的actionName,通过actionName找到对应的业务方法,JSON里也会有一些参数,把JSON里的数据解析出来,调用对应的业务方法就行了,同时把处理的过后的数据通过WEB服务端返回的WEB前端。
从上面的过程,来说,调用recvfrom接收到数据报后,调用一个过程,从webAjaxActionList 里找到对应的处理方法,调用处理方法,处理方法完成后,把要返回的数据通过sendto 再回到WEB服务端,再返回的WEB前端。整个过程就完事了。
WEB前端
完成上面的东西,WEB前端就可认方便的调用了,当HTML显示加载完成后,再通过AJAX的方式,用JSON的格式来调用数据。
如我的获取一个WIFI的连接状态,当然,交互的JSON数据需要WEB前端与主应用后端要协商好,用什么样的格式,比如我的是:
{"action":"wifi_status"}
表示调用的方法是 wifi_status
如下面的几个相关的方法:
/*获取WIFI连接状态*/
functiongetWifiStatus()
{
var data ='{"action":"wifi_status"}';
ajaxActionWrap(data,getWifiStatusCallBack);
}
functionajaxActionWrap(actionData, callback)
{
$.post(URL_AJAX_ACTION,
{
data: actionData,
},
function(data, status){
if(callback)
callback(data,status)
}
);
}
functiongetWifiStatusCallBack(data, status)
{
if(status != "success")
{
alert("get wifi statusfailed!\n");
return;
}else{
var jobj = eval(data)
if(jobj)
{
$("#wifiCurAp").html(jobj[0].wifi_status.ssid);
if(jobj[0].wifi_status.status== 1)
$("#wifiCurStatus").html("已连接");
else
$("#wifiCurStatus").html("未连接");
}else{
$("#wifiCurStatus").html("未连接");
}
}
}
在后端,它会找到wifi_status的对应处理方法,处理后返回定义好的JSON数据格式,WEB前端再显示出来。
最后
通过上面的处理方式,对于主应用来说,把业务相关的都隔离开了,在对应的处理方法中,WEB服务端只负责传输数据,WEB前端通过AJAX的方式传输JSON数据和接收,通过JS脚本控制。
在添加新的业务时,也只要修改WEB前端的JS脚本,主后端注册一下处理的方法就行。
注:对WEB应用只懂一点点,对上面的实现提一点注意的地方:
1:JS脚本里最好不要用eval转换数据生成对像,不安全,可以用jQuery里的对应工具。
2:AJAX的请求认证,一定要记得添加,像上面的应用的话,比较好的方式可以加在WEB服务端的ajax_json_data 里,在请求后端应用时,验证一下,见很多产品,AJAX请求尽然没有验证权限。
- 一个简单嵌入式WEB业务应用设计
- 简单Web应用框架设计
- 嵌入式TCP/IP栈设计及WEB应用开发
- 一个简单的WEB应用 VS2005
- 创建一个简单的Web Service应用
- python实现的一个简单web应用
- 应用系统业务撤销设计
- 一个典型Web应用的中间部分是业务层或服务层
- 嵌入式WEB Server的应用
- 嵌入式数据库--SQLite简单应用
- 设计嵌入式操作系统简单原理
- 开发一个简单的web应用定时任务
- 部署于Openshift 上的一个简单java web应用
- struts2建立一个最简单的web应用
- JBoss 系列七十:一个简单的 CDI Web 应用
- 浅析Tomcat原理(一个简单的web应用服务器)
- 每日一得--开发一个简单的 OSGi Web 应用实例
- Maven权威指南-----5、一个简单的Web应用
- zookeeper搭建以及Java连接zookeeper测试
- Java中关于OOM的场景及解决方法
- 底层解惑-spring的IOC相关接口:BeanFactory与FactoryBean
- python中四舍五入及向上向下取整处理
- iOS调用系统日历
- 一个简单嵌入式WEB业务应用设计
- 视图弹出后放大又缩小的动画实现、类似于alertView效果
- Lua 性能优化
- iOS中-Block使用
- 迷之RxJava —— 线程切换
- 怎么防止服务器的任务因断网中断(linux screen 命令详解)
- java并发编程:顺序输出A、B、C循环10次
- .NET MVC实现多图片上传并附带参数(ajaxfileupload)
- NYOJ 164 Game of Connections