前言
WebRTC 是一种实时通信技术,可以在浏览器中实现音视频通信。本文将介绍如何基于 Fastify 框架实现 WebRTC 视频聊天室。
准备工作
在开始实现之前,我们需要准备一些工作:
- 安装 Node.js 和 npm
- 安装 Fastify 框架和相关插件
- 安装 Webpack 和相关插件
- 安装 Socket.io 和相关插件
实现步骤
1. 创建项目
首先,我们需要创建一个新的项目。可以使用以下命令:
mkdir webrtc-chat cd webrtc-chat npm init -y
2. 安装依赖
安装 Fastify 和相关插件:
npm install fastify fastify-static fastify-websocket --save
安装 Webpack 和相关插件:
npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev
安装 Socket.io 和相关插件:
npm install socket.io socket.io-client --save
3. 创建服务器
创建一个 server.js
文件,使用 Fastify 框架创建一个服务器:
// javascriptcn.com 代码示例 const fastify = require('fastify')({ logger: true }); fastify.register(require('fastify-static'), { root: __dirname, }); fastify.register(require('fastify-websocket')); fastify.get('/', (req, reply) => { reply.sendFile('index.html'); }); fastify.listen(3000, (err, address) => { if (err) { fastify.log.error(err); process.exit(1); } fastify.log.info(`server listening on ${address}`); });
这个服务器会监听 3000
端口,并在根目录下提供静态文件服务。
4. 创建前端页面
在根目录下创建一个 index.html
文件,用来作为聊天室的前端页面:
// javascriptcn.com 代码示例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>WebRTC Chat Room</title> </head> <body> <h1>WebRTC Chat Room</h1> <div id="videos"></div> <form id="message-form"> <input type="text" id="message-input" /> <button type="submit">Send</button> </form> <script src="bundle.js"></script> </body> </html>
这个页面包含一个视频容器和一个文本框,用于输入聊天内容。
5. 创建客户端脚本
创建一个 client.js
文件,用来处理客户端的逻辑:
// javascriptcn.com 代码示例 const socket = io(); const videoContainer = document.getElementById('videos'); const messageForm = document.getElementById('message-form'); const messageInput = document.getElementById('message-input'); const localVideo = document.createElement('video'); localVideo.muted = true; localVideo.autoplay = true; navigator.mediaDevices .getUserMedia({ video: true, audio: true }) .then((stream) => { localVideo.srcObject = stream; videoContainer.appendChild(localVideo); socket.emit('join', { username: 'me', room: 'room1' }); }) .catch((err) => { console.log(err); }); socket.on('user-connected', (userId) => { console.log('User connected:', userId); }); socket.on('user-disconnected', (userId) => { console.log('User disconnected:', userId); }); messageForm.addEventListener('submit', (event) => { event.preventDefault(); const message = messageInput.value; socket.emit('message', { message }); messageInput.value = ''; }); socket.on('message', (data) => { console.log('Message received:', data); });
这个脚本会使用 getUserMedia
方法获取本地视频和音频流,并将其显示在页面上。然后使用 Socket.io 连接到服务器,并加入房间。当有用户连接或断开连接时,会在控制台输出相应信息。当用户输入聊天内容时,会将其发送到服务器,并在控制台输出收到的消息。
6. 创建 Webpack 配置文件
创建一个 webpack.config.js
文件,用来配置 Webpack:
// javascriptcn.com 代码示例 const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './client.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, plugins: [ new HtmlWebpackPlugin({ template: 'index.html', }), ], devServer: { contentBase: './dist', hot: true, port: 8080, }, };
这个配置文件会将 client.js
文件打包到 dist/bundle.js
文件中,并在 dist/index.html
中自动引入。同时配置了一个开发服务器,可以在浏览器中访问 http://localhost:8080
来预览聊天室。
7. 实现 WebRTC
现在我们已经有了一个可以发送和接收消息的聊天室,但是还没有实现 WebRTC 的功能。为了实现 WebRTC,我们需要使用一些额外的库。
首先安装 simple-peer
和 wrtc
:
npm install simple-peer wrtc --save
然后修改 client.js
文件,添加 WebRTC 相关的代码:
// javascriptcn.com 代码示例 const SimplePeer = require('simple-peer'); let peers = {}; socket.on('user-connected', (userId) => { console.log('User connected:', userId); const peer = new SimplePeer({ initiator: true, trickle: false, stream: localVideo.srcObject, }); peer.on('signal', (data) => { socket.emit('offer', { userId, offer: data }); }); peer.on('connect', () => { console.log('Connected to peer:', userId); }); peer.on('stream', (stream) => { const remoteVideo = document.createElement('video'); remoteVideo.srcObject = stream; remoteVideo.autoplay = true; remoteVideo.addEventListener('loadedmetadata', () => { remoteVideo.play(); }); videoContainer.appendChild(remoteVideo); }); peer.on('close', () => { console.log('Disconnected from peer:', userId); videoContainer.removeChild(videoContainer.lastChild); delete peers[userId]; }); peers[userId] = peer; }); socket.on('user-disconnected', (userId) => { console.log('User disconnected:', userId); if (peers[userId]) { peers[userId].destroy(); } }); socket.on('offer', (data) => { console.log('Offer received:', data); const peer = new SimplePeer({ initiator: false, trickle: false, stream: localVideo.srcObject, }); peer.on('signal', (answer) => { socket.emit('answer', { userId: data.userId, answer }); }); peer.on('connect', () => { console.log('Connected to peer:', data.userId); }); peer.on('stream', (stream) => { const remoteVideo = document.createElement('video'); remoteVideo.srcObject = stream; remoteVideo.autoplay = true; remoteVideo.addEventListener('loadedmetadata', () => { remoteVideo.play(); }); videoContainer.appendChild(remoteVideo); }); peer.on('close', () => { console.log('Disconnected from peer:', data.userId); videoContainer.removeChild(videoContainer.lastChild); delete peers[data.userId]; }); peer.signal(data.offer); peers[data.userId] = peer; }); socket.on('answer', (data) => { console.log('Answer received:', data); const peer = peers[data.userId]; if (peer) { peer.signal(data.answer); } });
这段代码会在有新用户连接时创建一个 SimplePeer
对象,并将本地视频流发送给对方。同时监听 signal
事件,将自己的信令发送给服务器。当收到其他用户的信令时,会创建一个新的 SimplePeer
对象,并使用 signal
方法传递对方的信令。当连接建立后,会在页面上显示远程视频流。
总结
本文介绍了如何基于 Fastify 实现 WebRTC 视频聊天室。我们使用了 Socket.io 和 SimplePeer
等库来实现实时通信和 WebRTC 功能。这些技术可以应用于各种实时应用,如在线游戏、视频会议等。希望本文能对读者有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/650921f795b1f8cacd3ea034