Mac上webrtc实现简易聊天室

2019-08-08  本文已影响0人  一叶知秋0830

一、搭建信令服务器

首先创建一个文件夹chatRoom用来存放项目文件,chatRoom文件中创建pem文件夹存放证书,创建public文件夹用于存放要发布的文件,创建server.js文件(信令服务器文件),server.js文件中代码如下。我这里是搭建的本地服务器,会涉及到证书的生成,可以参考:生成自签名证书。搭建好后将服务启动,这时会看到chatRoom文件夹中多了一个app.log文件,这个是日志文件,服务器运行中的日志都存在这个文件中。

// server.js文件代码

// 引入所需的各个模块
var http = require('http');
var https = require('https');
var fs = require('fs'); // 用于读取证书
var express = require('express');
var serve_index = require('serve-index');
// 引入socket.io,socket.io是一个WebSocket库,用于实现在不同浏览器和移动设备上进行实时通信。
// 安装socket.io模块的命令:sudo npm install socket.io -g
var socketIo = require('socket.io'); 
// 引入log4js,用于日志输出
// 安装log4js模块的命令:sudo npm install log4js -g
var log4js = require('log4js');
// log4js的配置(日志内容存储在app.log的文件中)
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();

// 定义一个express对象,用于web服务
var app = express();
// 发布静态目录,静态目录是当前路径下的public文件夹
app.use(serve_index('./public', {'icons': true}));
app.use(express.static('./public'));

// http服务
var http_server = http.createServer(app);
http_server.listen(8082,'192.168.20.242');

// https服务
// 读取证书
var options = {
   key : fs.readFileSync('./pem/private_key.pem'),
   cert : fs.readFileSync('./pem/cacert.pem')
};
var https_server = https.createServer(options,app);

/*
将socket.io与https_server绑定起来
当启动服务时socket.io和https_server这2个服务都是绑定在8083端口上
绑定的服务io(站点)下面可以有很多房间
*/
var io = socketIo.listen(https_server);
/*
io下面所有socket(一个socket就是一个链接,也就是一个客户端)都监听connection事件。
当一个客户端链接进来后底层就会发送一个connection消息过来
后面的匿名函数就是收到connection消息时要执行的函数,参数socket就是接收到消息的socket
*/
io.sockets.on('connection',(socket)=>{
    // socket监听加入房间的消息(join是我们自己定义的加入房间的消息),room是要加入的房间
    socket.on('join',(room)=>{
        // 加入房间(如果是第一个用户还没有房间的话就会自动创建一个房间)
        socket.join(room);
        // 根据房间标示获取房间
        var myRoom = io.sockets.adapter.rooms[room];
        if (myRoom) {
            // 获取房间人数(myRoom.sockets是房间所有用户)
            var userNum = Object.keys(myRoom.sockets).length;
            logger.info("当前房间人数为:"+userNum);
        }
        // 加入房间成功后可以给客户端回一个消息,joined是加入成功的消息,room和socket.id是回的参数
        socket.emit('joined',room,socket.id); // 给他本人回
        // socket.to(room).emit('joined',room,socket.id); // 给房间里除了自己外的所有人回
        // io.in(room).emit('joined',room,socket.id); // 给房间里的所有人回(注意这里是io调用的)
        // socket.broadcast.emit('joined',room,socket.id); // 给除了自己外所有站点的人回
    });

    // socket监听离开房间的消息
    socket.on('leave',(room)=>{
        var myRoom = io.sockets.adapter.rooms[room];
        if (myRoom) {
            // 获取房间人数,离开房间后房间人数会-1
            var userNum = Object.keys(myRoom.sockets).length;
            logger.info("当前房间人数为:"+(userNum-1));
        }
        socket.leave(room);
        socket.emit('leaved',room,socket.id); // 给他本人回
        // socket.to(room).emit('leaved',room,socket.id); // 给房间里除了自己外的所有人回
        // io.in(room).emit('leaved',room,socket.id); // 给房间里的所有人回(注意这里是io调用的)
        // socket.broadcast.emit('leaved',room,socket.id); // 给除了自己外所有站点的人回
    });

    // socket监听发送消息
    socket.on('message',(room,data)=>{
        // 收到消息后将消息发给房间所有人
        io.in(room).emit('message',room,socket.id,data);
    });
});

https_server.listen(8083,'192.168.20.242');

二、创建前端页面

前端页面效果如下图所示。开始时"加入房间"按钮可以点击,"离开房间"、"发送消息"和两个消息框都是禁用的,加入房间成功后"加入房间"按钮禁用,其他按钮和消息框变成可用状态。


前端页面效果图

在public目录下创建一个index.html文件,代码内容如下

// 前端页面代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>webrtc实现简易聊天室</title>
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <!-- socket.io的js文件 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
</head>
<body>
    
    <div>
        <label>用户名:</label>
        <input type="text" id="username"></input>
    </div>

    <div>
        <label>房间号:</label>
        <input type="text" id="room"></input>
        <button id="joinBtn">加入房间</button>
        <button disabled id="leaveBtn">离开房间</button>
    </div>

    <div>
        <label>消息:</label>
        <br>
        <textarea disabled id="output" style="line-height: 1.5" rows="10" cols="100"></textarea>
    </div>

    <div>
        <label>输入框:</label>
        <br>
        <textarea disabled id="input" style="line-height: 1.5" rows="3" cols="100"></textarea>
        <br>
        <button disabled id="sendBtn">发送消息</button>
    </div>

    <script type="text/javascript" src="js/client.js"></script>
</body>
</html> 

三、前端JS文件

在public目录下新建一个js目录,在js目录下创建一个client.js文件,代码内容如下:

// 前端js文件代码


'use strict'

var outputBox = $("#output")[0];
var inputBox = $("#input")[0];
var socket;
var room;

// 点击加入房间按钮
$("#joinBtn").click(function(){
    room = $("#room").val();
    console.log('111');
    // io调用connect方法,底层会给信令服务器发送connection消息
    socket = io.connect();
console.log('222');
    // 监听消息
    //监听加入房间成功的消息(加入房间成功后信令服务器会回一个joined消息)
    socket.on('joined',(room,id)=>{
        // 加入房间成功后对改变前端页面控制的状态
        $("#joinBtn").attr('disabled',true);
        $("#leaveBtn").attr('disabled',false);
        $("#output").attr('disabled',false);
        $("#sendBtn").attr('disabled',false);
        $("#input").attr('disabled',false);
    })
    // 监听离开房间成功的消息(离开房间成功后信令服务器会回一个leaved消息)
    socket.on('leaved',(room,id)=>{
        // 离开房间成功后对改变前端页面控制的状态
        $("#joinBtn").attr('disabled',false);
        $("#leaveBtn").attr('disabled',true);
        $("#output").attr('disabled',true);
        $("#sendBtn").attr('disabled',true);
        $("#input").attr('disabled',true);
    });
    // 监听接收消息(有新消息时信令服务器会发一个message消息)
    socket.on('message',(room,id,data)=>{
        outputBox.scrollTop = outputBox.scrollHeight;//窗口总是显示最后的内容
        outputBox.value = outputBox.value + data + '\r';// 将新消息拼接在原消息后面
    });

    // 发送加入房间的消息
    socket.emit('join',room);
});

// 点击离开房间按钮
$("#leaveBtn").click(function(){
    // 发送离开房间的消息
    socket.emit('leave',room);
});

// 点击发送消息按钮
$("#sendBtn").click(function(){
    var data = $("#username").val()+":"+$("#input").val();
    // 发送消息,信令服务器收到消息后会将消息发给房间的每一个人
    socket.emit('message',room,data);
    $("#input").val('');
});

四、测试

多打开几个浏览器页面,在地址栏输入https://192.168.20.242:8083/index.html,也可以在手机端浏览器输入这个地址(由于是本地服务器,所以需要手机和电脑连的是同一个局域网才行),每个页面都输入不同的用户名和同一个房间名,然后点击'加入房间'按钮,加入成功后在输入框输入消息并发送,可以看到所有页面的消息框都可以收到消息。

聊天室测试效果
上一篇下一篇

猜你喜欢

热点阅读