房間服務器:我當時放在windows上,以下操作最好都使用管理員權限運行
1、我的房間服務器用的NOSEJS,在windows上下載NOSEJS安裝程序,安裝完後環境變量PATH裏就自動加上了相應路徑,不過最好還是檢查一下
2、使用CMD走一次node -v,看到版本號了說明安裝正確
3、繼續安裝以下組件
> npm install express
> npm install yetify
> npm install getconfig
> npm install node-uuid
> npm install socket.io
> npm install node-static
4、自己編寫房間服務器代碼,主要就是給瀏覽器端交換offer、answer和candidate用,之所以用socket.io,是因爲具備比普通ajax更高的實時性。如果擔心長連接對服務器負擔大,完全可以在完成接通後關閉socket,提前是你不需要用socket來幹別的比如實時文本消息。由於谷歌強調安全性,在Chrome中必須要用https才允許調用本麥克風和攝像頭,這裏我貼一個我用https做的demo/server.jsvar static = require('node-static');
var http = require('https');
const fs = require('fs');
const options = { //這裏定義https證書文件
key: fs.readFileSync('site.key'),
cert: fs.readFileSync('site.pem')
};
var file = new(static.Server)();
var app = http.createServer(options, (req, res) => {
file.serve(req, res);
}).listen(8080);
var roomPerfix = 'room_';//房間名前綴
var io = require('socket.io').listen(app);
io.sockets.on('connection', function (socket){
//io.sockets.emit('message', socket.id + ' joind!');//某人加入在線列表
socket.room_id = 0;//初始房間號爲0
socket.on('message', function (message) {socket.broadcast.to(roomPerfix + this.room_id).emit('message', socket.nick_name + ':' + message);});
socket.on('data', function (data) {socket.broadcast.to(roomPerfix + this.room_id).emit('data', data);});
socket.on('offer', function (offer) {socket.broadcast.to(roomPerfix + this.room_id).emit('offer', offer);});
socket.on('answer', function (answer) {socket.broadcast.to(roomPerfix + this.room_id).emit('answer', answer);});
socket.on('candidate', function (candidate) {socket.broadcast.to(roomPerfix + this.room_id).emit('candidate', candidate);});
socket.on('nick_name', function (nick_name) {socket.nick_name = nick_name;});
//以上事件的作用分別是:實時文本聊天、自定義類型數據傳送、發起RTC呼叫、RTC迴應、交換ICE、設置暱稱
socket.on('join_hall', function (info_type) {
//進入大廳,自己的代碼請自己寫
});
//接受端上線創建房間,判斷是否已經存在房間
socket.on('create_room', function (room) {
//自己的代碼請自己寫
});
//發起端加入房間,判斷是否已經存在房間
socket.on('join_room', function (room) {
//同上
});
//遍歷房間在線狀態
socket.on('get_room_status', function (rooms) { //rooms傳過來的是一維數組,json形式
var room_list = JSON.parse(rooms);
var i,numClients,result=[];
for(i=0;i<room_list.length;i++){
numClients = io.sockets.clients(roomPerfix + room_list[i]).length;
result.push({room_id:room_list[i],room_status:numClients});
}
socket.emit('room_status_list',JSON.stringify(result));
});
//拒接:結束會話,接受端將發起端移出房間
socket.on('refuse_session', function (room) {
socket.broadcast.to(roomPerfix + room).emit('refuse_session',room);//拒接
//將發起端移出房間
io.sockets.clients(roomPerfix + room).forEach(function (room_socket) {
if(room_socket.id != socket.id){
room_socket.room_id = 0;
room_socket.leave(roomPerfix + room);
}
});
socket.broadcast.to('hall').emit('hall_show', room);//通知大廳,我可以接受連接
});
socket.on('disconnect', function(data){
//掉線處理
});
});
TURN/STUN服務器:目前沒有windows版,我在centos7.2下裝的turnserver-4.4.5.2
當時是照着http://www.centoscn.com/image-text/install/2015/0923/6216.html操作的,端口默認3478,自己可以根據需要配置端口和其他信息
它有個好處是同時提供stun和turn服務,這樣在簡單UDP穿透NAT成功的情況下,客戶端之間直接建立點對點通信,不會持續佔用服務器帶寬,而穿透不成功時,則使用中繼服務,這會佔用服務器帶寬,但可以保證在複雜網絡環境中的連接成功率。
WEBRTC客戶端加入:
var iceServer = {
"iceServers": [{
"url": "stun:你的IP:3478"
}, {
"url": "turn:你的IP:3478",
"username": "你的帳號",
"credential": "你的密碼"
}]
};
創建RTCPeerConnection時將iceServer作爲參數帶上,像這樣:var pc = new RTCPeerConnection(iceServer);
部署完成,便可以擺脫局域網,讓自己的程序基於以上服務,飛奔在internet上了。