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


    1 背景

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

    2 具体操作

    2.1 操作流程

    2.2 测试效果

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

    3 前端代码

    1. <html>
    2. <head>
    3. <title>webclient p2p demotitle>
    4. <meta charset="utf-8">
    5. <style>
    6. .left_part {
    7. width: 50%;
    8. float: left;
    9. }
    10. .right_part {
    11. width: 50%;
    12. float: right;
    13. overflow-y: scroll;
    14. }
    15. style>
    16. <script src="https://code.jquery.com/jquery-3.6.0.min.js">script>
    17. head>
    18. <body>
    19. <div class="right_part" id="left_part_container">
    20. <div>
    21. SignalServer:
    22. <input type="text" id="signal_url" value="127.0.0.1:8888">
    23. <button id="btn_sign_in">登入button>
    24. <button id="btn_sign_out">登出button><br>
    25. <input type="text" id="selected_peerid_for_p2p" disabled value="不允许修改的文本">
    26. <button id="btn_start_p2p" disabled>start_p2pbutton>
    27. div>
    28. <br>
    29. <table id="PeersTable">
    30. <thead>
    31. <tr>
    32. <th>Nameth>
    33. <th>PeerIdth>
    34. <th>Statusth>
    35. tr>
    36. thead>
    37. table>
    38. div>
    39. <div class="left_part" id="left_part_container">
    40. <video controls autoplay id="rtc_video_play" height="500" style="width:100%">video>
    41. div>
    42. <script type="text/javascript">
    43. var myselfPeerId = -1;
    44. var pc = new RTCPeerConnection({ "offerExtmapAllowMixed": false });
    45. var datachannel = null;
    46. var stream = new MediaStream();
    47. async function initPC() {
    48. pc.addTransceiver("audio", {direction: "recvonly"});
    49. pc.addTransceiver("video", {direction: "recvonly"});
    50. pc.onconnectionstatechange = function(event){
    51. console.log("connection state change: ", pc.connectionState);
    52. };
    53. pc.onicecandidate = async (ev) => {
    54. console.log('=======>' + JSON.stringify(ev.candidate));
    55. };
    56. pc.ontrack = function(event) {
    57. stream.addTrack(event.track);
    58. };
    59. datachannel = pc.createDataChannel('chat');
    60. datachannel.onopen = function(event) {
    61. console.log("datachannel onopen: ", event.data);
    62. }
    63. datachannel.onmessage = function(event) {
    64. console.log("receive message: ", event.data);
    65. }
    66. datachannel.onerror = function(event) {
    67. console.log("datachannel error: ", event.data);
    68. }
    69. datachannel.onclose = function(event) {
    70. console.log("datachannel close: ");
    71. }
    72. }
    73. async function startP2P(signal_url) {
    74. initPC();
    75. var offer = await pc.createOffer();
    76. await pc.setLocalDescription(offer);
    77. let sendOfferPromise = await fetch(signal_url, {
    78. "method": "POST",
    79. "body": JSON.stringify(offer)
    80. });
    81. if (sendOfferPromise.ok) {
    82. console.log("send offer: " + JSON.stringify(offer));
    83. } else {
    84. alert("HTTP-Error: " + sendOfferPromise.status);
    85. }
    86. }
    87. async function nfyFromSignal(nfyPromise) {
    88. let nfyString = await nfyPromise.text();
    89. if (nfyString.includes("answer")) {
    90. console.log("receive answer: " + nfyString);
    91. pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(nfyString)));
    92. } else if (nfyString.includes("candidate")) {
    93. console.log("receive candidate: " + nfyString);
    94. pc.addIceCandidate(new RTCIceCandidate(JSON.parse(nfyString)));
    95. } else {
    96. let peersString = nfyString;
    97. // console.log("rsp: ", peersString)
    98. let peersChunk = peersString.split("\n");
    99. for (let i=0; ilength && peersChunk[i].length>0; ++i) {
    100. const peerColumns = peersChunk[i].split(",");
    101. // console.log("index: " + i + ", data: " + peerColumns)
    102. // for example: kevin@home-pc,36,1
    103. // peerColumns[0]: peer_name
    104. // peerColumns[1]: peer_id
    105. // peerColumns[2]: peer_status
    106. // table's column index starts from 1, not 0
    107. const row_find_peer_id = $("#PeersTable tr:has(td:nth-child(2):contains('" + peerColumns[1] + "'))");
    108. if (row_find_peer_id.length > 0) {
    109. console.log("peerid:" + peerColumns[1] + ", status change from " + row_find_peer_id.find('td:nth-child(3)').text() + " to " + peerColumns[2]);
    110. row_find_peer_id.find('td:nth-child(3)').text(peerColumns[2]);
    111. continue;
    112. }
    113. const row_find_peer_name = $("#PeersTable tr:has(td:nth-child(1):contains('" + peerColumns[0] + "'))");
    114. if (row_find_peer_name.length > 0) {
    115. console.log("peerid:" + peerColumns[1] + ", status change from " + row_find_peer_name.find('td:nth-child(3)').text() + " to " + peerColumns[2]);
    116. row_find_peer_name.find('td:nth-child(2)').text(peerColumns[1]);
    117. row_find_peer_name.find('td:nth-child(3)').text(peerColumns[2]);
    118. continue;
    119. }
    120. const row_peer = $("");
    121. row_peer.append($("").text(peerColumns[0]));
    122. row_peer.append($("").text(peerColumns[1]));
    123. row_peer.append($("").text(peerColumns[2]));
    124. $("#PeersTable").append(row_peer);
    125. }
    126. }
    127. }
    128. async function pendingWait(myself_peerid) {
    129. const signal_url = document.getElementById("signal_url").value;
    130. while (true) {
    131. let v = await fetch(`http://${signal_url}/wait?peer_id=${myself_peerid}`);
    132. nfyFromSignal(v);
    133. }
    134. }
    135. $('#btn_sign_in').on('click', async () => {
    136. const signal_url = document.getElementById("signal_url").value;
    137. let signinResultPromise = await fetch(`http://${signal_url}/sign_in`);
    138. if (signinResultPromise.ok) {
    139. myselfPeerId = parseInt(signinResultPromise.headers.get("Pragma"));
    140. console.log("my peerid is: " + myselfPeerId);
    141. nfyFromSignal(signinResultPromise);
    142. pendingWait(myselfPeerId);
    143. } else {
    144. alert("HTTP-Error: " + signinResultPromise.status);
    145. }
    146. })
    147. $('#btn_sign_out').on('click', async () => {
    148. $("#PeersTable tbody").empty();
    149. const signal_url = document.getElementById("signal_url").value;
    150. let signoutResultPromise = await fetch(`http://${signal_url}/sign_out?peer_id=${myselfPeerId}`);
    151. if (signoutResultPromise.ok) {
    152. console.log("sign_out: " + myselfPeerId + " successful");
    153. } else {
    154. alert("HTTP-Error: " + signoutResultPromise.status);
    155. }
    156. })
    157. $('#PeersTable').on('click', 'tr', function() {
    158. const row_selected = $(this);
    159. const row_selected_peer_id = parseInt(row_selected.find('td:nth-child(2)').text());
    160. if (row_selected_peer_id === myselfPeerId) {
    161. console.log("You should not choose yourself [" + myselfPeerId + "] to start p2p");
    162. $("#btn_start_p2p").prop("disabled", true);
    163. return;
    164. }
    165. const row_selected_peer_id_status = parseInt(row_selected.find('td:nth-child(3)').text());
    166. if (row_selected_peer_id_status === 1) {
    167. console.log("selected peerid: " + row_selected_peer_id);
    168. $('#selected_peerid_for_p2p').val(row_selected_peer_id);
    169. $("#btn_start_p2p").prop("disabled", false);
    170. } else {
    171. console.log("The peer [" + row_selected_peer_id + "] you choose is offline");
    172. $("#btn_start_p2p").prop("disabled", true);
    173. }
    174. })
    175. $('#btn_start_p2p').on('click', async () => {
    176. const signal_url = document.getElementById("signal_url").value;
    177. const remote_peer_id = $('#selected_peerid_for_p2p').val();
    178. const sendmsg_url = `http://${signal_url}/message?peer_id=${myselfPeerId}&to=${remote_peer_id}`;
    179. console.log("sendmsg url: " + sendmsg_url);
    180. // $('#rtc_video_play').show();
    181. // $('#rtc_video_play').prop('muted', false);
    182. $('#rtc_video_play').prop('srcObject', stream);
    183. console.log("Start P2P from [" + myselfPeerId + "] to [" + remote_peer_id + "]");
    184. startP2P(sendmsg_url);
    185. })
    186. script>
    187. body>
    188. html>

  • 相关阅读:
    R语言时间序列数据算术运算:使用diff函数计算时间序列数据的逐次差分、使用时间序列之间的除法计算相对变化率(乘以100获得百分比)
    Linux | 信号
    11 个最值得推荐的 Windows 数据恢复软件
    西门子S7-1500作为智能设备共享功能
    IP地址的分类,五分类编制CIDR以及子网的划分和子网掩码
    前端高频面试问题
    报式套接字通讯实例
    c++之类与对象
    C语言源代码系列-管理系统之学生选修课程系统
    【frp】cron定时检查zfrpc.service是否启动成功
  • 原文地址:https://blog.csdn.net/hclbeloved/article/details/132810159