android 服务器 域名 函数 sdk websocket API exception void 移动推送 API 网关 双向通信
摘要: API 网关目前已经具备双向通信的能力,目前用户只需要在 API 网关上设置三个 API,然后下载自动生成的 SDK 到客户端,简单嵌入到客户端就能完美实现客户端和服务器端之间的双向通信的功能.
阿里云 / 楚骧
一. 概述
移动端 APP 大多数功能都能通过客户端向服务器端发送请求,服务器应答来完成,比如用户注册,获取商品列表等能力.但是有一些场景是客户端向服务器端发送请求这种方式完成不了的,比如服务器向客户端推送应用内通知,用户之间的即时通信等功能.这种时候就需要建立一个通信通道,让服务器能够给指定的客户端发送下行通知请求.也就是客户端和服务器端之间具备双向通信的能力.具备双向通行能力的架构对于移动 APP 属于刚性需求.
API 网关目前已经具备双向通信的能力,目前用户只需要在 API 网关上设置三个 API,然后下载自动生成的 SDK 到客户端,简单嵌入到客户端就能完美实现客户端和服务器端之间的双向通信的功能.
API 网关将逐渐放开此能力给所有用户,目前仅放开了杭州和香港两个 Region.API 网关的双向通信能力构建于 WebSocket 协议之上,目前仅提供 Android 版本的 SDK,后期将提供 iOS 的 SDK.下面是利用 API 网关实现双向通信的能力的业务流程简图:
流程描述
(1) 客户端在启动的时候和 API 网关建立了 WebSocket 连接,并且将自己的设备 ID 告知 API 网关;
(2) 客户端在 WebSocket 通道上发起注册信令;
(3) API 网关将注册信令转换成 HTTP 协议发送给用户后端服务,并且在注册信令上加上设备 ID 参数;
(4) 用户后端服务验证注册信令,如果验证通过,记住用户设备 ID,返回 200 应答;
(5) 用户后端服务通过 HTTP/HTTPS/WebSocket 三种协议中的任意一种向 API 网关发送下行通知信令,请求中携带接收请求的设备 ID;
(6) API 网关解析下行通知信令,找到指定设备 ID 的连接,将下行通知信令通过 WebSocket 连接发送给指定客户端;
(7) 客户端在不想收到用户后端服务通知的时候,通过 WebSocket 连接发送注销信令给 API 网关,请求中不携带设备 ID;
(8) API 网关将注销信令转换成 HTTP 协议发送给用户后端服务,并且在注册信令上加上设备 ID 参数;
(9) 用户后端服务删除设备 ID,返回 200 应答.
二. 双向通信三种管理信令
要使用 API 网关的双向通信能力,首先要了解 API 网关双向通信相关的三种信令,需要注意的是,这三个信令其实就是 API 网关上的三个 API,需要用户去 API 网关创建后才能使用.
1. 注册信令
注册信令是客户端发送给用户后端服务的信令,起到两个作用:
(1)将客户端的设备 ID 发送给用户后端服务,用户后端服务需要记住这个设备 ID.用户不需要定义设备 ID 字段,设备 ID 字段由 API 网关的 SDK 自动生成;
(2)用户可以将此信令定义为携带用户名和密码的 API,用户后端服务在收到注册信令的验证客户端的合法性.用户后端服务在返回注册信令应答的时候,返回非 200 时,API 网关会视此情况为注册失败.
客户端要想收到用户后端服务发送过来的通知,需要先发送注册信令给 API 网关,收到用户后端服务的 200 应答后正式注册成功.
2. 下行通知信令
用户后端服务,在收到客户端发送的注册信令后,记住注册信令中的设备 ID 字段,然后就可以向 API 网关发送接收方为这个设备的下行通知信令了.只要这个设备在线,API 网关就可以将此下行通知发送到端.
3. 注销信令
客户端在不想收到用户后端服务的通知时发送注销信令发送给 API 网关,收到用户后端服务的 200 应答后注销成功,不再接受用户后端服务推送的下行消息.
三. API 网关设置双向通信
1. 开通绑定分组域名的 WebSocket 通道
1.1 创建分组
已经有分组的情况可忽略本节.
要使用 API 网关的基本功能,首先需要在 API 网关上创建一个分组,关于分组的创建,请参见文档:
https://help.aliyun.com/document_detail/29493.html
1.2 在分组上绑定域名
已经已经绑定了域名的情况可忽略本节.
创建完分组后,需要在分组上绑定一个域名,关于分组上域名的绑定,请参见文档:
https://help.aliyun.com/document_detail/29494.html
1.3 开通域名的 WebSocket 通道
绑定好域名后,需要开通域名上的 WebSocket 通道,具体开通方法如下:
开通页面路径:API 网关控制台 -> 开放 API-> 分组详情
2. 创建注册,下行通知,注销信令的 API
需要刚才创建的分组下创建三个 API,普通 API 的创建流程请参见文档:
https://help.aliyun.com/document_detail/29478.html
这三个 API 在创建的时候,需要特别注意的是,需要选择 "双向通信 API 类别" 选项."双向通信 API 类别" 选项在勾选 "WebSocket 协议" 时会自动弹出,如下图:
2.1 注册信令 API
注册信令是客户端发送给用户后端服务的信令,创建的时候需要注意的是:
(1) 一般会包含用户名和密码两个字段,如图所示:
(2) 只能通过 WebSocket 协议传输
当然这个信令的定义由用户自己去定义,包含什么参数都是可以的.重要的是,这个信令的应答必须是 200,客户端才算注册成功.
2.2 下行通知 API
注销信令是用户后端服务发送给客户端的信令,创建的时候需要注意的是:
(1) 强烈建议使用和客户端不同的 APP 进行授权,区分用户后端服务和客户端调用权限;
(2) 可以使用 HTTP/HTTPS/WebSocket 中任意协议调用此 API;
(3) 因为是发送给客户端的,因此不需要和其他 API 一样定义后端服务参数;
(4) 请求中必须携带接收通知的客户端 ID 的 x-ca-deviceid 头,且不可修改;
创建页面如下图:
2.3 注销信令 API
注销信令是客户端发送给用户后端服务的信令,创建的时候需要注意的是只能通过 WebSocket 协议传输.
3. 生成,下载 SDK
在三个信令 API 全部创建成功后,需要将分别授权到指定 APP 上.授权后,需要发布到线上环境.在授权,发布完成后,就可以到 SDK 文档自动生成页面去生成,下载 SDK 了.
目前 API 网关提供的 SDK 中具备 WebSocket 通信能力的只有 Android,其他语言的 SDK 目前还不具备 WebSocket 通信能力.近期将升级 iOS 的 SDK,让它支持 WebSocket 通信通道.
因此您可以下载 Android 的 SDK 作为客户端 SDK,使用这个 SDK 来使用 WebSocket 和 API 网关进行通信,并在此 SDK 上发送注册信令,接收用户后端服务发送的下行通知信令.您可以下载 JAVA 语言的 SDK 作为服务器端 SDK,用来发送下行通知信令.两个 SDK 配合完成双向通信功能.下面是下载页面:
4. 调用 SDK 的注册信令, 并在 SDK 中读取下行通知信令的内容
Android 的 SDK 下载下去后,需要仔细阅读 SDK 的安装和使用说明,也就是 ReadMe.txt 文件.
自动生成的 SDK 里面有所有 API 的调用入口,我们找到调用入口,就可以调用这个 API 来发送注册信令了.下面是一个 Demo 示例,在此 Demo 中,我们在启动的时候先初始化一个 WebSocket 通道出来,在通道中注册接收用户后端服务发送的下行通知的函数 onNotify,客户端接收到用户后端服务发送的下行通知,SDK 会调用这个函数来通知客户端.然后 Demo 提供注册函数 registerWebsocketTest 供外部调用.
public class Demo_HangZhou {
static{
WebSocketClientBuilderParams websocketParam = new WebSocketClientBuilderParams();
websocketParam.setAppKey("12345678");
websocketParam.setAppSecret("12345678");
websocketParam.setApiWebSocketListner(new ApiWebSocketListner() {
@Override
//客户端接收到用户后端服务发送的下行通知,SDK会调用这个函数来通知客户端
public void onNotify(String message) {
System.out.println(message);
}
@Override
public void onFailure(Throwable t, ApiResponse response) {
if(null != t){
t.printStackTrace();
}
if(null != response){
System.out.println(response.getCode());
System.out.println(response.getMessage());
}
}
});
WebSocketApiClient_hangzhou.getInstance().init(websocketParam);
}
public static void registerWebsocketTest(){
WebSocketApiClient_hangzhou.getInstance().register("fred" , "123456" , new ApiCallback() {
@Override
public void onFailure(ApiRequest request, Exception e) {
e.printStackTrace();
}
@Override
public void onResponse(ApiRequest request, ApiResponse response) {
try {
System.out.println(getResultString(response));
}catch (Exception ex){
ex.printStackTrace();
}
}
});
}
}
5. 用户后端服务发送下行通知
用户后端服务在接收到客户端发送的注册信令后,需要记住信令请求中设备 ID.然后用户后端服务给客户端发送下行通知就变得非常容易,就和调用普通 API 一样,发送一个标准的 API 调用给 API 网关就可以了.下面是调用代码示例:
public class Demo_Hanzhou {
static{
HttpClientBuilderParams param = new HttpClientBuilderParams();
param.setAppKey("123456");
param.setAppSecret("123456");
HttpApiClient_BeiJing.getInstance().init(param);
}
public static void HanZhouNotifyTest(){
HttpApiClient_HanZhou.getInstance().notify("NotifyContent" , new ApiCallback() {
@Override
public void onFailure(ApiRequest request, Exception e) {
e.printStackTrace();
}
@Override
public void onResponse(ApiRequest request, ApiResponse response) {
try {
System.out.println(response.getCode());
}catch (Exception ex){
ex.printStackTrace();
}
}
});
}
}
让我们再来整理一下 API 网关双向通信能力的使用流程:
开通分组绑定的域名的 WebSocket 通道;
创建注册,下行通知,注销三个 API,给这三个 API 授权,并上线;
用户后端服务实现注册,注销信令逻辑,下载 JAVA 的 SDK 发送下行通知;
下载 AndroidSDK,嵌入到客户端,建立 WebSocket 连接,发送注册请求,监听下行通知;
来源: https://yq.aliyun.com/articles/394520