如何用HTML5实现双人会议式摄像头收发?连接关闭问题排查
问题
我参考Tutorial Point的代码片段,尝试实现类似双人会议的HTML5摄像头收发功能,但连接总是自动关闭。在单台电脑上测试本地收发时发现:代码绑定一个端口后接收端也绑定同一端口;若不绑定同一端口,发送端又缺少目标端口定义。我尝试了123、80、10000端口,且已通过gpedit的IP安全策略允许这些端口,但仍提示连接关闭。
代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content= "HTML Tidy for Linux (vers 25 March 2009), see www.w3.org" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js" type= "text/javascript"> </script> <script type="text/javascript"> </script> <title>webpage</title> <style type="text/css"> /*<![CDATA[*/ body.c2 {background-color:black;text-align:center} div.c1 {position:absolute;} /*]]>*/ </style> </head> <body class="c2"> <div id="d4" class="c1"> <p><input type="button" id="stop" onclick="stop()" /> Stop Cam <input type="button" id="start" onclick="start()" /> Start Cam <input type="button" id="run" onclick= "WebSocketTest()" /> Start Cam</p> </div><script type="text/javascript"> //<![CDATA[ function drawImge(){ var video = document.querySelector("#video"); var canvas = document.querySelector("#videoCanvas"); var ctx = canvas.getContext('2d'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; ctx.drawImage(video, 0, 0, canvas.width, canvas.height); var faceArea = 300; var pX=canvas.width/2 - faceArea/2; var pY=canvas.height/2 - faceArea/2; ctx.rect(pX,pY,faceArea,faceArea); ctx.lineWidth = "2"; ctx.strokeStyle = "green"; ctx.stroke(); setTimeout(drawImge , 100); } var video = document.querySelector("#video"); video.onplay = function() { setTimeout(drawImge , 300); }; var stop = function () { var stream = video.srcObject; var tracks = stream.getTracks(); for (var i = 0; i < tracks.length; i++) { var track = tracks[i]; track.stop(); } video.srcObject = null; } var start = function () { var video = document.getElementById('video'), vendorUrl = window.URL || window.webkitURL; if (navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia({ video: true }) .then(function (stream) { video.srcObject = stream; if ("WebSocket" in window) { alert("WebSocket is supported by your Browser!"); // Let us open a web socket var ws = new WebSocket("ws://127.0.0.1:123/echo"); var wss = new WebSocket("ws://127.0.0.1:80/echo"); wss.onopen = function() { // Web Socket is connected, send data using send() wss.send(stream); }; wss.onmessage = function (evt) { var received_msg = evt.data; }; wss.onclose = function() { // websocket is closed. alert("Connection is closed..."); }; } else { // The browser doesn't support WebSocket alert("WebSocket NOT supported by your Browser!"); } }).catch(function (error) { console.log("Something went wrong!"); }); } } $(function () { start(); }); var WebSocketTest = function () { if ("WebSocket" in window) { alert("WebSocket is supported by your Browser!"); // Let us open a web socket var ws = new WebSocket("ws://127.0.0.1:123/echo"); ws.onopen = function() { // Web Socket is connected, send data using send() ws.send("Message to send"); alert("Message is sent..."); }; ws.onmessage = function (evt) { var received_msg = evt.data; alert("Message is received..."); }; ws.onclose = function() { // websocket is closed. alert("Connection is closed..."); }; } else { // The browser doesn't support WebSocket alert("WebSocket NOT supported by your Browser!"); } } $(function () { WebSocketTest(); }); //]]> </script> </body> </html>
解决方案
核心问题分析
- 缺少WebSocket服务端:代码仅实现了WebSocket客户端,但没有对应服务端监听指定端口。浏览器发起连接后无服务端响应,连接会直接关闭。
- 媒体流传输方式错误:直接用
wss.send(stream)发送MediaStream对象无效,WebSocket无法直接传输原始媒体流,需借助WebRTC的RTCPeerConnection实现点对点音视频传输,WebSocket仅用于交换信令(如SDP、ICE候选)。 - 端口逻辑混乱:本地测试无需绑定多个端口,WebRTC是点对点连接,WebSocket作为信令通道只需一个服务端端口即可。
修复步骤
搭建WebSocket服务端
用Node.js快速实现简单信令服务(先安装ws包:npm install ws):const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', (ws) => { ws.on('message', (data) => { // 转发信令给其他在线客户端 wss.clients.forEach((client) => { if (client !== ws && client.readyState === WebSocket.OPEN) { client.send(data); } }); }); });启动服务后,客户端统一连接
ws://127.0.0.1:8080。改用WebRTC实现音视频传输
替换原WebSocket传输媒体流的逻辑:- 客户端通过WebSocket交换SDP Offer/Answer和ICE候选信息
- 创建RTCPeerConnection实例,将本地摄像头流添加到连接中,远端流渲染到video标签展示
修正端口使用
所有客户端连接同一个WebSocket服务端端口(如8080),WebRTC会自动协商点对点传输的媒体端口,无需手动指定多个端口。
关键注意事项
- 本地测试时,确保WebSocket服务端正常运行,可通过浏览器控制台(F12→网络→WebSocket)查看连接错误详情
- WebRTC在localhost环境下无需HTTPS,但生产环境必须使用HTTPS
- 避免使用系统保留端口(如80、123),选择1024以上的非知名端口(如8080、3000)
内容的提问来源于stack exchange,提问作者Ho Yeung - Lee-Maiva
相关产品推荐
相关产品推荐

