这篇文章主要参考了 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. Xcode 8.X Command Line Tools

    Summary Step 1. Upgrade Your System to macOS Sierra Step 2. Open the Terminal Application Step 3. Is ...

  2. Effectively bypassing kptr_restrict on Android

    墙外通道:http://bits-please.blogspot.com/2015/08/effectively-bypassing-kptrrestrict-on.html In this blog ...

  3. SaltStack数据系统-Grans详解

    1:Grains是系统的一个组件,存放着minion启动时收集的系统底层的一些信息,每次minion启动的时候,会进行系统的采集,将其保存下来,在以后的生命周期中不会重新搜集,除非重启~ #查看gra ...

  4. PHP 5.3中的命名空间使用方法

    PHP的命名空间(namespace)是php5.3之后才有的.这个概念在C#中已经很早就有了,php中的namespace其实和c#的概念是一样的. 为什么php中要使用namespace? 假设如 ...

  5. Vim——回顾整理

    一.命令练习(一) hjkl(左下上右) 保存到某路径 :saveas 路径 w 到下一个单词的开头 e 到下一个单词的结尾 % 括号匹配移动(),{},[] 0 到行头 $ 到行头 gU字母变大写 ...

  6. html页面背景设定相关

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. MEF 插件式开发之 DotNetCore 中强大的 DI

    背景叙述 在前面几篇 MEF 插件式开发 系列博客中,我分别在 DotNet Framework 和 DotNet Core 两种框架下实验了 MEF 的简单实验,由于 DotNet Framewor ...

  8. centos7.4+mysql5.6+virtualenv+python3.6+nginx+uwsgi+django生产环境搭建

    一 更新yum # yum update 二 安装gcc  lrzsz软件 # yum install gcc 用来编译python3.6源码 # yum install lrzsz 用来上传文件 三 ...

  9. 【读书笔记】iOS-对iOS应用进行模糊测试

    一,模糊测试,是指通过反复向待测应用发送畸形的数据,对应用进行动态测试的过程. 二,模糊测试,也称动态分析,是一种构造非法输入并将其提供给应用,以期让应用暴露出某些安全问题的艺术和科学. 参考资料:& ...

  10. python之成员(面向对象)

    1. 成员 在类中你能写的所有内容都是类的成员 class Person: def __init__(self, name, gender): self.name = name # 成员 self.g ...