这篇文章主要参考了 Webrtc WebSocket实现音视频通讯,非常感谢提供代码

前端部分完全是从这篇文章复制过来的,只是修改了webscket的url,还有加入了webrtc-adapterjs,至于做什么,可以点击链接进行了解

前端代码部分(主要来自开头提及的博文)

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
Welcome<br/><input id="text" type="text" />
<button onclick="send()">发送消息</button>
<hr/>
<button onclick="closeWebSocket()">关闭WebSocket连接</button>
<hr/>
<div id="message"></div> <video id="vid1" width="320" height="240" autoplay></video>
<video id="vid2" width="320" height="240" autoplay></video><br>
<a id="create" href="webrtc.html#true" onclick="init()">点击此链接新建聊天室</a><br>
<p id="tips" style="background-color:red">请在其他浏览器中打开:http://此电脑 加入此视频聊天</p> <script type="text/javascript" src="http://cdn.staticfile.org/webrtc-adapter/zv4.1.1/adapter.min.js"></script>
<script type="text/javascript">
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia; var isCaller = window.location.href.split('#')[1];
var websocket = null;
//判断当前浏览器是否支持WebSocket
if('WebSocket' in window) {
websocket = new WebSocket("ws://192.168.31.175:8181");
} else {
alert('当前浏览器 Not support websocket')
} //连接发生错误的回调方法
websocket.onerror = function() {
setMessageInnerHTML("WebSocket连接发生错误");
}; //连接成功建立的回调方法
websocket.onopen = function() {
setMessageInnerHTML("WebSocket连接成功");
} // 创建PeerConnection实例 (参数为null则没有iceserver,即使没有stunserver和turnserver,仍可在局域网下通讯)
var pc = new window.RTCPeerConnection(null); // 发送ICE候选到其他客户端
pc.onicecandidate = function(event) {
setMessageInnerHTML("我看看 1");
if(event.candidate !== null) {
setMessageInnerHTML("我看看 2");
websocket.send(JSON.stringify({
"event": "_ice_candidate",
"data": {
"candidate": event.candidate
}
}));
}
}; //接收到消息的回调方法
websocket.onmessage = function(event) {
setMessageInnerHTML("接收到的信息");
setMessageInnerHTML(event.data);
if(event.data == "new user") {
console.log("new user");
location.reload();
} else {
var json = JSON.parse(event.data);
console.log('onmessage: ', json);
//如果是一个ICE的候选,则将其加入到PeerConnection中,否则设定对方的session描述为传递过来的描述
if(json.event === "_ice_candidate") {
pc.addIceCandidate(new RTCIceCandidate(json.data.candidate));
} else {
pc.setRemoteDescription(new RTCSessionDescription(json.data.sdp));
// 如果是一个offer,那么需要回复一个answer
if(json.event === "_offer") {
pc.createAnswer(sendAnswerFn, function(error) {
console.log('Failure callback: ' + error);
});
}
}
}
} //连接关闭的回调方法
websocket.onclose = function() {
setMessageInnerHTML("WebSocket连接关闭");
} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
closeWebSocket();
} //将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
} //关闭WebSocket连接
function closeWebSocket() {
websocket.close();
} //发送消息
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
} // stun和turn服务器
var iceServer = {
"iceServers": [{
"url": "stun:stunserver.org"
}, {
"url": "turn:numb.viagenie.ca",
"username": "webrtc@live.com",
"credential": "muazkh"
}]
}; // 如果检测到媒体流连接到本地,将其绑定到一个video标签上输出
pc.onaddstream = function(event) {
document.getElementById('vid2').src = URL.createObjectURL(event.stream);
}; // 发送offer和answer的函数,发送本地session描述
var sendOfferFn = function(desc) {
pc.setLocalDescription(desc);
websocket.send(JSON.stringify({
"event": "_offer",
"data": {
"sdp": desc
}
}));
},
sendAnswerFn = function(desc) {
pc.setLocalDescription(desc);
websocket.send(JSON.stringify({
"event": "_answer",
"data": {
"sdp": desc
}
}));
}; // 获取本地音频和视频流
navigator.getUserMedia({
"audio": true,
"video": true
},
function(stream) {
//绑定本地媒体流到video标签用于输出
document.getElementById('vid1').src = URL.createObjectURL(stream);
document.getElementById('vid1').muted = true;
//向PeerConnection中加入需要发送的流
pc.addStream(stream);
//如果是发起方则发送一个offer信令
if(isCaller) {
pc.createOffer(sendOfferFn, function(error) {
console.log('Failure callback: ' + error);
});
}
},
function(error) {
//处理媒体流创建失败错误
console.log('getUserMedia error: ' + error);
}); window.onload = function() {
if(isCaller == null || isCaller == undefined) {
var tips = document.getElementById("tips");
tips.remove();
} else {
var create = document.getElementById("create");
create.remove();
}
}; function init() {
location.reload();
}
</script> </body> </html>

提及博文的java部分,我用了.net 控制台程序简单实现了一个,相当于一个极简的信令服务器吧(Fleck 可以在vs的管理nuget程序包中获得)

static void Main(string[] args)
{
//客户端url以及其对应的Socket对象字典
IDictionary<string, IWebSocketConnection> dic_Sockets = new Dictionary<string, IWebSocketConnection>(); var server = new WebSocketServer("ws://192.168.31.175:8181"); //出错后重启
server.RestartAfterListenError = true; server.Start(socket =>
{
socket.OnOpen = () => {
//获取客户端网页的url
string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
dic_Sockets.Add(clientUrl, socket);
Console.WriteLine(DateTime.Now.ToString() + "|服务器:和客户端网页:" + clientUrl + " 建立WebSock连接!"); };
socket.OnClose = () => //连接关闭事件
{
string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
//如果存在这个客户端,那么对这个socket进行移除
if (dic_Sockets.ContainsKey(clientUrl))
{
//注:Fleck中有释放
//关闭对象连接
//if (dic_Sockets[clientUrl] != null)
//{
//dic_Sockets[clientUrl].Close();
//}
dic_Sockets.Remove(clientUrl);
}
Console.WriteLine(DateTime.Now.ToString() + "|服务器:和客户端网页:" + clientUrl + " 断开WebSock连接!");
};
socket.OnMessage = message => //接受客户端网页消息事件
{
string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
foreach (var item in dic_Sockets.Where(a=>a.Key!=clientUrl))
{
item.Value.Send(message);
}
//Console.WriteLine(DateTime.Now.ToString() + "|服务器:【收到】来客户端网页:" + clientUrl + "的信息:\n" + message);
};
socket.OnBinary = b => { };
}); Console.ReadKey();
}

记录完毕,这个东西仅仅只是个demo,可以拿来玩一下

webrtc 实时视频 .net websocket信令服务器的更多相关文章

  1. 如何搭建WebRTC信令服务器

    WebRTC 有一整套规范,如怎样使用它的接口.使用SDP进行媒体协商.通过ICE收集地址并进行连通性检测等等.除此之外,WebRTC还需要房间服务器将多端聚集到一起管理,以及信令服务器进行信令数据交 ...

  2. WebRTC 信令服务器

    WebRTC 信令服务器 node.js & V8 libuv socket.io https://socket.io/ node-static SSR https://github.com/ ...

  3. 一步一步搭建客服系统 (2) 如何搭建SimpleWebRTC信令服务器

    上次介绍了<3分钟实现网页版多人文本.视频聊天室 (含完整源码)>使用的是default 信令服务器,只是为了方便快速开始而已.SimapleWebRTC官方文档里第一条就讲到,不要在生产 ...

  4. 基于Tomcat7、Java、WebSocket的服务器推送聊天室

    http://blog.csdn.net/leecho571/article/details/9707497 http://blog.fens.me/java-websocket-intro/ jav ...

  5. Tomcat学习总结(4)——基于Tomcat7、Java、WebSocket的服务器推送聊天室

    前言           HTML5 WebSocket实现了服务器与浏览器的双向通讯,双向通讯使服务器消息推送开发更加简单,最常见的就是即时通讯和对信息实时性要求比较高的应用.以前的服务器消息推送大 ...

  6. Nodejs搭建音视频通信-信令服务器 总结

    1.安装nodejs  node-v10.16.3-x64.msi 2.安装配置环境变量 这里的环境配置主要配置的是npm安装的全局模块所在的路径,以及缓存cache的路径,之所以要配置,是因为以后在 ...

  7. WebSocket部署服务器外网无法连接解决方案

    首先要说的是我遇见的问题: WebSocket connection to 'ws://www.xxxx.com/xxx/xx' failed: Error during WebSocket hand ...

  8. WebRTC MCU( Multipoint Conferencing Unit)服务器调研

    接触过的有licode.kurento. licode的缺陷:文档支持有限,licode的app client库只有js的 kurento的优势:文档齐全,Demo俱备,封装API比较齐全.它的主要特 ...

  9. 使用Websocket与服务器建立连接

    handleMessage = () => { const url = '////'; //某url const token = getCookie('xnToken');//向后端发请求得登陆 ...

随机推荐

  1. c++为什么要面向对象?

    前言 c和c++的区别是什么?不可置否,最重要的就是c++的编程思想是面向对象,而c的编程思想是面向过程,这是它们的本质区别,如果你在使用c++编程时使用的还是面向过程的编程思想,那么还不如使用c,因 ...

  2. html 可编辑的下拉框

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 关于 Nginx 配置 WebSocket 400 问题

    今天把项目升级了 asp.net core 到 2.1 的版本,使用了 signalr  的功能,由于阿里云不支持 websocket 协议,所以使用了 nginx 代理方式来解决,后续就报了一个登陆 ...

  4. SSM整合(四)-整合后配置文件汇总

    1.新建Maven项目创建pom.xml pom.xml内容如下 <project xmlns="http://maven.apache.org/POM/4.0.0" xml ...

  5. 让Java线程池实现任务阻塞执行的一种可行方案

    Java的线程池一般是基于concurrent包下的ThreadPoolExecutor类实现的, 不过当我们基于spring框架开发程序时, 通常会使用其包装类ThreadPoolTaskExecu ...

  6. docker 日志方案

    docker logs默认会显示命令的标准输出(STDOUT)和标准错误(STDERR).下面使用echo.sh和Dockerfile创建一个名为echo.v1的镜像,echo.sh会一直输出”hel ...

  7. php 获取中文字符串首字母

    <?php $limit=array( //gb2312 拼音排序 array(45217,45252), //A array(45253,45760), //B array(45761,463 ...

  8. biztalk rosettanet 自定义 pip code

    USE [BTARNDATA] GO /****** Object: StoredProcedure [dbo].[proc_GetActivityStatus] Script Date: 09/16 ...

  9. #9 Python列表和元组

    前言 Python中有6种序列:列表.元组.字符串.Unicode字符串.buffer对象和xrange对象.序列通用操作包括:索引.切片.长度.加.乘.最大值.最小值,遍历和检查成员.虽然Pytho ...

  10. FFmpeg使用基础

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10297002.html 本文介绍FFmpeg最基础的概念,了解FFmpeg的简单使用,帮 ...