技术前言
通过前面的教程,可以轻松实现两个浏览器之间的文本信号交互和视频对讲功能。
本次课程要融合以前所有技术点,做一次综合性实例,采用nodejs实现一个完整的聊天室功能。其界面样式仿照微信的界面搭建。接口方法
在此我根据实例代码用到的接口做如下讲解,为了方便本实例我们采用nodejs开发,其中用到了技术。如果对(https:///)不明白的话可以先学习一下再回来看本教程。
1. io.(‘connection’, function (socket) {});
消息连接方法,其中回调函数的socket参数为一个client与服务器的连接标识,不同的client会有不同的连接标识。
2. (‘message’, “this is a test”);
向所有已连接服务器的终端也包括自己在内广播消息"this is a test"。
3. (‘message’, “this is a test”);
向除了自己所有已连接服务器的socket终端广播消息"this is a test"
4. (‘game’).emit(‘message’, ‘nice game’);
向game房间中除了自己的所有终端广播消息"this is a test"
5. io.(‘game’).emit(‘message’, ‘cool game’);
向game房间中包括自己在内的所有终端广播消息"this is a test"
sending to individual socketid
6. io.(socketid).emit(‘message’, ‘for your eyes only’);
仅给连接编号为socketid的终端发送消息
7. io.(‘xx’,function);
以‘xx‘为协义订阅服务端的消息通知事件。
实践代码
前端界面
index.jade
extends layout
title=abc
block header
link(rel='stylesheet', href='/styleshee;)
script(src = "/javascri;)
script(src = "/javascri;)
script(src = "/javascripts/.js")
script(src="/javascri;)
script(src="/javascri;)
script(src = "/javascri;)
script(src="../javascripts/index;)
block content
h1 SocketIo Server Web1
p Welcome to SocketIo Server Web
index.html
<style type="text/css">
#localVideo {
background-color: #999999;
border: 1px #999999 solid;
width: 100%;
height: 100%;
}
#remoteVideo {
position: relative;
float: left;
top: -395px;
left: 5px;
background-color: black;
width: 150px;
height: 150px;
text-align: center;
z-index: 1;
}
.vbtn{
position: relative;
top: -90px;
}
.vbtn img{
width: 64px;
height: 64px;
}
.video {
position: absolute;
display: none;
top:150px;
left: 250px;
border: 1px black solid;
width: 450px;
height: 400px;
}
.talk a:link {color: white;}
.span {
position: relative;
padding: 5px;
}
.tip {
display: block;
background: #f00;
border-radius: 50%;
width: 8px;
height: 8px;
top: 0px;
right: 0px;
position: absolute;
}
</style>
<div class="wrapper">
<div class="container">
<div class="left">
<div class="top">
<img src="../images/cha; id="headerImg" class="search" alt="" />
<span class="name" id="headerName"></span>
</div>
<ul class="people">
<li class="person" data-chat="person1">
<img src="../images/cha; alt="" />
<span class="name">张三三</span>
<span class="preview">I was wondering...</span>
</li>
<li class="person" data-chat="person2">
<img src="../images/cha; alt="" />
<span class="name">李四四</span>
<span class="preview">I've forgotten how it felt before</span>
</li>
<li class="person" data-chat="person3">
<img src="../images/cha; alt="" />
<span class="name">王五五</span>
<span class="preview">But we’re probably gonna need a new carpet.</span>
</li>
<li class="person" data-chat="person4">
<img src="../images/cha; alt="" />
<span class="name">赵七七</span>
<span class="preview">It’s not that bad...</span>
</li>
<li class="person" data-chat="person5">
<img src="../images/cha; alt="" />
<span class="name">周八皮</span>
<span class="preview">Wasup for the third time like is
you blind bitch</span>
</li>
<li class="person" data-chat="person6">
<img src="../images/cha; alt="" />
<span class="name">李寻欢</span>
<span class="preview">howdoyoudoaspace</span>
</li>
</ul>
</div>
<div class="right">
<div class="top"><span>To: <span class="name" id="friendName">暂无好友</span></span>
</div>
<div class="chat" data-chat="person1"></div>
<div class="chat" data-chat="person2"></div>
<div class="chat" data-chat="person3"></div>
<div class="chat" data-chat="person4"></div>
<div class="chat" data-chat="person5"></div>
<div class="chat" data-chat="person6"></div>
<div class="write">
<a href="javascript:;" class="write-link attach"></a>
<input type="text" id="txtContent" />
<a href="javascript:;" class="write-link smiley" id="videoBtn"></a>
<a href="javascript:;" class="write-link send" id="sendBtn"></a>
</div>
</div>
</div>
</div>
<div id="video" class="video">
<video id="localVideo" autoplay playsinline></video>
<video id="remoteVideo" autoplay playsinline></video>
<div class="vbtn">
<img src="../image; id="CloseBtn" />
</div>
</div>
服务端
var app = express();
a(6000);
var server = require('http').Server(app);
var io = require('')(server);
(6100);
var persons = [];
var getPersonSeq = function() {
var tempSeq = Ma() * 5) + 1;
(p => {
if == tempSeq) {
tempSeq = getPersonSeq();
}
});
return tempSeq;
}
io.('connection', function(socket) {
if ) == -1) {
({
id: ,
seq: getPersonSeq()
});
}
function trace() {
con(arguments);
}
con("用户 '" + + "' 连接成功!");
('ready', , persons);
('change', persons);
('disconnect', function() {
trace('终端(' + + ')已断开。 ');
var tempPersons = [];
(e => {
if != ) {
(e);
}
});
persons = tempPersons;
);
('change', persons);
});
('message', function(body) {
var d = new Date();
body.from = ;
body.time = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
).emit('message', body);
trace('终端(' + + "):message>", body);
});
('meeting', function(body) {
///向除自己外所有meeting终端广播消息
('meeting', body);
//(room).emit('meeting', body);
trace('终端(' + + "):meeting>", body);
});
('create', function(room, callbackfunc) {
var clientsInRoom = io.[room];
var numClients = clientsInRoom ? Object.key).length : 0;
var temproom = {
id: room,
count: numClients
};
(room);
(temproom);
if (typeof(callbackfunc) == 'function') {
callbackfunc(temproom);
}
});
('join', function(room, callbackfunc) {
var clientsInRoom = io.[room];
var numClients = clientsInRoom ? Object.key).length : 0;
var robj = {
id: room,
count: numClients
}
switch (numClients) {
case 0:
trace('终端(' + + ')进入的房间 ”' + room + '" 不存在!');
('empty', room);
break;
case 1:
///向房间room中发送消息
io.(room).emit('join', room);
(room);
trace('房间 ' + room + '中现在有' + numClients + '个终端!');
break;
case 2:
('full', room);
trace('房间 ”' + room + '" 已满。');
break;
}
if (typeof(callbackfunc) == 'function') {
callbackfunc(robj);
}
});
('ipaddr', function() {
var ifaces = os.networkInterfaces();
for (var dev in ifaces) {
ifaces[dev].forEach(function(details) {
if === 'IPv4' && de !== '127.0.0.1') {
('ipaddr', de);
}
});
}
});
});
部署发布
本实例代码用nodejs直接发布到服务上,经测试会发生跨域访问,我们可以通过Nginx实现一个反向代理,由于webrtc视频通讯需要采用https协议访问才能调用视频流,Nginx需要设置ssl配置。
Nginx Https Server 配置如下:
# HTTPS server
server {
listen 443 ssl;
server_name localhost;
ssl_certificate ca/cer;
ssl_certificate_key ca/cer;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Nginx-Proxy true;
proxy_set_header Connection "";
proxy_pass ;
proxy_redirect default;
}
}
运行结果
不同浏览器之间普通文本内容通讯,左侧选择好友,右侧发送消息。
不同浏览器之间视频实时通讯,左侧选择好友,右侧发送视频邀请。在测试的时候我是用的同一台电脑,所以本地和远程都是相同的图像。
实践历程
1. WebRTC实践简介
2. WebRTC实践获取视频流
3. WebRTC实践传输视频流
4. WebRTC实践信令服务
5. WebRTC实践点对点通信
6. WebRTC实践视频聊天室
7.WebRTC实践总结