preface
I wrote an article about Websocket “Online Chat room based on WebSocket (I) (II)” before, this time I changed to WebRTC to realize voice and video functions.
The client
There are plenty of WebRTC demos available online, but many of them won’t work even if they climb the wall. In addition, it is complicated to configure using WebRTC directly, so in this article, we use a package library of WebRTC, SimpleWebRTC, the website is github.com/andyet/Simp… , this is a nodeJS project, after testing can be directly used in the LAN without climbing over the wall.
First, introduce latest-v2.js from the demo above into the page
<script type="text/javascript" src="js/latest-v2.js"></script>
Copy the code
Webrtc is then configured in JS and the connection is established
webrtc = new SimpleWebRTC({
// The id of the video element that displays the local camera screen
localVideoEl: 'myVideo'.// The id of the video element that displays the image of the remote camera
remoteVideosEl: ' '.// Automatically requests access to media devices, i.e. the popup box asks whether access to camera and microphone devices is allowed
autoRequestMedia: true.debug: false.detectSpeakingEvents: true.// Media request parameters
media: {
video: true./ / camera
audio: true/ / the microphone
},
autoAdjustMic: false
});
// Add the video control to display the screen when new remote videos are uploaded
webrtc.on('videoAdded'.function (video, peer) {
console.log('video added', peer);
$(video).fadeIn('slow').appendTo(Console.Win + " #videocontent");
$(video).attr("id"."dest-" + peer.id);
});
// Remove the video screen when the remote video stream is disconnected
webrtc.on('videoRemoved'.function (video, peer) {
console.log('video removed ', peer);
var dest = $('video[id="dest-' + peer.id + '"]);
dest && dest.remove()
});
Copy the code
To join the room
webrtc.joinRoom('video');// 'video' is the name of the room, which can be set arbitrarily, but can only be used in the same room
Copy the code
Leave the room
webrtc.leaveRoom();// The remote client cannot receive the audio/video stream after leaving the room
Copy the code
Note: WebrTC seems to have requirements for chrominum, so we recommend upgrading to the latest Chrome browser. Edge browser support has been tested and IE11 still does not support it.
The service side
The previous server used Tomcat7, so this time we will use nodeJS instead. The most common examples of websocket in NodeJS on the web are socket.io, which claims to provide the following real-time connection schemes and automatically selects the most capable transport mode at runtime without affecting API usage.
* WebSocket * Adobe Flash Socket * AJAX long polling * AJAX multiple streams * Iframe * JSONP pollingCopy the code
However, I feel that the usage of socket. IO is complicated, or there are some differences from the previous tomcat development ideas, and the triggered event name is strange, which I cannot accept for a while (it seems that the client also needs to change the socket. IO writing method), so I give up and choose to use the original usage, which is similar to the client. The most important thing is that the client doesn’t have to change.
Nodejs environment configuration here is not much to introduce, I am also n long ago curious to come over to play, perennial use, a rookie.
First, install the WS module
NPM install ws // it is better to install in the global path with -g so that you do not have to install everywhereCopy the code
And then there was a flood of code
(function(){
// HTTP service Settings
var express = require('express'),
app = express(),
http = require('http').createServer(app);
app.use(express.static(__dirname));
http.listen(8080.function(){
console.log('httpServer: listening on "http://localhost:8080"');
});
// WebSocket service Settings
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({
port: 8082.// Port Settings, preferably different from the HTTP service listening port
// host: "localhost",// If this parameter is not set, websocket requests can be initiated using external, internal, or loopback addresses. After this parameter is set, only specified IP addresses can be used
path: "/websocket/chat"// Request address, do not set the default root path
}, function() {
console.log('websocketServer: listening on "ws://localhost:8082/chat"');
}),
connectionList = new ArrayList(),
roomInfo = {};
// The connection is established
wss.on('connection'.function(ws) {
var wsid = ws._ultron.id,
name = "Tourists" + new Date().getTime().toString();
console.log("%s joined the chat room.",name);
roomInfo = connectionList.length > 0 ? roomInfo : {
creater: name,
createTime: new Date().toLocaleString()
};
connectionList.add({
wsid: wsid,
name: name,
connect: ws
});
var dests = getDests(),
setNameMsg = {
host: name,
type: 6.//setName
roomInfo: roomInfo,
dests: dests
},
joinMsg = {
host: name,
type: 1.//setName
roomInfo: roomInfo,
dests: dests
},
msg = JSON.stringify(setNameMsg);
// Set the name
ws.send(msg);
msg = JSON.stringify(joinMsg);
// Notify everyone of a new connection
connectionList.foreach(function(obj) {
obj.connect.send(msg);
});
// Received the message
ws.on('message'.function(message) {
console.log('Received message from %s: %s', name, message);
// deserialize
var msg = JSON.parse(message);
msg.host = name;
/ / the serialization
message = JSON.stringify(msg);
connectionList.foreach(function(obj) {
obj.connect.send(message);
});
});
// The connection is down
ws.on('close'.function(message) {
console.log("%s left the chat room.", name );
// Remove the current connection
var index = connectionList.find(function(obj) {
return obj.wsid == wsid;
});
index > -1 && connectionList.removeAt(index);
var closeMsg = {
host: name,
type: 2.//close
dests: getDests()
};
message = JSON.stringify(closeMsg);
connectionList.foreach(function(obj) {
obj.connect.send(message);
});
});
});
function getDests() {
var dests = [];
connectionList.foreach(function(obj) {
dests[dests.length] = obj.name;
});
return dests;
}
function ArrayList(array) {
this.array = typeofarray ! = ='undefined' && array instanceof Array ? array : new Array(a);this.length = this.array.length;
var that = this,
setLength = function() {
that.length = that.array.length;
};
this.get = function(index){
return this.array[index];
}
this.add = function(obj) {
this.array.push(obj);
setLength();
};
this.indexOf = function(obj) {
return this.array.indexOf(obj);
}
this.find = function(callback) {
for(var i = 0; i < this.length; i++){
if(callback(this.get(i))) {
returni; }}return -1;
}
this.removeAt = function(index){
this.array.splice(index, 1);
setLength();
};
this.remove = function(obj){
var index = this.indexOf(obj);
if (index >= 0) {this.removeAt(index); }};this.clear = function(){
this.array.length = 0;
setLength();
};
this.insertAt = function(index, obj){
this.array.splice(index, 0, obj);
setLength();
};
this.foreach = function(callback) {
for(var i = 0; i < this.length; i++){
callback(this.get(i)); }}; }}) ();Copy the code
Write the above code to server.js, then run the command line to switch to the current directory and start the service using the Node server command (in my case, double-click the batch file in the root directory of the project to open it).
Two servers are started. HTTP is the HTTP server, which is used for page access in the current directory. The other WSS is the WebSocket server, which is used for the WebSocket service. When a new connection is established, the WebSocket server triggers the “connection” event. When a message is received and the connection is disconnected, the webSocket server triggers the “object” event. This is slightly different from tomcat, which fires all ServerEndpoint events.
The reverse proxy configuration of Nginx was mentioned at the end of the previous article, which also applies to NodeJS, so I won’t go into details here.
conclusion
- Thanks to the off-the-shelf wrapper library SimpleWebRTC, it has very little code, is very easy to use, and is much better in terms of performance than my previous implementation through WebSocket. However, the effect of the Internet access has not been tested, the Internet also needs STUN, ICE and other servers to achieve NAT penetration, interested students can go over the wall to try.
- The server side is implemented by NodeJS, so that all the code is composed of HTML + JS + CSS, and the service starts quickly and consumes little memory.
Reference article:
- Blog.chinaunix.net/uid-2456787…
- My.oschina.net/yushulx/blo…
The project code is already ingithubUpdate on