Nodejs搭建音视频通信-信令服务器 总结
2、安装配置环境变量
这里的环境配置主要配置的是npm安装的全局模块所在的路径,以及缓存cache的路径,之所以要配置,是因为以后在执行类似:npm install express [-g] (后面的可选参数-g,g代表global全局安装的意思)的安装语句时,会将安装的模块安装到【C:\Users\用户名\AppData\Roaming\npm】路径中,占C盘空间。例如:我希望将全模块所在路径和缓存路径放在我node.js安装的文件夹中,则在我安装的文件夹【D:\Develop\nodejs】下创建两个文件夹【node_global】及【node_cache】。
创建完这两个空文件夹之后,打开cmd命令窗口,输入:
npm config set prefix "D:\Develop\nodejs\node_global"
npm config set cache "D:\Develop\nodejs\node_cache"

接下来设置环境变量,关闭cmd窗口,“我的电脑”-右键-“属性”-“高级系统设置”-“高级”-“环境变量”:


备注:使用npm install -g 'xxx' 之后仍然报Cannot find module 'xxx' 错误,可以通过设置环境变量NODE_PATH来解决。
在系统目录中找到C:\Users\Administrator\.npmrc文件 修改如下即可:
cache =D:\Develop\nodejs\node_cache
npm install express -g # -g是全局安装的意思3、自签名的https证书
openssl genrsa -out 1557605_www.learningrtc.cn.key 2048//这是秘钥(生成秘钥文件)
openssl req -new -sha256 -key 1557605_www.learningrtc.cn.key -out csr.pem//签名请求文件(申请者需要将自己的信息及其公钥放入证书请求中。但在实际操作过程中,所需要提供的是私钥而非公钥,因为它会自动从私钥中提取公钥)
openssl x509 -req -in csr.pem -signkey 1557605_www.learningrtc.cn.key -out 1557605_www.learningrtc.cn.pem//这是证书
4、信令服务器主要代码
server.js文件
'use strict'
var log4js = require('log4js');
var http = require('http');
var https = require('https');
var fs = require('fs');
var socketIo = require('socket.io');
var express = require('express');
var serveIndex = require('serve-index');
var USERCOUNT = 3;
log4js.configure({
appenders: {
file: {
type: 'file',
filename: 'app.log',
layout: {
type: 'pattern',
pattern: '%r %p - %m',
}
}
},
categories: {
default: {
appenders: ['file'],
level: 'debug'
}
}
});
var logger = log4js.getLogger();
var app = express();
app.use(serveIndex('./public')); //node server.js启动后,项目的根目录在public文件夹下(public文件夹和server.js文件在同一个目录下,public文件夹下有index.html文件、css文件和js文件夹等)
app.use(express.static('./public'));
//http server
var http_server = http.createServer(app);
http_server.listen(80, '0.0.0.0');
var options = {
key : fs.readFileSync('./cert/1557605_www.learningrtc.cn.key'), //https秘钥,放在cert文件夹下
cert: fs.readFileSync('./cert/1557605_www.learningrtc.cn.pem') //https证书,放在cert文件夹下
}
//https server
var https_server = https.createServer(options, app);
var io = socketIo.listen(https_server);
io.sockets.on('connection', (socket)=> {
socket.on('message', (room, data)=>{
logger.debug('message, room: ' + room + ", data, type:" + data.type);
socket.to(room).emit('message',room, data);
});
/*
socket.on('message', (room)=>{
logger.debug('message, room: ' + room );
socket.to(room).emit('message',room);
});
*/
socket.on('join', (room)=>{
socket.join(room);
var myRoom = io.sockets.adapter.rooms[room];
var users = (myRoom)? Object.keys(myRoom.sockets).length : 0;
logger.debug('the user number of room (' + room + ') is: ' + users);
if(users < USERCOUNT){
socket.emit('joined', room, socket.id); //发给除自己之外的房间内的所有人
if(users > 1){
socket.to(room).emit('otherjoin', room, socket.id);
}
}else{
socket.leave(room);
socket.emit('full', room, socket.id);
}
//socket.emit('joined', room, socket.id); //发给自己
//socket.broadcast.emit('joined', room, socket.id); //发给除自己之外的这个节点上的所有人
//io.in(room).emit('joined', room, socket.id); //发给房间内的所有人
});
socket.on('leave', (room)=>{
socket.leave(room);
var myRoom = io.sockets.adapter.rooms[room];
var users = (myRoom)? Object.keys(myRoom.sockets).length : 0;
logger.debug('the user number of room is: ' + users);
//socket.emit('leaved', room, socket.id);
//socket.broadcast.emit('leaved', room, socket.id);
socket.to(room).emit('bye', room, socket.id);
socket.emit('leaved', room, socket.id);
//io.in(room).emit('leaved', room, socket.id);
});
});
https_server.listen(8443, '0.0.0.0');
index.html文件:
<html>
<head>
<title>Chat Room</title>
<link rel="stylesheet" href="./css/main.css"></link>
</head>
<body>
<table align="center">
<tr>
<td>
<label>UserName: </label>
<input type=text id="username"></input>
</td>
</tr>
<tr>
<td>
<label>room: </label>
<input type=text id="room"></input>
<button id="connect">Conect</button>
<button id="leave" disabled>Leave</button>
</td>
</tr>
<tr>
<td>
<label>Content: </label><br>
<textarea disabled style="line-height: 1.5;" id="output" rows="10" cols="100"></textarea>
</td>
</tr>
<tr>
<td>
<label>Input: </label><br>
<textarea disabled id="input" rows="3" cols="100"></textarea>
</td>
</tr>
<tr>
<td>
<button id="send">Send</button>
</td>
</tr>
</table> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="./js/client.js"></script>
</body> </html>
client.js文件:
'use strict'
var userName = document.querySelector('input#username');
var inputRoom = document.querySelector('input#room');
var btnConnect = document.querySelector('button#connect');
var btnLeave = document.querySelector('button#leave');
var outputArea = document.querySelector('textarea#output');
var inputArea = document.querySelector('textarea#input');
var btnSend = document.querySelector('button#send');
var socket;
var room;
btnConnect.onclick = ()=>{
//connect
socket = io.connect();
//recieve message
socket.on('joined', (room, id) => {
btnConnect.disabled = true;
btnLeave.disabled = false;
inputArea.disabled = false;
btnSend.disabled = false;
alert("room:"+room + ",id:"+id);
});
socket.on('leaved', (room, id) => {
btnConnect.disabled = false;
btnLeave.disabled = true;
inputArea.disabled = true;
btnSend.disabled = true;
socket.disconnect();
});
socket.on('message', (room, data) => {
outputArea.scrollTop = outputArea.scrollHeight;//窗口总是显示最后的内容
outputArea.value = outputArea.value + data + '\r';
});
socket.on('disconnect', (socket)=>{
btnConnect.disabled = false;
btnLeave.disabled = true;
inputArea.disabled = true;
btnSend.disabled = true;
});
//send message
room = inputRoom.value;
socket.emit('join', room);
}
btnSend.onclick = ()=>{
var data = inputArea.value;
data = userName.value + ':' + data;
socket.emit('message', room, data);
inputArea.value = '';
}
btnLeave.onclick = ()=>{
room = inputRoom.value;
socket.emit('leave', room);
}
inputArea.onkeypress = (event)=> {
//event = event || window.event;
if (event.keyCode == 13) { //回车发送消息
var data = inputArea.value;
data = userName.value + ':' + data;
socket.emit('message', room, data);
inputArea.value = '';
event.preventDefault();//阻止默认行为
}
}
5、启动服务
cmd窗口,进入项目位置,输入:node server.js 启动服务。
Chrome浏览器和360极速浏览器,页面分别输入https://localhost:8443/index.html,加入同一个房间,可以发送聊天信息,房间里的用户可以识别到新加入的用户(收到join等消息)。
参考地址:
https://blog.csdn.net/u012853084/article/details/79089946
https://blog.csdn.net/paulowina/article/details/78591432
https://blog.csdn.net/abccheng/article/details/82622899
https://www.iteye.com/blog/freeman983-1350861
Nodejs搭建音视频通信-信令服务器 总结的更多相关文章
- p2p音视频通信
今年音频没事干了,根据业务需求,调研音视频p2p通信,减小服务器压力,一切从0开始. 需要信令服务器,打洞服务器,帮助链接打通双方,实现p2p音视频通信. 服务器和客服端交互等都需要实现. 谷歌web ...
- 利用 nodeJS 搭建一个简单的Web服务器(转)
下面的代码演示如何利用 nodeJS 搭建一个简单的Web服务器: 1. 文件 WebServer.js: //-------------------------------------------- ...
- 【秒懂音视频开发】26_RTMP服务器搭建
从本节开始,正式开启流媒体相关的内容. 流媒体 基本概念 流媒体(Streaming media),也叫做:流式媒体. 是指将一连串的多媒体数据压缩后,经过互联网分段发送数据,在互联网上即时传输影音以 ...
- 一步一步搭建客服系统 (2) 如何搭建SimpleWebRTC信令服务器
上次介绍了<3分钟实现网页版多人文本.视频聊天室 (含完整源码)>使用的是default 信令服务器,只是为了方便快速开始而已.SimapleWebRTC官方文档里第一条就讲到,不要在生产 ...
- nodejs搭建web服务器初级
nodejs搭建简单的web服务器 1.1简介 Node.js是基于Chrome JavaScript运行时建立的一个平台,实际上它是对Google Chrome V8引擎进行了封装,它主要用于创建快 ...
- 8┃音视频直播系统之 WebRTC 信令系统实现以及通讯核心并实现视频通话
一.信令系统 信令系统主要用来进行信令的交换 在通信双方彼此连接.传输媒体数据之前,它们要通过信令服务器交换一些信息,如规范协商 若 A 与 B 要进行音视频通信,那么 A 要知道 B 已经上线了,同 ...
- 用nodejs搭建类似于C++的服务器后台.类似网易pomelo
实际的情况,用nodejs跑业务,非常的快,只要用好其无阻塞和回调这两点,处理速度真的是杠杠的. 从年初开始,我用nodejs搭建了类似C++的服务器后台,也想和做同样的事情的朋友分享,本服务平台因为 ...
- 12┃音视频直播系统之 WebRTC 实现1对1直播系统实战
一.搭建 Web 服务器 前面我们已经实现过,但是没有详细说HTTPS服务 首先需要引入了 express 库,它的功能非常强大,用它来实现 Web 服务器非常方便 同时还需要引入 HTTPS 服务, ...
- 融云携新版实时音视频亮相 LiveVideoStack 2019
4 月 19 日,LiveVideoStack 2019 音视频大会在上海隆重开幕,全球多媒体创新专家.音视频技术工程师.产品负责人.高端行业用户等共襄盛会,聚焦音频.视频.图像.AI 等技术的最新探 ...
随机推荐
- Ubuntu下软件打开时状态图标与原始图标不重合问题解决
问题描述 如下图书所示,pycharm打开时,运行的pycharm图标与原始的在收藏夹中的图标不重合.而其他软件不会这样,运行软件的图标与原始图标会重合, 解决办法 把鼠标悬浮在打开的pycharm上 ...
- CSP-S全国模拟赛第四场 【nan?】
本来想抢三题的 rk1 ?[无耻 最后发现 T2 好像还是慢了些,只搞了个 rk2 子段与子段 第一题随便分析一下,发现一段区间中某个元素的贡献次数就是 \((x+1)·(y+1)\) x 是他左边的 ...
- centos 6.x 编译安装 pgsql 9.6
文章结构如下: 一. 环境配置 1. 配置防火墙 查看IPTABLES 当前状态与关闭过程 chkconfig --list|grep iptables 关闭iptables service ipta ...
- 一分钟理解sku和spu
SPU SPU = Standard Product Unit (标准化产品单位) SPU是商品信息聚合的最小单位,是一组可复用.易检索的标准化信息的集合,该集合描述了一个产品的特性.通俗点讲,属性值 ...
- java json对象转换
引入的jar包: commons-beanutils-1.9.2.jar commons-collections-3.2.1.jar commons-lang-2.6.jar commons-logg ...
- drf模块分析
drf请求模块.渲染模板.解析模块.响应模块.异常模块 请求模块 drf的请求模块 1.drf的request是在wsgi的request基础上再次封装 2.wsgi的request作为drf的req ...
- 在Linux上安装tomcat和JDK
1.tomcat的安装 a.#cd download(进入download文件夹) b.#wget http://111.23.5.142:82/mirrors.hust.edu.cn/apache/ ...
- (转)linux chattr lsattr 命令
转http://www.ha97.com/5172.html PS:有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了.chattr命令的作用很大,其中一些功 ...
- 机器学习聚类算法之DBSCAN
一.概念 DBSCAN是一种基于密度的聚类算法,DBSCAN需要两个参数,一个是以P为中心的邻域半径:另一个是以P为中心的邻域内的最低门限点的数量,即密度. 优点: 1.不需要提前设定分类簇数量,分类 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(11)|Structs结构体]
[易学易懂系列|rustlang语言|零基础|快速入门|(11)] 有意思的基础知识 Structs 我们今天来看看数据结构:structs. 简单来说,structs,就是用来封装相关数据的一种数据 ...