WebRTC学习笔记四 RTCDataChannel

news2024/11/25 18:38:18

一、RTCDataChannel

    简单来说,RTCDataChannel 就是在点对点连接中建立一个双向的数据通道,从而获得文本、文件等数据的点对点传输能力。它依赖于流控制传输协议(SCTP),SCTP 是一种传输协议,类似于 TCP 和 UDP,可以直接在 IP 协议之上运行。但是,在 WebRTC 的情况下,SCTP 通过安全的 DTLS 隧道进行隧道传输,该隧道本身在 UDP 之上运行

    这个示例在Connect之后,可以输入文本后,使用send发送到另一端。注意: 尽管参与连接的两端都在同一页面,我们将启动连接的一端称为 "local" 端,另一端称为 "remote" 端。

1.建立本地节点

localConnection = new RTCPeerConnection();
​
sendChannel = localConnection.createDataChannel("sendChannel");
sendChannel.onopen = handleSendChannelStatusChange;
sendChannel.onclose = handleSendChannelStatusChange;

    第一步是建立该连接的 "local" 端,它是发起连接请求的一方。 下一步是通过调用RTCPeerConnection.createDataChannel() 来创建 RTCDataChannel 并设置事件侦听以监视该数据通道, 从而获知该通道的打开或关闭 (即获得该对等连接的通道打开或者关闭的时机)。

    请务必记住该通道的每一端都拥有自己的 RTCDataChannel 对象。

    createDataChannel方法允许传入第二个参数进行不同的配置

  • reliable 设置消息传递是否进行担保

  • ordered 用来设置消息的接受是否需要按照发送时的顺序

  • maxRetransmitTime 设置消息发送失败时,多久重新发送

  • maxRetransmits 设置消息发送失败时,最多重发次数

  • protocol 设置强制使用其他子协议,但当用户代理不支持该协议时会报错

  • negotiated 此选项用来设置开发人员是否有责任在两边创建数据通道,还是浏览器来自动完成这个步骤

  • id 这个用来设置通道的唯一标识,可以在多通道时进行区分

    这些配置项很多,不过大部分只在高级应用中才会使用。主要使用的配置项是reliable和 ordered,当设置为true时数据通道表现得更像TCP,设置为False时表现得更像UDP。

    negotiated 为解决两边用户同步创建数据通道而设置。用来处理ondatachannel事件触发时的不同行为。默认值是false,表示浏览器会在通道另一边自动触发这个事件,告诉它这个新通道。如果设置成True,开发者需要自己在通道两边创建相同ID的数据通道。

【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~

  

2.建立远程节点

remoteConnection = new RTCPeerConnection();
remoteConnection.ondatachannel = receiveChannelCallback;

    远程端的建立过程类似“local”端, 但它无需自己创建 RTCDataChannel , 因为我们将通过上面建立的渠道进行连接。 我们创建对 datachannel 的事件处理回调;数据通道打开时该逻辑将被执行, 该回调处理将接收到一个 RTCDataChannel 对象,此过程将在文章后面部分描述。

3.设立ICE 候选人

    下一步为每个连接建立 ICE 候选侦听处理, 当连接的一方出现新的 ICE 候选时该侦听逻辑将被调用以告知连接的另一方此消息。

    注意: 在现实场景,当参与连接的两节点运行于不同的上下文,建立连接的过程或稍微复杂些,每一次双方通过调用RTCPeerConnection.addIceCandidate(),提出连接方式的建议 (例如: UDP,、中继UDP 、 TCP之类的) , 双方来回往复直到达成一致。本文既然不涉及现实网络环境,因此我们假定双方接受首次连接建议。

    localConnection.onicecandidate = e => !e.candidate
        || remoteConnection.addIceCandidate(e.candidate)
        .catch(handleAddCandidateError);
​
    remoteConnection.onicecandidate = e => !e.candidate
        || localConnection.addIceCandidate(e.candidate)
        .catch(handleAddCandidateError);

    我们配置每个 RTCPeerConnection 对于事件 icecandidate 建立事件处理。

4.启动连接尝试

    建立节点连接的最后一项是创建一个连接offer.

    localConnection.createOffer()
    .then(offer => localConnection.setLocalDescription(offer))
    .then(() => remoteConnection.setRemoteDescription(localConnection.localDescription))
    .then(() => remoteConnection.createAnswer())
    .then(answer => remoteConnection.setLocalDescription(answer))
    .then(() => localConnection.setRemoteDescription(remoteConnection.localDescription))
    .catch(handleCreateDescriptionError);

5.数据通道(data channel)的连接

    RTCPeerConnection 一旦open, 事件datachannel 被发送到远端以完成打开数据通道的处理, 该事件触发 receiveChannelCallback() 方法,如下所示:

  function receiveChannelCallback(event) {
    receiveChannel = event.channel;
    receiveChannel.onmessage = handleReceiveMessage;
    receiveChannel.onopen = handleReceiveChannelStatusChange;
    receiveChannel.onclose = handleReceiveChannelStatusChange;
  }

    事件datachannel 在它的channel属性中包括了: 对代表remote节点的 channel的RTCDataChannel 的指向, 它保存了我们用以在该channel上对我们希望处理的事件建立的事件监听。 一旦侦听建立, 每当remote节点接收到数据 handleReceiveMessage() 方法将被调用, 每当通道的连接状态发生改变 handleReceiveChannelStatusChange() 方法将被调用, 因此通道完全打开或者关闭时我们都可以作出相应的相应。

6.对通道状态变化的处理

    local节点和remote节点采用同样的方法处理表示通道连接状态变更的事件。

    当local节点遭遇open 或者 close 事件, handleSendChannelStatusChange() 方法被调用:

function handleSendChannelStatusChange(event) {
    if (sendChannel) {
      var state = sendChannel.readyState;
​
      if (state === "open") {
        messageInputBox.disabled = false;
        messageInputBox.focus();
        sendButton.disabled = false;
        disconnectButton.disabled = false;
        connectButton.disabled = true;
      } else {
        messageInputBox.disabled = true;
        sendButton.disabled = true;
        connectButton.disabled = false;
        disconnectButton.disabled = true;
      }
    }
  }

    如果通道状态已经变更为 "open", 意味着我们已经完成了在两对等节点之间建立连接。 相应地用户界面根据状态更新,许用并将输入光标聚焦在text 输入框,以便用户可以立即输入要发送给对方的文本消息, 同时界面许用 "Send" 和 "Disconnect" 按钮(既然它们已经准备好了),禁用"Connect"按钮,既然在已经建立连接的情况下用不着它。

    当连接状态变更为 "closed"时,界面执行相反的操作: 禁用文本输入框和 "Send" 按钮 , 许用"Connect" 按钮, 以便用户在需要时可以打开新的连接,禁用"Disconnect" 按钮,既然没有连接时用不着它。

    另一方面,作为我们例子的remote 节点, 则无视这些状态改变事件, 仅仅是在控制台输出它们:

function handleReceiveChannelStatusChange(event) {
    if (receiveChannel) {
      console.log("Receive channel's status has changed to " +
                  receiveChannel.readyState);
    }
  }

7.发送消息

    当用户按下 "Send" 按钮,触发我们已建立的该按钮的 click事件处理逻辑,在处理逻辑中调用sendMessage() 方法。 该方法也足够简单:

  function sendMessage() {
    var message = messageInputBox.value;
    sendChannel.send(message);
​
    messageInputBox.value = "";
    messageInputBox.focus();
  }

    send方法可以发送String,Blob,ArrayBuffer,ArrayBufferView。

8.接收消息

    当远程通道发生“message”事件时,我们的handleReceiveMessage()方法被调用来处理事件。

  function handleReceiveMessage(event) {
    var el = document.createElement("p");
    var txtNode = document.createTextNode(event.data);

    el.appendChild(txtNode);
    receiveBox.appendChild(el);
  }

二、多人画板例子

    参考 【从头到脚】WebRTC + Canvas 实现一个双人协作的共享画板

// 有省略
constructor(canvas, {moveCallback}) {
    ···
    this.moveCallback = moveCallback || function () {}; // 鼠标移动的回调
}
onmousemove(e) { // 鼠标移动
    this.isMoveCanvas = true;
    let endx = e.offsetX;
    let endy = e.offsetY;
    let width = endx - this.x;
    let height = endy - this.y;
    let now = [endx, endy]; // 当前移动到的位置
    switch (this.drawType) {
        case 'line' : {
            let params = [this.last, now, this.lineWidth, this.drawColor];
            this.moveCallback('line', ...params);
            this.line(...params);
        }
        ...
moveCallback(...arr) { // 同步到对方
    this.send(arr);
},
send(arr) { // 发送消息
    if (arr[0] === 'text') {
        ···
    } else { // 处理数据同步
        this.channel.send(JSON.stringify(arr));
    }
}

     页面收到 Callback 通知以后,直接调用 send 方法,将数据传递给对方。接收到数据后,调用封装类相应方法进行绘制。

handleChannel(channel) { // 处理 channel
    ···
    channel.onmessage = (e) => { // 收到消息 普通消息类型是 对象
        if (Array.isArray(JSON.parse(e.data))) { // 如果收到的是数组,进行结构
            let [type, ...arr] = JSON.parse(e.data);
            this.palette[type](...arr); // 调用相应方法
        } else {
            this.messageList.push(JSON.parse(e.data)); // 接收普通消息
        }
        // console.log('channel onmessage', e.data);
    };
}
```·

                

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/48499.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[ECCV2022]Language-Driven Artistic Style Transfer

标题:Language-Driven Artistic Style Transfer 链接:https://sites.cs.ucsb.edu/~william/papers/LDAST.pdf 如标题所示,本文做的是基于文本引导的风格迁移。整体的思路还是用的AST(arbitrary style transfer)那一套自编码器结构。AST的思…

期中考试【Verilog】

期中考试【Verilog】前言推荐期中考试一. 单选题(共10题)二. 填空题(共5题)三. 简答题(共3题)四. 其它(共4题)最后前言 编写于2022/11/30 13:30 以下内容源自Verilog期中试题 仅供…

Windows访问centOS的Tomcat

首先,先准备好jdk1.8和Tomcat的文件 点击此处获取jdk1.8和Tomcat的文件(提取码:xxrc) 配置IP地址 打开终端输入ifconfig,检查centOS的ip地址 根据要求,是要把ip地址最后一位改为自己的学号(前…

手把手教你做智能合约开源|多文件合约开源|引用文件开源

本文手把手教你使用 区块链浏览器 验证智能合约的三种方式。 验证单一 Solidity 文件 在开始验证之前,我们需要首先部署智能合约。进入 Remix IDE,创建一个合约新文件。复制粘贴下面的代码: // SPDX-License-Identifier: MITpragma solidit…

夜曲编程Python体验课

目录 day1 编程中的“文本” 代码规范 打印数字 打印字符串 注释 总结思维导图 day2 变量与赋值 变量 常量 赋值 格式化输出 转义字符: 总结思维导图 day3 编程中的“数字” 整形 浮点型 运算符 四种常见的四则运算符( - * / &…

【软件测试】测试人的我们,咋做一个如鱼得水的测试员?

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 一千个人&#xff0…

短视频创作,主动变现和被动变现方式详解,建议收藏反复阅读-下

同样先说纲要,有兴趣可以继续看下去,上一篇讨论了抖音变现的有三个建议,①变现标准低、②变现天花板高、③可主动变现。 这一篇的内容只要是抖音上被动和主动两类变现方式,涉及了直播打赏,广告接单,视频带货…

小啊呜产品读书笔记001:《邱岳的产品手记-15》第28讲 产品分析的套路(上):谁是利益相关者? 29讲产品分析的套路(中):解决什么问题?

小啊呜产品读书笔记001:《邱岳的产品手记-15》第28讲 产品分析的套路(上):谁是利益相关者?& 29讲产品分析的套路(中):解决什么问题? 一、今日阅读计划二、泛读&知…

【Big Data】Hadoop--MapReduce经典题型实战(单词统计+成绩排序+文档倒插序列+每月Top3温度)

🍊本文使用了4个经典案例进行MapReduce实战 🍊参考官方源码,代码风格较为优雅 🍊解析详细 一、Introduction MapReduce是一个分布式运算程序的编程框架,核心功能是将用户写的业务逻辑代码和自身默认代码整合成一个完整…

vue+videojs视频播放、视频切换、视频断点分段上传

“本次需求是做一个视频列表,点击视频列表播放对应视频;同时要求实现断点分段上传大文件(视频)的功能 。 videojs文档:Getting Started with Video.js - Video.js: The Player Framework | Video.js 断点续传组件地址…

WebRTC学习笔记六 兼容性 adapter.js

一、adapter.js发展背景 adapter.js自2012年底或者2013年初WebRTC早期的时候就已经出现了。它最初是Google的apprtc demo的一部分。原始版本仍可在Chrome tree中找到。它是一个非常小的项目,还没有150行。主要功能是隐藏像webkitRTCPeerConnection和mozRTCPeerConne…

Spring Boot+Mybatis:实现数据库登录注册与两种properties配置参数读取

〇、参考资料 1、hutool介绍 https://blog.csdn.net/abst122/article/details/124091375 2、Spring BootMybatis实现登录注册 https://www.cnblogs.com/wiki918/p/16221758.html 3、Spring Boot读取自定义配置文件 https://www.yisu.com/zixun/366877.html 4、Spring Boot读取p…

医院用故障电弧探测器AAFD 安科瑞 时丽花

摘 要: 医院运行中对于用电方面的要求越来越高,为了更好地体现用电价值,首先应该确保用电的安全性,尤其是对 于越来越繁杂的医院用电系统。基于此,在未来医院用电过程中应该加大关注力度,切实做好相关管理工…

Compose学习-> Text()

设置文本:text xxx 直接设置 Text(text "我是一个Text")引用资源文件:stringResource Text(text stringResource(id R.string.string_text))设置字体颜色:color xxx 引用系统自带的颜色 Text(text "我是一个Text"…

【技术分享】NB860+Lierda云平台=上电即上云——云管端协作让万物互联更简单(二)

随着物联网行业的快速发展,越来越多的物联网云服务平台涌现。如何快速实现应用开发,如何管理,如何让设备快速上云,成为关注的焦点。 第一期中我们介绍了基于MQTT协议快速接入利尔达物联网全连接云平台,本期我们将介绍如…

ManageEngine 第六次入选 Gartner® 安全信息和事件管理魔力象限™!

今天,我们很高兴地宣布,ManageEngine 已在2022年 Gartner 安全信息和事件管理 (SIEM) 魔力象限中获得认可,今年已经是其连续第六次出现在Gartner中。ManageEngine非常高兴再次获得这一认可。 在过去两年中,互联网向云计算的转变不…

svn的常规使用

svn的常规使用svn的常规使用1 客户端2 svn server3 qt使用svn4 svn项目迁移svn的常规使用 1 客户端 下载地址:官网,中文简体语言包在其下方 分别安装客户端可语言包,在安装语言包的时候勾选应用,svn便可变成中文了,或…

改革后IB数学该如何选?

IB数学,作为一个IB课程里必选科目,让无数IB学霸为之自豪,他们能解出外教都不会做的题。另一方面,也让很多同学(自称“学渣”)避之不及。 从2019年起,IB数学教学大纲发生重大改革。▲图源&#x…

Android -- 每日一问:如何理解 Android 中的 Context,它有什么用?

经典回答 官方文档对于 Context 的解释: Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and cla…

[附源码]SSM计算机毕业设计学生宿舍设备报修JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…