一、概述

移动端APP大多数功能都能通过客户端向服务器端发送请求,服务器应答来完成。比如:用户注册,获取商品列表等能力。

但有一些场景需要服务器向客户端推送应用内通知,如:用户之间的即时通信等功能。这种时候就需要建立一个通信通道,让服务器能够给指定的客户端发送下行通知请求。也就是客户端和服务器端之间具备双向通信的能力。

具备双向通行能力的架构对于移动APP属于刚性需求。

使用须知

API网关已经在所有Region开放双向通信能力,双向通信能力构建于WebSocket协议之上,目前Android,Objective-C,JAVA三种SDK均支持双向通信。

(若您有此之外的需求可以工单或者钉钉群:11747055进行咨询)

实现方式

API网关目前已经在所有Region提供双向通信的能力,用户只需要在API网关上设置三个API,然后下载自动生成的SDK到客户端,简单嵌入到客户端就能完美实现客户端和服务器端之间的双向通信的功能。

下面是利用API网关实现双向通信的能力的业务流程简图:

流程描述

(1) 客户端在启动的时候和API网关建立了WebSocket连接,并且将自己的设备ID告知API网关;

(2) 客户端在WebSocket通道上发起注册信令;

(3) API网关将注册信令转换成HTTP协议发送给用户后端服务,并且在注册信令上加上设备ID参数(增加在名称为x-ca-deviceid的header中);

(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了。

因此您可以下载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网关双向通信能力的使用流程:

  1. 开通分组绑定的域名的WebSocket通道;
  2. 创建注册、下行通知、注销三个API,给这三个API授权、并上线;
  3. 用户后端服务实现注册,注销信令逻辑,下载JAVA的SDK发送下行通知;
  4. 下载AndroidSDK,嵌入到客户端,建立WebSocket连接,发送注册请求,监听下行通知;

另外,给大家撰写了SDK实现指南,网址为:https://help.aliyun.com/document_detail/88178.html

这篇文章中的一个结合报文的流程图可以帮助大家更好理解双向通信的原理,贴出来给大家参考:

如果在使用中遇到棘手的问题,请加入我们钉钉交流群:API网关-客户服务群(群号:11747055)。