node服务端使用socket.io实现简单实时视频一对一webrtc通讯

1. 首先新建一个node项目

步骤:创建空文件夹 > 终端输入 npm init -y > 安装依赖 express  cors  socket.io(npm install express cors  socket.io )

文化目录

 

创建index.js入口文件

//引入模块
const express = require('express');
const http = require('http');
const cors = require('cors');
const https = require('https')
const fs = require("fs");
const path = require("path");


//初始化
const app = express();

const cred = {
  key: fs.readFileSync(path.resolve(__dirname, './172.168.1.150.key')),
  cert: fs.readFileSync(path.resolve(__dirname, './172.168.1.150.crt'))
}

const server = https.createServer(cred,app);

app.use(cors());

//初始化io
const io = require('socket.io')(server, {
  cors: {
    origin: '*',
    methods: ['GET', 'POST'],
  },
});

//服务器socket连接
io.on('connection', (socket) => {
  socket.emit('me', socket.id);
  //断开通信
  socket.on('disconnect', () => {
    socket.broadcast.emit('callEnded');
  });

  socket.on('callUser', (data) => {
    //将数据传递给通信的接听方
    io.to(data.userToCall).emit('callUser', {
      signal: data.signalData,
      from: data.from,
      name: data.name,
    });
  });

  socket.on('answerCall', (data) => {
    //将数据传递给通信的发起方
    io.to(data.to).emit('callAccepted', data.signal);
  });
});

server.listen(5001, () => {
  console.log('服务器正在5001端口号运行....');
});

证书文件获取:前端开发本地搭建https环境_寂静狂想曲的博客-CSDN博客_前端使用https

终端运行 node ./index.js

运行成功

2. 准备vue前端页面

<template>
  <div id="app">
    <div>第一步:</div>
    <div>
      请先给自己取个名字吧:<input type="text" v-model="myName">
    </div>
    <div>
      这是你的id,想让别人call你的话就复制下来发给需要TA的人吧:  {{socketID}}
    </div>
    <br/>
    <div>第二步:</div>
    <div>
      你要call别人吗?那就输入对方id吧: <input type="text" v-model="userSocketID">
    </div>

    <br/>
    <div>第三步:</div>
    <div>
      <button class="call_btn" @click="callClick()">要是想call TA 就点我吧</button>
      <div style="display:flex;">
        <div>
          <div>提示:</div>
          <img style="height:300px;width: 500px;" src="../assets/1.jpg">
        </div>
        <div style="margin-left:20px;">
          <div>不要点取消,点取消就会弹这个,那就再点一次 call TA</div>
          <img style="height:300px;width: 300px;" src="../assets/2.jpg">
        </div>
      </div>
    </div>


    <div class="user_row">
      <div class="user_nav">
        <div>{{myName}}</div>
        <div class="video_item">
          <video autoplay ref="user_video" controls></video>
        </div>
      </div>

      <div class="user_nav">
        <div>{{otherName}}</div>
        <div class="video_item">
          <video autoplay ref="userTwo_video" controls></video>
        </div>
      </div>

      <div>
        <button style="margin-left:20px;height: 300px;width: 300px;" v-show="isAnswerShow" @click="answerCall()">来电话了,点击接听 ,大一点才看的见</button>
      </div>
    </div>


  </div>
</template>

<script>
const Peer = require("simple-peer");
import io from 'socket.io-client';
export default {
  name: "App",
  data() {
    return {
      myName: '',
      otherName: '',
      socket: null,
      socketID: '',
      userSocketID: '',
      curStream: null,
      userStream: null,
      isAnswerShow: false,
      caller: null,
      callerSignal: null,
    };
  },
  created() {
    try {
      this.socket = io.connect('https://172.168.1.148:5001')
    } catch (error) {
      alert(error)
    }
  },
  mounted() {
    this.getSocketId()
  },
  methods: {
    getSocketId() {
      this.socket.on('me', (res) => {
        this.socketID = res
      });
      //接听方获取从服务器传递的发起方数据
      this.socket.on('callUser', (data) => {
        console.log('来电了,拨打发信息',data);
        if(data) {
          this.isAnswerShow = true
          this.caller = data.from
          this.callerSignal = data.signal
        }
      });
    },

    // 点击拨打电话
    async callClick() {
      if(!this.myName) {
        alert('你为什么不给自己取名字???')
        return
      }
      if(!this.userSocketID) {
        alert('call TA 就要填TA的id呀,伤脑筋')
        return
      }

      var options = {
        audio: true,
        video: true,
      }
      try {
        this.curStream = await navigator.mediaDevices.getDisplayMedia(options)
        this.$refs.user_video.srcObject = this.curStream
      }catch(err) {
        alert('点分享呀')
        return
      }

      //实例化对等连接对象
      var peer = new Peer({
        initiator: true,
        stream: this.curStream,
        trickle: false,
      });

      //传递信令数据
      peer.on('signal', (data) => {
        this.socket.emit('callUser', {
          userToCall: this.userSocketID,
          signalData: data,
          from: this.socketID,
          name: this.myName,
        });
      });

      //获取对方的stream
      peer.on('stream', (stream) => {
        console.log(stream);
        this.$refs.userTwo_video.srcObject = stream
      });

      //当接听方同意通话后获取信令
      this.socket.on('callAccepted', (signal) => {
        peer.signal(signal);
      });
    },

    // 点击接听电话
    async answerCall() {
      var constraints = {
        audio: true,
        video: true
      }
      var screen = await navigator.mediaDevices.getDisplayMedia(constraints)
      this.$refs.userTwo_video.srcObject = screen
      this.userStream = screen
      
      var peer = new Peer({
        initiator: false,
        stream: this.userStream,
        trickle: false,
      });

      peer.on('signal', (data) => {
        this.socket.emit('answerCall', {
          signal: data,
          to: this.caller,
        });
      });

       peer.on('stream', (stream) => {
        this.$refs.user_video.srcObject = stream
      });

      peer.signal(this.callerSignal);
    },

  },
};
</script>

<style>
.user_row {
  margin-top: 20px;
  display: flex;
}
.user_nav {
  margin-right: 20px;
}
.video_item {
  display: block;
  height: 200px;
  width: 200px;
  border: 1px solid #333;
}

.video_item > video {
  height: 100%;
  width: 100%;
  object-fit: fill;
}

.call_btn {
  margin-top: 10px;
}
</style>

const fs = require("fs");

module.exports = {
  devServer: {
    https: true,
    key: fs.readFileSync('./172.168.1.150.key'),
    cert: fs.readFileSync('./172.168.1.150.crt')
  }
};

 

这样就可以在局域网内与小伙伴一对一屏幕共享聊天了,注意:此示例为屏幕共享流,如换成摄像头需要navigator.mediaDevices.getDisplayMedia() 函数改为navigator.mediaDevices.getUserMedia()函数 具体文档地址MediaDevices.getUserMedia() - Web APIs | MDN

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.项目代码功能经验证ok,确保稳定可靠运行。欢迎下载使用! 2.主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时私信沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源说明】 基于Nodejs与Electron实现仿TIM界面简单聊天软件源码(含添加好友、群聊、语音视频通话等功能)+使用说明.zip 是基于`electron(vue2)`和`nodejs`实现简单聊天软件,其中用`websocket`和`http`进行通讯传递,数据库使用了`mysql`数据库,该项目功能简单,界面简洁,适合正在练习`websocket`和`vue`的小白查看代码,代码量极少且逻辑清晰,每个功能都会添加相应的逻辑供大家观看学习(大佬勿喷) 基于Nodejs与Electron实现仿TIM界面简单聊天软件源码(含添加好友、私聊、群聊、语音视频通话等功能)+使用说明.zip基于Nodejs与Electron实现仿TIM界面简单聊天软件源码(含添加好友、私聊、群聊、语音视频通话等功能)+使用说明.zip基于Nodejs与Electron实现仿TIM界面简单聊天软件源码(含添加好友、私聊、群聊、语音视频通话等功能)+使用说明.zip 基于Nodejs与Electron实现仿TIM界面简单聊天软件源码(含添加好友、私聊、群聊、语音视频通话等功能)+使用说明.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值