使用 Vue 3 和 WebRTC 来实现一个简单的点对点聊天应用,服务端使用 WebSocket (ws) 来建立信令服务器,用于连接和交换 WebRTC 所需的 SDP 和 ICE 候选信息。
1. 项目初始化
首先,我们创建一个基于 Vue 3 的项目:
npm init vue@latest webrtc-chat
cd webrtc-chat
npm install
然后,安装 WebSocket 依赖:
npm install ws
2. 创建 WebSocket 信令服务器
我们使用 Node.js 和 ws
模块来创建信令服务器:
// server.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
ws.on('message', (message) => {
// 将消息广播给其他客户端
wss.clients.forEach((client) => {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
});
// 向新连接的客户端发送欢迎消息
ws.send(JSON.stringify({ type: 'welcome', message: 'Connected to WebSocket server' }));
});
console.log('WebSocket server is running on ws://localhost:8080');
运行服务器:
node server.js
3. 创建 Vue 3 应用
在 src
文件夹中创建 components/Chat.vue
组件。
<template>
<div>
<h2>点对点聊天</h2>
<textarea v-model="message" placeholder="输入消息..."></textarea>
<button @click="sendMessage">发送</button>
<button @click="createOffer">发送 Offer</button>
<div v-for="(msg, index) in messages" :key="index">{{ msg }}</div>
</div>
</template>
<script>
export default {
data() {
return {
message: '',
messages: [],
peerConnection: null,
dataChannel: null,
ws: null
};
},
mounted() {
this.initializeWebSocket(); // 初始化 WebSocket
this.initializePeerConnection(); // 初始化 PeerConnection
},
methods: {
// 初始化 WebSocket 连接
initializeWebSocket() {
this.ws = new WebSocket('ws://localhost:8080');
// 接收来自信令服务器的消息
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'offer') {
this.handleOffer(data); // 处理接收到的 Offer
} else if (data.type === 'answer') {
this.handleAnswer(data); // 处理接收到的 Answer
} else if (data.type === 'candidate') {
this.addIceCandidate(data); // 添加接收到的 ICE 候选
}
};
},
// 初始化 PeerConnection 和数据通道
initializePeerConnection() {
this.peerConnection = new RTCPeerConnection();
// 监听 ICE 候选事件
this.peerConnection.onicecandidate = (event) => {
if (event.candidate) {
this.ws.send(JSON.stringify({
type: 'candidate',
candidate: event.candidate
})); // 将 ICE 候选发送到信令服务器
}
};
// 创建数据通道
this.dataChannel = this.peerConnection.createDataChannel('chat');
this.dataChannel.onmessage = (event) => {
this.messages.push(`Peer: ${event.data}`); // 接收消息并更新聊天记录
};
// 监听远程数据通道
this.peerConnection.ondatachannel = (event) => {
this.dataChannel = event.channel;
this.dataChannel.onmessage = (event) => {
this.messages.push(`Peer: ${event.data}`);
};
};
},
// 创建并发送 Offer
async createOffer() {
const offer = await this.peerConnection.createOffer();
await this.peerConnection.setLocalDescription(offer);
this.ws.send(JSON.stringify({ type: 'offer', sdp: offer })); // 发送 Offer
},
// 处理接收到的 Offer
async handleOffer(data) {
await this.peerConnection.setRemoteDescription(new RTCSessionDescription(data.sdp));
const answer = await this.peerConnection.createAnswer();
await this.peerConnection.setLocalDescription(answer);
this.ws.send(JSON.stringify({ type: 'answer', sdp: answer })); // 发送 Answer
},
// 处理接收到的 Answer
async handleAnswer(data) {
await this.peerConnection.setRemoteDescription(new RTCSessionDescription(data.sdp));
},
// 添加接收到的 ICE 候选
async addIceCandidate(data) {
if (data.candidate) {
await this.peerConnection.addIceCandidate(new RTCIceCandidate(data.candidate));
}
},
// 发送消息
sendMessage() {
if (this.dataChannel && this.message) {
this.dataChannel.send(this.message); // 通过数据通道发送消息
this.messages.push(`Me: ${this.message}`); // 更新本地聊天记录
this.message = ''; // 清空输入框
}
}
}
};
</script>
<style>
textarea {
width: 100%;
height: 100px;
margin-bottom: 10px;
}
button {
display: block;
margin-bottom: 10px;
}
</style>
4. 启动应用
运行以下命令以启动 Vue 应用:
npm run dev
打开浏览器开两个窗口访问 http://localhost:3000
,点击发送offer即可进行实时的点对点聊天。
评论 (0)