webRTC-NodeJS creates a signaling server directory
Article Directory
Preface
- This article is taken from "Learning WebRTC"
- To create a complete
WebRTC
application, you need to put aside the development of the client side and turn to the development of the server side
Recommended reading
- 《Learning WebRTC》
Build a signaling server
- Connect two users who are not on the same computer
- The purpose of the server is to replace the original signaling mechanism through network transmission
- Responding to multiple users:
- Allow users from one party to call the other party to establish a
WebRTC
connection between the two parties - Once the user calls the other party, the server will pass the request, response and
ICE
candidate path between the two parties
- Allow users from one party to call the other party to establish a
Process
- Information flow when the server establishes a connection
- Log in to the server, log in and send a user ID in the form of a string to the server to ensure that it is not used
- Log in, start calling, send request by using the other party's identification code
- Send a leave message to terminate the connection
- This process is mainly used as a channel for sending information to each other
note
- Since there are no rules for the realization of signaling, any protocol, technology or mode can be used
WebSockets
-
WebRTC
The steps required to establish a connection must be real-time, and it is best to use itWebSockets
.WebRTC
Real-time messaging cannot be delivered using peer-to-peer connections -
Socket
Send information in both directions in the form of string and binary code -
Completely depends on the
WebSocket
framework:Meteor JavaScript framework
-
npm
Installationwebsocket
:npm install ws
-
wscat
:npm install wscat
server.js
const WebSocketServer = require('ws').Server,
wss = new WebSocketServer({
port: 8888});
wss.on("connection", connection => {
console.log("User connected");
connection.on("message", message => {
console.log("Got message:", message);
});
connection.send("hello world!")
});
-
Monitor server-side
connection
events, when the user establishes awebsocket
connection with the server , this will be called, and all the information of the connected party -
Installation
wscat
test:npm install -g ws
,wscat -c ws://localhost:8888
or FeExperiment
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let websocket = new WebSocket("ws://localhost:8888");
</script>
</body>
</html>
Identify users
- In a typical network application, the server needs a way to identify the connected user
- Follow the unique rules, so that each user has an identification in the form of a string, that is, the user name
Only one is id
needed to identify
const WebSocketServer = require('ws').Server,
wss = new WebSocketServer({
port: 8888});
wss.on("connection", connection => {
console.log("User connected");
connection.on("message", message => {
// console.log("Got message:", message);
let data;
try{
data = JSON.parse(message);
}catch(e) {
console.log(e);
data = {
};
}
});
connection.send("hello world!")
});
Complete signaling server
const WebSocketServer = require('ws').Server,
wss = new WebSocketServer({
port: 8888}),
users = {
};
wss.on("connection", connection => {
console.log("User connected");
connection.on("message", message => {
// console.log("Got message:", message);
let data, conn;
try{
data = JSON.parse(message);
}catch(e) {
console.log(e);
data = {
};
}
switch(data.type) {
case "login":
console.log("User logged in as", data.name);
if(users[data.name]) {
sendTo(connection, {
type: "login",
success: false
});
}else {
users[data.name] = connection;
connection.name = data.name;
sendTo(connection, {
type: "login",
success: true
});
}
break;
case "offer":
console.log("sending offer to:", data.name);
conn = users[data.name];
if(conn != null){
connection.otherName = data.name;
sendTo(conn, {
type: "offer",
offer: data.offer,
name: connection.name
});
}
break;
case "answer":
console.log("sending answer to:", data.name);
conn = users[data.name];
if(conn != null){
connection.otherName = data.name;
sendTo(conn, {
type: "answer",
answer: data.answer
})
}
break;
case "candidate":
console.log("sending to", data.name);
conn = users[data.name];
if(conn != null){
sendTo(conn, {
type: "candidate",
candidate: data.candidate
});
}
break;
case "leave":
console.log("Disconnected user from ", data.name);
conn = users[data.name];
conn.otherName = null;
if(conn != null){
sendTo(conn, {
type: "leave"
});
}
break;
default:
sendTo(connection, {
type: "error",
message: "Unrecognized command: " + data.type
});
break;
}
});
});
wss.on("close", function(){
if(connection.name){
delete users[connection.name];
if(connection.otherName) {
console.log("Disconnected,",connection.otherName);
let conn = users[connection.otherName];
conn.otherName = null;
if(conn != null){
sendTo(conn,{
type: "leave"
});
}
}
}
});
wss.on("listening", () => {
console.log("Server started...");
});
function sendTo(conn, message) {
conn.send(JSON.stringify(message));
}