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