一对一WebRTC视频通话系列(三)——leave和peer-leave信令实现

本篇博客主要分为两部分,第一部分为leave信令的实现,即当有客户端离开房间后,服务端和其他在房间内的客户需知晓。第二部分为媒体协商和网络协商相关API。

本系列博客主要记录一对一WebRTC视频通话实现过程中的一些重点,代码全部进行了注释,便于理解WebRTC整体实现。


一对一WebRTC视频通话系列往期博客

一对一WebRTC视频通话系列(一)------ 创建页面并显示摄像头画面
一对一WebRTC视频通话系列(二)------websocket和join信令实现


一对一WebRTC视频通话系列(三)------leave和peer-leave信令实现

一、leave信令实现

1.1 客户端:

javascript 复制代码
//监听离开按钮点击事件
document.getElementById('leaveBtn').onclick = function () {
    console.log("leaveBtn clicked");
    doLeave();
}
javascript 复制代码
function doLeave() {
    var jsonMsg = {
        'cmd': 'leave',
        'roomId': roomId,
        'uid': localUserId,
    };
    var message = JSON.stringify(jsonMsg); //将json对象转换为字符串
    zeroRTCEngine.sendMessage(message);   //设计方法:用实现方法而不是直接用变量    
    console.info("doLeave message: " + message);
}

1.2 服务端

修改signal_server.js文件,在监听客户端发送的消息处添加leave信令代码

javascript 复制代码
// 监听客户端发送的消息
conn.on("text", function (str) {
    console.info("Received msg:"+str);
    var jsonMsg = JSON.parse(str);

    switch(jsonMsg.cmd){
        case SIGNAL_TYPE_JOIN:
            handleJoin(jsonMsg, conn); 
            break;
        case SIGNAL_TYPE_LEAVE:
            handleLeave(jsonMsg);
            break;
    }
});

handleLeave()函数:在某个用户离开房间时,向其他房间内在线的用户发送通知,告知某个用户离开了当前房间。实现原理是通过哈希表(roomMap)来存储房间内的用户信息,当某个用户离开房间时,从哈希表中移除该用户,并遍历房间内其他在线用户,发送通知。

首先,代码会打印一条日志,显示用户ID(uid)和房间ID(roomId)。

然后,代码会获取存储房间信息的Map(roomMap)。

如果房间不存在,代码会打印一条错误日志,然后返回。

从roomMap中移除用户ID(uid)。

如果房间内还有其他在线用户,遍历房间内所有用户(clients)。

对于每个在线用户,会创建一个JSON消息,内容包括用户离开房间的事件类型(SIGNAL_TYPE_PEER_LEAVE)和离开的用户ID(remoteUid)。

将JSON消息转换为字符串(msg),并通过WebSocket发送给该用户(remoteClient)。

最后,代码会打印一条日志,通知用户离开房间。

javascript 复制代码
// 处理用户离开房间
function handleLeave(message){
    // 获取房间ID和用户ID
    var roomId = message.roomId;
    var uid = message.uid;
    console.log(" uid:" + uid + " leave room: "+roomId);

    // 获取房间Map
    var roomMap = roomTableMap.get(roomId);
    if(roomMap == null){
        console.error("roomId:" + roomId + " is not exist");
        return;
    }
    roomMap.remove(uid);
    if(roomMap.size() >= 1){
        var clients = roomMap.getEntrys();
        for(var i in clients){
            jsonMsg = {
                'cmd':SIGNAL_TYPE_PEER_LEAVE,
                'remoteUid':uid
            }
            // 给所有房间内其他用户发送用户离开消息
            var msg = JSON.stringify(jsonMsg);
            var remoteUid = clients[i].key;
            var remoteClient =roomMap.get(remoteUid);
            if(remoteClient){
                console.info("notify peer"+ remoteClient.uid +"uid" + uid + "leave room");
                remoteClient.conn.sendText(msg);
            }
        }
    }
}

运行结果:

客户1:

客户2:

服务端:

二、媒体协商和网络协商API

媒体协商

  • createOffer
    基本格式:aPromise = myPeerConnection.createOffer([options]);
javascript 复制代码
	var options = {
		offerToReceiveAudio: true, // 告诉另一端,你是否想接收音频,默认true
		offerToReceiveVideo: true, // 告诉另一端,你是否想接收视频,默认true
		iceRestart: false, // 是否在活跃状态重启ICE网络协商
	};
  • createAnswer
    基本格式:aPromise = RTCPeerConnection .createAnswer([ options ]); 目前createAnswer的options是无效的。
  • setLocalDescription
    基本格式:aPromise = RTCPeerConnection .setLocalDescription(sessionDescription);
  • setRemoteDescription
    基本格式:aPromise = pc.setRemoteDescription(sessionDescription);

https://webrtc.github.io/samples/src/content/peerconnection/restart­ice/

活跃状态下,页面源代码中iceRestart默认为true

javascript 复制代码
offerOptions.iceRestart = true

修改iceRestart为flase,则响应如下,不再进行ice candidate交换

网络协商

  • addIceCandidate
    基本格式:aPromise = pc.addIceCandidate(候选人);
    candidate
    注意Android和Web端的不同。
属性 说明
candidate 候选者描述信息
sdpMid 与候选者相关的媒体流的识别标签
sdpMLineIndex 在SDP中 m=的索引值
usernameFragment 包括了远端的唯一标识
javascript 复制代码
	var candidateJson = {
		'label': event.candidate.sdpMLineIndex,
		'id': event.candidate.sdpMid,
		'candidate': event.candidate.candidate
	};
相关推荐
可乐鸡翅yeah_28 分钟前
hls.js 缓冲区参数 maxBufferLength、maxBufferSize 通俗讲解与业务调参
开发语言·javascript·ios·音视频·safari·m3u8
wangbing11251 小时前
开发指南148-WebSocket-后端
网络·websocket·网络协议
小宋10211 小时前
视频 RAG 从零实现:镜头切分、字幕对齐与时间段引用
人工智能·音视频
Dovis(誓平步青云)1 小时前
导览音频切换太快,旧讲解不能覆盖新展品
android·前端·javascript·ecmascript·音视频·宠物
归秋14218 小时前
多轨音频智能混音软件怎么选:从 demo 到更完整作品的 AI 后期工具思路
人工智能·音视频
小猴子爱上树20 小时前
跨马翻译:批量图片翻译与视频字幕、智能抠图一站式在线图片翻译工具
大数据·人工智能·python·音视频
每天死循环21 小时前
ComfyUI MiniMax H3文生视频(t2v)提示词教程:四段式写法+5秒768p实测(附模板和参数)
音视频·文生视频·comfyui·ai视频·minimax
企业数字化笔记1 天前
视频像素分割怎么选?HSV 阈值、传统掩膜、语义分割和实例分割的效果与代价
opencv·音视频
youdexiang1 天前
AI 生成会议纪要好用吗?多款 APP 功能分析
java·人工智能·音视频
DP DPharness1 天前
手机连不上 DSH 时的排错顺序:从 401 到 WebSocket 放行
websocket·网络协议·智能手机