您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
混合移动应用的消息推送之 websocket
 
 来源:ibm 发布于:2017-2-16
   次浏览      
 

混合移动应用消息推送

混合应用一般使用 Cordova 之类的中间件,以 WebView 作为用户界面层,以 Javascript 作为基本逻辑,以及和中间件通讯,再由中间件访问底层 API 的方式,进行应用开发。开发时可能不采用或者大部分不采用原生语言,但是却有所有原生应用的特性。而开发消息推送功能时,我们就既可以使用 Native App 的系统自带推送如 GCM 和 APNS,又可以使用基于 html5 的 websocket 推送。

对于混合应用的 websocket 消息推送,其基本原理如下:

图 1. Hybrid app websocket 工作流程

而原生应用的消息推送,其基本原理如下图:

图 2. 原生 app 消息推送工作流程

目前后者主要应用于原生 app, 而前者由于开发周期短,跨平台性好,维护成本低,一般可以用于混合应用的消息推送。基于 websocket 的消息推送,我们就可以自己去实现消息推送的服务端,这样我们就掌握了推送服务的主动权,对于安全性极高的企业,websocket 推送无疑是最好的选择,因为如果使用 GCM 或者 APNS 推送,我们不得不将信息发送到 GCM server 或者 APNS server, 再由 GCM 或者 APNS 服务端转发到客户端,信息安全性不得而知。一旦推送服务器出现异常,我们的消息推送将变得非常被动。 但是 GCM 和 APNS 也是使用长连接进行消息推送,而且一个手机上的所有 app 共用一个长连接,对于手机性能将会有极大的帮助。两种推送各有利弊,读者可自选选择。本文将针对 websocket 的消息推送进行一系列介绍。

Websocket 接口简介

WebSocket 的实现分为客户端和服务端两部分,客户端(通常为浏览器)发出 WebSocket 连接请求,服务端响应,实现类似 TCP 握手的动作,从而在浏览器客户端和 WebSocket 服务端之间形成一条 HTTP 长连接快速通道。两者之间后续进行直接的数据互相传送,不再需要发起连接和响应。同时两者都可以关闭这个长连接。我们正是利用了混合移动应用的 webview 可以支持 websocket 的这个特性来实现服务器端对客户端的一个消息推送。Websocket 针对客户端而言,性能,资源使用以及及时性要比传统的轮询更好。

Websocket 客户端 API

对于 websocket 客户端,目前主流的移动操作系统的 webview 层都已经支持 websocket 服务。以下列举了常见的移动系统支持情况:

表 1. 主流移动系统的 webview 对 websocket 的支持情况

常见浏览器和移动系统的 webview 都已经实现了 w3 规范的 websocket 接口,具体接口参考清单 1

清单 1. Websocket 客户端接口

[Constructor(in DOMString url, in optional DOMString protocol)] 
interface WebSocket {
readonly attribute DOMString URL;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSED = 2;
readonly attribute unsigned short readyState;
readonly attribute unsigned long bufferedAmount;
//networking
attribute Function onopen;
attribute Function onmessage;
attribute Function onclose;
boolean send(in DOMString data);
void close();
};
WebSocket implements EventTarget;

其中 URL 属性代表 WebSocket 服务器的网络地址,协议通常”ws”或者”wss“,send 方法就是发送数据到服务器端,close 方法就是关闭连接。除了这些方法,还有一些很重要的事件:onopen,onmessage,onerror 以及 onclose。详细解释请参考表 2

表 2. Websocket 的对象方法属性

下面一段代码展示了建立 websocket 实例:

清单 2. Websocket 创建连接实例

var ws= new WebSocket("ws://localhost:8080/PushNotification"); 
ws.onopen = function (event) {
console.log("connected to server");
};
ws.onmessage = function (event) {
//when a new message coming, we will call Cordova plugin here
};

 

当有新消息到达时,onmessage 会自动触发,我们可以在这个方法里利用 Cordova plugin 去实现调用 android 或者 ios 的 notification。

Websocket 服务器端 API

对于 websocket 服务器端,目前主流的 web 服务器都已经支持。以下列举了常见的服务器支持情况:

表 3. 主流 web 服务器对 websocket 的支持情况

以下我们使用 websphere liberty 8.5.5.5 作为 web 服务器,websocket 功能需要另外安装,步骤如下:

1.安装 websocket,执行以下命令

bin/featureManager install websocket-1.0 --when-file-exists=ignore

2.在 server.xml 中引入如下配置

<featureManager> 
<feature>websocket-1.0</feature>
</featureManager>

3.重启 websphere liberty 即可生效

WebSocket 服务端的代码示例如下:

清单 3. Websocket 服务器端接口

@ServerEndpoint(value = "/PushNotification") 
public class PushNotifyWithWebSocket {
private static Set<Session>
sessions = Collections.newSetFromMap(new
ConcurrentHashMap<Session,Boolean>());

@OnMessage
public void receiveMessage(String message) {
//todo
}
@OnOpen
public void onOpen(Session session, EndpointConfig ec) {
sessions.add(currentSession);

}
@OnClose
public void onClose(Session session, CloseReason reason) {
//todo
}
@OnError
public void onError(Throwable t) {
//todo
}
/**
* Send a message to a all client
* @param message
*/
public void sendMessage(JSONArray message) throws Exception {

ObjectMapper mapper = new ObjectMapper();
//send message to all online user
for (Session session: sessions){
session.getBasicRemote().sendText(message. toString());
}
}
}

使用 ServerEndpoint 注释的类必须有一个公共的无参数构造函数,@onMessage 注解的 Java 方法用于接收传入的 WebSocket 信息,这个信息可以是文本格式,也可以是二进制格式。

OnOpen 在这个端点一个新的连接建立时被调用。参数提供了连接的另一端的更多细节。Session 表明两个 WebSocket 端点对话连接的另一端,可以理解为类似 HTTPSession 的概念,我们可以将多个 Session 保存到 server 端,以便我们与客户端通信。OnClose 在连接被终止时调用。参数 closeReason 可封装更多细节,如为什么一个 WebSocket 连接关闭。OnError 在 websocket 通信出现异常才会调用。

在清单 3 中我们可以看出,如果我们有新消息需要推送到客户端,我们就可以调 sendMessage 方法,一旦客户端收到 message 就可以通过 Cordova plugin 调用系统 API 来实现消息提示。下文将着重讲解如何创建一个 Cordova plugin。

利用 Cordova plugin 调用本地 notification

以上我们了解了如何在 Hybrid App 中创建 websocket 连接,当我们收到信息时,这个时候只需要调用 IOS 或者 Android 的本地消息推送即可让用户知道有新的信息到达。这个时候我们就要创建一个新的 Cordova plugin 去触发 notification。

创建一个 Cordova plugin

Cordova plugin 是我们通过 JavaScript 调用系统 API 的中间件,一般情况下我们通过 JavaScript 不能够完成而系统 API 可以完成的任务时,我们就要创建一个 plugin。不同的平台在调用底层 API 时会有不同,但是前段代码不会改变。 以下我们将创建一个 Cordova plugin 用来调用本地消息推送。下文以 android 平台为例,其他平台思路类似。

1.在 cordova_plugins.js 中引入新的 plugin

 { 
"file": "plugins/com.test.notification/www/notification.js",
"id": "com.test.notification.localNotification",
"clobbers": [
"cordova.plugins.localNotification"
]
}

2.然后在 plugins/com.test.notification/www 目录下边创建 notification.js,代码示例如下:

cordova.define("com.test.notification.localNotification",
function(require, exports, module) {
var argscheck = require('cordova/argscheck'),
utils = require('cordova/utils'),
exec = require('cordova/exec');
var localNotification = function() {
};
localNotification.sendNotify = function(message,success, error) {
cordova.exec(success, error, 'localNotification', 'sendNotify', message);
};
module.exports = localNotification;
});

3. 创建一个 java 类来继承 Cordova 接口,代码示例如下

package com.test.notification; 
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

//ellipsis code
// …… .

public class localNotification extends CordovaPlugin {
//ellipsis code
// … ..
@Override
public boolean execute(String action, final JSONArray args,
final CallbackContext callbackContext) throws JSONException {
if ("sendNotify".equals(action)) {
NotificationManager manager = (NotificationManager) this.cordova
.getActivity().getSystemService(
Context.NOTIFICATION_SERVICE);

String title = args.getString(0);
String text = args.getString(1);
Notification notification
= new Notification.Builder(this.cordova.getActivity())
.setTicker("New notification").setDefaults(1)
.setSmallIcon(R.drawable.icon)
.setAutoCancel(true)
.setContentTitle(title).setContentText(text)
.setContentIntent(PendingIntent.getActivity(this.cordova.getActivity(),
0, this.cordova.getActivity().getIntent(), 0)).build();
manager.notify(1, notification);

return true;
}
}
}

在 res/xml/config.xml 配置 plugin feature

<feature name=" localNotification "> 
<param name="android-package"
value="com.test.notification.
localNotification" /> </feature>

至此一个完整的 plugin 已经建立完成。然后我们只需要在 JavaScript 端调用这个 plugin 就可以触发一个 notification,具体调用方式参考清单 4:

清单 4. 客户端调用系统 notification

var ws= new WebSocket("ws://localhost:8080/PushNotification"); 
ws.onopen = function (event) {
console.log("connected to server");
};
ws.onmessage = function (event) {
var notifys = jQuery.parseJSON(evnt.data);
var message = ["New Job Notification",notifys[0].message];
cordova.plugins.localNotification.sendNotify(message);
};

当执行 cordova.plugins.localNotification.sendNotify 方法时,cordova 会向 webview 发送一个 XMLHttpRequest 请求并且包含的参数中有 sendNotify 关键字,这个请求会被我们已经实现的 Cordova plugin 拦截住,并且执行一个 android Notification,这个时候一个消息就成功推送到客户端。如下图

图 3. 通过 websocket server 成功将信息推送到客户端

Websocket 消息推送的利弊

Websocket 消息推送优点 :

开发周期短,维护成本低。

消息不经转第三方服务器,直接由服务器发送到客户端,安全性好。基于 GCM 或者 APNS 的消息推送会把消息发送 GCM 服务器或 APNS 服务器,再由他们转发到客户端。

自己开发服务端,可扩展性好。

对于客户端而言,长连接比轮询的方式性能和及时性更好。

Websocket 消息推送缺点 :

长连接浪费服务端资源。

不能后台运行,一旦 app 退出就不能收到 notification。

由于服务器保持多个长连接,性能将会下降,最大连接数也会有限制。

总结

随着手机性能的不断改善,hybrid app 的性能几乎接近原生 app 的体验,最重要的是还可以跨平台,所以 hybrid app 越来越受到开发者的青睐,尤其是前端开发者。他们既能利用熟悉的 html5, css3,angular js 作为主体开发语言,又能适时利用 Cordova plugin 调用底层的 API,这样既节约了开发成本,又能体验原生开发的乐趣。本文就利用 Cordova 跨移动平台框架,开发了一组调用 local notification 的 android plugin, 前端代码不需要改变,我们只需要编写 iOS 端的 local notification 就可以适配一下 ios 平台。利用这种方法,我们同样可以扩展更多 plugin。而 websocket 作为 HTML5 的新特性,它不像传统的轮询查询服务端的方式而是主动 push 的方式向客户端推送消息,websocket 这种长连接的特性不仅适合消息推送,对于实时在线聊天功能也是非常适合。本文就结合了 websocket 和 Cordova 的特性开发了混合移动的消息推送。

 

   
次浏览       
 
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
 
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试
最新活动计划
软件架构设计方法、案例与实践 8-23[特惠]
Linux内核编程及设备驱动 8-15[北京]
Python、数据分析与机器学习 8-23[特惠]
嵌入式软件架构设计 8-22[线上]
QT应用开发 9-5[北京]

android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...