这篇文章主要参考了 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. Apache Commons Digester 一 (基础内容、核心API)

    前言 在许多需要处理XML格式数据的应用环境中, 如果能够以“事件驱动”的方式来处理XML文档,比如,当识别出特定的XML元素时,触发“创建对象”操作事件(或者触发调用对象的方法事件),这对于应用程序 ...

  2. 独享锁 & 共享锁

    独享锁(互斥锁):同时只能有一个线程获得锁.比如,ReentrantLock 是互斥锁,ReadWriteLock 中的写锁是互斥锁. 共享锁:可以有多个线程同时获得锁.比如,Semaphore.Co ...

  3. java ee期末项目相关

    1.项目简介 本项目是对纸杯生产进行管理的的一个系统,从前端接收到订单,然后根据订单内容进行纸杯的生产.如下为该系统的总流程图: 1.项目系统架构图 3.系统用例图 4.ER图 主要的代码和相关文件见 ...

  4. GAN笔记——理论与实现

    GAN这一概念是由Ian Goodfellow于2014年提出,并迅速成为了非常火热的研究话题,GAN的变种更是有上千种,深度学习先驱之一的Yann LeCun就曾说,"GAN及其变种是数十 ...

  5. .12-浅析webpack源码之NodeWatchFileSystem模块总览

    剩下一个watch模块,这个模块比较深,先大概过一下整体涉及内容再分部讲解. 流程图如下: NodeWatchFileSystem const Watchpack = require("wa ...

  6. struts2、hibernate以及spring是如何配置的

    第一次使用这3大框架进行网站编写的人没有一个清楚的流程,建起网站来会比较头疼,今天来讲讲3大框架的配置 基本流程: 用户点击页面之后,服务器收到一个请求,请求经过web.xml的拦截器过滤后进入act ...

  7. 类Exception_A继承Exception,类Exception_B继承Exception_A,请问执行此段代码的输出是什么?

    @Test public void Test_Exception() { try { throw new ExceptionB("A"); } catch (ExceptionA ...

  8. c#实战开发:以太坊钱包对接私链 (二)

    上一篇讲了 以太坊私链搭建 首先下载Ethereum Wallet 钱包 可以直接百度 下载如果直接打开它会默认连接公链 所以我们要通过命令打开 "F:\Program Files\Ethe ...

  9. MyBatis学习笔记(三) Configuration类

    一.初探Configuration类 我们先来看一下MyBatis的XML配置文件的结构,(摘自mybatis.org) 下面这个是Configuration类的部分变量 一点不一样是不是??? 其实 ...

  10. html页面背景设定相关

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