webrtc-m79-测试peerconnectionserver的webclient-p2p-demo

1 背景

webrtc的代码中有peerconnectionclient和peerconnectionserver的例子,但是没有对应的web端的例子,这里简单的写了一个测试例子,具体如下:

2 具体操作

2.1 操作流程

2.2 测试效果

使用webclient与peerconnectionclient的测试效果如下:

3 前端代码

<html>
<head><title>webclient p2p demo</title><meta charset="utf-8"><style>.left_part {width: 50%;float: left;}.right_part {width: 50%;float: right;overflow-y: scroll;}</style><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head><body><div class="right_part" id="left_part_container"><div>SignalServer:<input type="text" id="signal_url" value="127.0.0.1:8888"><button id="btn_sign_in">登入</button><button id="btn_sign_out">登出</button><br><input type="text" id="selected_peerid_for_p2p" disabled value="不允许修改的文本"><button id="btn_start_p2p" disabled>start_p2p</button></div><br><table id="PeersTable"><thead><tr><th>Name</th><th>PeerId</th><th>Status</th></tr></thead></table></div><div class="left_part" id="left_part_container"><video controls autoplay id="rtc_video_play" height="500" style="width:100%"></video></div><script type="text/javascript">var myselfPeerId = -1;var pc = new RTCPeerConnection({ "offerExtmapAllowMixed": false });var datachannel = null;var stream = new MediaStream();async function initPC() {pc.addTransceiver("audio", {direction: "recvonly"});pc.addTransceiver("video", {direction: "recvonly"});pc.onconnectionstatechange = function(event){console.log("connection state change: ", pc.connectionState);};pc.onicecandidate = async (ev) => {console.log('=======>' + JSON.stringify(ev.candidate));        };pc.ontrack = function(event) {stream.addTrack(event.track);                         };datachannel = pc.createDataChannel('chat');datachannel.onopen = function(event) {console.log("datachannel onopen: ", event.data);}datachannel.onmessage = function(event) {console.log("receive message: ", event.data);}datachannel.onerror = function(event) {console.log("datachannel error: ", event.data);}datachannel.onclose = function(event) {console.log("datachannel close: ");}                    }async function startP2P(signal_url) {initPC();var offer = await pc.createOffer();await pc.setLocalDescription(offer);let sendOfferPromise = await fetch(signal_url, {"method": "POST","body": JSON.stringify(offer)});if (sendOfferPromise.ok) {console.log("send offer: " + JSON.stringify(offer));                         } else {alert("HTTP-Error: " + sendOfferPromise.status);}               }   async function nfyFromSignal(nfyPromise) {let nfyString = await nfyPromise.text();if (nfyString.includes("answer")) {console.log("receive answer: " + nfyString);pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(nfyString)));} else if (nfyString.includes("candidate")) {console.log("receive candidate: " + nfyString);pc.addIceCandidate(new RTCIceCandidate(JSON.parse(nfyString)));} else {let peersString = nfyString;// console.log("rsp: ", peersString)let peersChunk = peersString.split("\n");for (let i=0; i<peersChunk.length && peersChunk[i].length>0; ++i) {const peerColumns = peersChunk[i].split(",");// console.log("index: " + i + ", data: " + peerColumns)// for example: kevin@home-pc,36,1// peerColumns[0]: peer_name// peerColumns[1]: peer_id// peerColumns[2]: peer_status// table's column index starts from 1, not 0const row_find_peer_id = $("#PeersTable tr:has(td:nth-child(2):contains('" + peerColumns[1] + "'))");if (row_find_peer_id.length > 0) {console.log("peerid:" + peerColumns[1] + ", status change from " + row_find_peer_id.find('td:nth-child(3)').text() + " to " + peerColumns[2]);row_find_peer_id.find('td:nth-child(3)').text(peerColumns[2]);continue;}const row_find_peer_name = $("#PeersTable tr:has(td:nth-child(1):contains('" + peerColumns[0] + "'))");if (row_find_peer_name.length > 0) {console.log("peerid:" + peerColumns[1] + ", status change from " + row_find_peer_name.find('td:nth-child(3)').text() + " to " + peerColumns[2]);row_find_peer_name.find('td:nth-child(2)').text(peerColumns[1]);row_find_peer_name.find('td:nth-child(3)').text(peerColumns[2]);continue;}                  const row_peer = $("<tr>");row_peer.append($("<td>").text(peerColumns[0]));row_peer.append($("<td>").text(peerColumns[1]));row_peer.append($("<td>").text(peerColumns[2]));$("#PeersTable").append(row_peer);}                }}async function pendingWait(myself_peerid) {const signal_url = document.getElementById("signal_url").value;while (true) {let v = await fetch(`http://${signal_url}/wait?peer_id=${myself_peerid}`);nfyFromSignal(v);}}$('#btn_sign_in').on('click', async () => {const signal_url = document.getElementById("signal_url").value;let signinResultPromise = await fetch(`http://${signal_url}/sign_in`);if (signinResultPromise.ok) {myselfPeerId = parseInt(signinResultPromise.headers.get("Pragma"));console.log("my peerid is: " + myselfPeerId);nfyFromSignal(signinResultPromise);pendingWait(myselfPeerId);               } else {alert("HTTP-Error: " + signinResultPromise.status);}})        $('#btn_sign_out').on('click', async () => {$("#PeersTable tbody").empty();const signal_url = document.getElementById("signal_url").value;let signoutResultPromise = await fetch(`http://${signal_url}/sign_out?peer_id=${myselfPeerId}`);if (signoutResultPromise.ok) {console.log("sign_out: " + myselfPeerId + " successful");       } else {alert("HTTP-Error: " + signoutResultPromise.status);}})$('#PeersTable').on('click', 'tr', function() {const row_selected = $(this);const row_selected_peer_id = parseInt(row_selected.find('td:nth-child(2)').text());if (row_selected_peer_id === myselfPeerId) {console.log("You should not choose yourself [" + myselfPeerId + "] to start p2p");$("#btn_start_p2p").prop("disabled", true);return;}const row_selected_peer_id_status = parseInt(row_selected.find('td:nth-child(3)').text());if (row_selected_peer_id_status === 1) {console.log("selected peerid: " + row_selected_peer_id);$('#selected_peerid_for_p2p').val(row_selected_peer_id);$("#btn_start_p2p").prop("disabled", false);                } else {console.log("The peer [" + row_selected_peer_id + "] you choose is offline");$("#btn_start_p2p").prop("disabled", true);}})$('#btn_start_p2p').on('click', async () => {const signal_url = document.getElementById("signal_url").value;const remote_peer_id = $('#selected_peerid_for_p2p').val();const sendmsg_url = `http://${signal_url}/message?peer_id=${myselfPeerId}&to=${remote_peer_id}`;console.log("sendmsg url: " + sendmsg_url);// $('#rtc_video_play').show();// $('#rtc_video_play').prop('muted', false);$('#rtc_video_play').prop('srcObject', stream);console.log("Start P2P from [" + myselfPeerId + "] to [" + remote_peer_id + "]");startP2P(sendmsg_url);})</script>
</body>
</html>

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

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

相关文章

算法 数据结构 双向环形链表 手撸环形链表 环形链表实现容器 环形链表添加修改删除获取大小 环形链表实现自定义容器 手撸容器 双向环形哨兵链表 数据结构(六)

1. 环形链表&#xff1a; 2. 建议先不要看我写得自己先实现下&#xff0c;只将Node内部类复制自己命名得容器内&#xff0c; 实现方法&#xff1a; a. add方法&#xff08;添加到头部&#xff0c;尾部添加&#xff0c;指定位置添加&#xff09; b. get方法&#xff08;获取首部…

HBASE知识点

HBASE是什么&#xff1f; 高可靠、高性能、面向列、可伸缩、实时读写的分布式数据库。利用HDFS作为其文件存储系统&#xff0c;利用MapReduce来处理HBase中的海量数据。利用Zookeeper作为其分布式协同服务。用于存储非结构化和半结构化的松散数据。 HBase数据模型 RowKey: 唯…

Java“牵手”拼多多商品详情数据,拼多多商品详情接口,拼多多API接口申请指南

拼多多商品详情API接口的作用是获取拼多多平台上某个商品的详细信息&#xff0c;包括商品标题、价格、图片、规格、参数、店铺信息等。 开发者可以通过该接口获取到商品的原始数据&#xff0c;方便进行数据分析、价格比较、爬取等操作。通过该接口获取到的商品详情数据可以结合…

flink命令行提交jar包任务

1. 环境准备 1.1 flink环境准备 关于如何安装flink&#xff0c;这个写的非常详细&#xff0c;https://blog.csdn.net/qq_43699958/article/details/132826440 在flink的bin目录启动flink cluster [rootlocalhost bin]# ./start-cluster.sh1.2 Linux环境准备 1.2.1 关闭linu…

43.MQ—RabbitMQ

目录 一、MQ—RabbitMQ。 &#xff08;1&#xff09;同步调用与异步调用。 &#xff08;1.1&#xff09;同步调用。 &#xff08;1.2&#xff09;异步调用。 &#xff08;2&#xff09;MQ之间的区别。 &#xff08;3&#xff09;RabbitMQ学习。 &#xff08;3.1&#xf…

一文读懂:苹果手机怎么录屏?

“刚买的苹果14&#xff0c;最近需要用来录屏&#xff0c;找了很久都没找到&#xff0c;朋友说苹果手机没有录屏功能&#xff0c;可是我半信半疑&#xff0c;花了这么多钱买的&#xff0c;怎么可能没有录屏功能呢&#xff0c;有人知道苹果手机怎么录屏吗&#xff1f;” 苹果手…

骨传导耳机对大脑有影响吗?骨传导耳机到底好不好

先上结论&#xff0c;骨传导耳机对大脑没有影响。骨传导耳机使用的是骨传导技术&#xff0c;声音是通过头骨骨头和颌骨给内耳传递的&#xff0c;而不是通过传统的空气传播&#xff0c;它将声音传输到颅骨&#xff0c;然后透过骨头振动直接刺激内耳&#xff0c;绕过外耳和中耳。…

C#,《小白学程序》第十五课:随机数(Random)第二,统计学初步,数据统计的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十五课&#xff1a;随机数&#xff08;Random&#xff09;第二&#xff0c;统计学初步&#xff0c;数据统计的计算方法与代码 /// 用随机数做简单的统计并用图形显示统计结果。 /// </summary> /// <param name&q…

数电课程设计——课设一:加减计数器

为了帮助大家更好学习FPGA硬件语言&#xff0c;创立此资源 包含文件有&#xff1a;实验报告、仿真文件&#xff0c;资料很全&#xff0c;有问题可以私信 一、实验内容 1、利用QuartusII和Modelsim实现100进制可逆计数器编码显示实验。 二、实验步骤 &#xff08;1&#xff…

CentOS 7 openssl 3.0.10 rpm包制作 —— 筑梦之路

源码下载地址&#xff1a; https://www.openssl.org/source/openssl-3.0.10.tar.gz 编写spec文件&#xff1a; cat << EOF > openssl.specSummary: OpenSSL 3.0.10 for CentosName: opensslVersion: %{?version}%{!?version:3.0.10}Release: 1%{?dist}Obsoletes…

企业可以自己建立大数据平台吗?有哪些好处?

随着企业的快速发展&#xff0c;企业累积了越来越多的数据&#xff0c;但管理巨量的大数据是一件非常难的事情&#xff0c;且很多数据没有充分发挥作用。因此不少企业在问&#xff0c;企业可以自己建立大数据平台吗&#xff1f;有哪些好处&#xff1f; 企业可以自己建立大数据…

vue 验证码 图片点击

实现登陆验证 图片依次点击功能 demo &#xff0c;上图可以根据demo修改&#xff0c;直接拿用 <template><div><div class"big-box" id"BigBox" :style"background-image:url( imgCodeUrl )"><div class"click-box…

最新IDE流行度最新排名(每月更新)

2023年09月IDE流行度最新排名 顶级IDE排名是通过分析在谷歌上搜索IDE下载页面的频率而创建的 一个IDE被搜索的次数越多&#xff0c;这个IDE就被认为越受欢迎。原始数据来自谷歌Trends 如果您相信集体智慧&#xff0c;Top IDE索引可以帮助您决定在软件开发项目中使用哪个IDE …

python开发之个微机器人的二次开发

简要描述&#xff1a; 取消消息接收 请求URL&#xff1a; http://域名地址/cancelHttpCallbackUrl 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/json 参数&#xff1a; 参数名类型说明codestring1000成功&#xff0c;1…

水循环原理VR实景教学课件开发

日本核污水排海让人们越来越重视海洋大气层水循环的安全&#xff0c;水循环是一个周而复始、循环往复的动态过程&#xff0c;为了将水循环过程以形象、生动地形式展示出来&#xff0c;水循环VR全景动态演示逐渐受到大家青睐。 传统的水循环教育方式通常是通过图片、动画或实地考…

MySql安装包配置

电脑重配过多次&#xff0c;此为mysql安装记录贴&#xff0c;方便查阅 从官网下载的安装包进行本地配置 下载地址 解压下载下来的zip压缩包 解压出来的文件中新增配置my.ini文件 [mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录 basedirD:\\software\\package\\M…

Adobe Acrobat Reader界面改版 - 解决方案

问题 日期&#xff1a;2023年9月 Adobe Acrobat Reader下文简称Adobe PDF Reader&#xff0c;此软件会自动进行更新&#xff0c;当版本更新至2023.003.20284版本后。 软件UI界面会大改版&#xff1a;书签页变成了右边、工具栏变到了左边、缩放按钮变到了右下角&#xff0c;如…

通过curl命令分析http接口请求各阶段的耗时等

目录 一、介绍二、功能1、-v 输出请求 响应头状态码 响应文本等信息2、-x 测试代理ip是否能在该网站使用3、-w 额外输出查看接口请求响应的消耗时间4、-o 将响应结果存储到文件里面5、-X post请求测试 (没测成功用的不多) 一、介绍 Curl是一个用于发送和接收请求的命令行工具和…

【LeetCode-简单题】977. 有序数组的平方

文章目录 题目方法一&#xff1a;双指针方法二&#xff1a; 题目 方法一&#xff1a;双指针 class Solution { // 方法一 &#xff1a;双指针public int[] sortedSquares(int[] nums) {int left 0;int right nums.length -1 ;int[] res new int[nums.length];//结果集新数组…

中金支付-对账文件接受base64后保存文件

前后接口不太清楚。 通过别人的对接沟通过程中看到这个问题&#xff0c;简单尝试成功后做个记录。 接口返回内容为Base64&#xff0c;那么先进行解码base64_decode。 解码后内容截图如下&#xff1a; 大概能看出来里面含有csv文件&#xff0c;且接口中说明&#xff1a;对账文件…