MQTT作为WebRTC信令

Stun Server是开源的coTurn穿透服务器,Signal Server是开源的Apache Active MQ。

部署环境

搭建信令服务器

Signal Server用的是开源的Apache ActiveMQ,网上有很多花里胡哨的方法,这个是简单能搭建成功的过程,搭建过程。

搭建穿透服务

穿透服务器用的是开源的coturn,搭建过程

SDP交换
根据MQTT协议订阅发布机制:
订阅同一个主题:(实现接收消息)
发布同一个主题:(实现发布消息)

对于每一个客户端来说唯一标示是ClientId,客户端发布消息时设置的主题也是ClientId.

1、客户端连接到ActiveMQ服务器


MQTT作为WebRTC信令_第1张图片
main

这里的ClientId,就是在ActiveMQ服务端添加的


MQTT作为WebRTC信令_第2张图片
添加ClientId

这里主要是连接到ActiveMQ的流程

/**
     * 连接到服务器
     * @param clientId
     */
    private void CreateConnect(String clientId) {
        this.clientId = clientId;

        //服务器地址
        String  uri ="tcp://";
        uri = uri + host + ":" + port;
        Log.d(TAG,"URI === " + uri + "   ClientID === " + clientId);

        MqttAndroidClient client = new MqttAndroidClient(context,uri,clientId);

        mqttConnection = new MqttConnection(clientId,host,port,client,false);

        MqttConnectOptions conOpt = new MqttConnectOptions();

        conOpt.setConnectionTimeout(30);//连接超时时间
        conOpt.setKeepAliveInterval(60);//心跳间隔时间 100 S

        client.setCallback(new MqttCallbackHandler(context,clientId));//连接后的回调
        //开始连接到服务器
        try {
            client.connect(conOpt,null,new ConnectCallBackHandler(context));
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

首先,呼叫方initCall,主要作用是创建PeerConnection对象,设备,将音视频数据封装成MediaStream添加到然后打开本地音视频PeerConnection中,显示呼叫页面。
然后呼叫方startCall,主要作用是CreateOffer,SendOffer,所以要发布Topic:呼叫方Message;
假如ClientA呼叫ClientB,首先ClientA订阅主题ClientB,然后ClientB订阅主题ClientA。

Client A给Client B发送消息时,发布主题Client_A_ID和Message。
Client B给Client A发送消息时,发布主题Client_B_ID和Message。

zjf001连接到服务器
根据前面文章,看一下基本流程

  • Client A连接到Signal Server,订阅所有主题,Client B连接到Signal Server,订阅所有主题。

  • Client A首先发布主题TOPIC_CLIENTIDA_TO_CLIENTIDB_CALL_OUT,发送消息CALL_OUT,创建PeerConnection对象,设备,将音视频数据封装成MediaStream添加到然后打开本地音视频PeerConnection中,显示呼叫页面。

  • Client B收到消息CALL_OUT之后,显示接听页面,点击接听按钮之后,Client B发布主题TOPIC_CLIENTIDB_TO_CLIENTIDA_CALL_IN,发送消息CALL_IN,Client A接收到CALL_IN后,ClientA调用PeerConnection的CreateOffer方法创建一个用于offer的SDP对象,SDP对象中保存当前音视频的相关参数。ClientA通过PeerConnection的SetLocalDescription方法将该SDP对象保存起来,然后发布主题TOPIC_CLIENTIDA_TO_CLIENTIDB_OFFER_SDP
    和消息SDP,并通过Signal服务器发送给ClientB。

  • ClientB接收到ClientA发送过的offer SDP对象,通过PeerConnection的SetRemoteDescription方法将其保存起来,并调用PeerConnection的CreateAnswer方法创建一个应答的SDP对象,通过PeerConnection的SetLocalDescription的方法保存该应答SDP对象,然后发布主题TOPIC_CLIENTIDB_TO_CLIENTIDA_ANSWER_SDP和消息SDP,并将它通过Signal服务器发送给ClientA。

  • ClientA接收到ClientB发送过来的应答SDP对象,将其通过PeerConnection的SetRemoteDescription方法保存起来。

  • 在SDP信息的offer/answer流程中,ClientA和ClientB已经根据SDP信息创建好相应的音频Channel和视频Channel并开启Candidate数据的收集,Candidate数据可以简单地理解成Client端的IP地址信息(本地IP地址、公网IP地址、Relay服务端分配的地址)。

  • 当ClientA收集到Candidate信息后,PeerConnection会通过OnIceCandidate接口给ClientA发送通知,ClientA会发布主题 TOPIC_CLIENTIDA_TO_CLIENTIDB_CANDIDATE
    和消息ICESERVER,ClientA将收到的Candidate信息通过Signal服务器发送给ClientB,ClientB接收到消息后,通过PeerConnection的AddIceCandidate方法保存起来。同样的操作ClientB对ClientA再来一次。

  • 这样ClientA和ClientB就已经建立了音视频传输的P2P通道,ClientB接收到ClientA传送过来的音视频流,会通过PeerConnection的OnAddStream回调接口返回一个标识ClientA端音视频流的MediaStream对象,在ClientB端渲染出来即可。同样操作也适应ClientB到ClientA的音视频流的传输。

你可能感兴趣的:(MQTT作为WebRTC信令)