代码共享是 的一个重要方面。 编程 随着远程工作和虚拟协作的兴起,开发人员需要可靠的代码共享工具来提供实时通信、视频和音频会议以及友好的用户界面。 就是这样一个例子。 Codeshare.io 但今天,我们要卷起袖子,使用 构建我们自己的代码共享游乐场。系好安全带! 🎢 Dyte 是一个对开发人员友好的平台,它提供强大的 SDK 以在我们的产品中构建实时体验。在此博客中,我们将带您完成使用 Dyte.io 和 ReactJs 构建代码共享平台的过程。开始吧! 🏃 Dyte.io 第 0 步:设置 Dyte 帐户 首先,我们需要设置一个 Dyte 帐户。为此,首先访问 Dyte.io,然后点击开始构建。在下一页上,使用 Google 或 GitHub 帐户登录以获取您的免费 Dyte 帐户 🎉。您将在左侧边栏的 API 密钥选项卡下找到您的 API 密钥。确保您的 API 密钥安全,不要与任何人共享。 第 1 步:设置环境 在我们深入编码之前再打一个检查点。 我们将使用 Node.js(一种流行的 JavaScript 运行时环境)和 create-react-app(一种使用预配置设置生成 React 项目的工具)。 首先,我们将创建三个文件夹 、 和 。 client server plugin 注意:🧑💻 如果您使用的是 Mac,您应该在系统设置中关闭“AirPlay Receiver”,因为它默认占用端口 5000。 仅供参考,这就是本博客末尾的 。 final folder structure 我们将继续使用下面的命令安装 CLI。 Dyte $ npm install -g @dytesdk/cli 继续授权部分并使用以下命令选择组织。 $ dyte auth login $ dyte auth org 有关详细信息,请访问 。 Dyte CLI 文档 第 2 步:设置新的自定义插件 要开始构建自定义 Dyte 插件,我们将使用以下命令克隆 。插件模板让我们可以更快上手。 Dyte Plugin Template $ git clone https://github.com/dyte-in/react-plugin-template.git 该模板使用 并允许我们创建自己的实时插件,与 Dyte 会议无缝协作。它有很多有趣的功能可以帮助我们在几分钟内解决复杂的问题。现在,我们将使用“npm install”命令安装依赖项。 @dytesdk/plugin-sdk $ npm install 接下来,我们将通过运行以下命令添加几个依赖项。 $ npm i @uiw/react-codemirror @codemirror/lang-javascript uuid 在这里,我们添加了 ,它提供了一个带有语言支持的预构建代码编辑器。我们还安装了 UUID,这将帮助我们通过函数调用生成 UUID。这很快就会派上用场。 react-codemirror 现在我们已经设置好了所有内容,我们可以使用此命令来启动和测试我们的自定义插件设置。 $ npm start 第 3 步:试用我们的新自定义插件 要尝试使用我们新的自定义插件,我们必须访问 http://staging.dyte.io 在这里,系统会提示我们创建一个新会议。非常简单,只需添加您的姓名和会议名称,然后点击 。在下一页上,它会要求您 会议。点击加入,你就进去了。 Create join 在右下角找到 按钮,然后单击它以显示所有现有插件。我们对名为的插件感兴趣,点击 它会在会议中显示您的插件🤯。 Plugins launch 我们已经准备好了一切。现在,我们可以开始编写一些实际代码了! 让我们从我们的代码编辑器组件开始。 第 4 步:创建我们的代码编辑器 让我们开始创建我们自己的代码编辑器🧑💻。 为此,我们将首先创建一个组件,然后使用我们之前安装的 包。首先,在 中名为 文件中创建一个新的 ,并粘贴以下代码。 CodeMirror src/containers CodeEditor.js React Functional Component <CodeMirror style={{ fontSize: "32px", textAlign: "left" }} value={code} onChange={handleCodeChange} height="100vh" width="100vw" theme={'dark'} extensions={[javascript({ jsx: true })]}/> CodeMirror 组件提供了一个预建的代码编辑器。它带有各种语法突出显示功能。 第 5 步:处理代码更改 为了处理实时代码更改,让我们首先创建一个名为 的新状态 code import { useEffect, useState, useRef } from "react"; const [code, setCode] = useState("function add(a, b) { return a + b;}"); 现在,我们将创建一个 函数,只要使用 函数在 中的代码发生更改,它就会发出事件。 handleCodeChange plugin.emit() CodeMirror 在这里,我们正在发射一个具有两个属性的对象。第一个是随机生成的 ,第二个是我们的整个代码。 user id import { useEffect, useState, useRef } from "react"; import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; const CodeEditor = ({ plugin }) => { const [code, setCode] = useState("function add(a, b) {return a + b;}"); const [userId, setUserId] = useState() const handleCodeChange = async (code) => { plugin.emit(`CODE_CHANGE`, { code, user }) } return ( <> <CodeMirror style={{ fontSize: "32px", textAlign: "left" }} value={code} onChange={handleCodeChange} height="100vh" width="100vw" theme={'dark'} extensions={[javascript({ jsx: true })]} /> </> ); } export default CodeEditor; 第 6 步:监听代码更改事件 当其他人更改代码时,我们需要监听事件。为此,我们将使用 函数,如下所示。该函数接受 作为参数并接收代码更改。 plugin.on() event name 这里要注意的另一件事是,只有当它是由其他用户发送时,我们才必须更新我们当前的代码。为此,我们需要放置一个简单的条件语句 if(data.user != userId){} import { useEffect, useState, useRef } from "react"; import CodeMirror from '@uiw/react-codemirror'; import { javascript } from '@codemirror/lang-javascript'; import {v4} from 'uuid'; const user = v4() const CodeEditor = ({ plugin }) => { const [code, setCode] = useState("function add(a, b) {\n return a + b;\n}"); const [userId, setUserId] = useState() useEffect(() => { if (plugin) { const startListening = async () => { plugin.on(`CODE_CHANGE`, (data) => { if(data.user != user) { setCode(data.code) } }); } startListening() } }, [plugin]) const handleCodeChange = async (code) => { plugin.emit(`CODE_CHANGE`, { code, user }) } return ( <> <CodeMirror style={{ fontSize: "32px", textAlign: "left" }} value={code} onChange={handleCodeChange} height="100vh" width="100vw" theme={'dark'} extensions={[javascript({ jsx: true })]} /> </> ); } export default CodeEditor; 在这个组件中,我们使用 CodeMirror 创建一个代码编辑器。使用 函数调用,对编辑器的任何更改都会向会议中的所有用户发出一个事件 。 函数将 和 作为参数。 plugin.emit() CODE_CHANGE emit eventName data 在下一步中,我们需要将 CodeEditor 组件导入到 文件中。您的文件应如下所示。 👇 Main.tsx import { useDytePlugin } from '../context' import CodeEditor from './CodeEditor'; const Main = () => { const plugin = useDytePlugin(); return ( <div style={{ height: "100%" }}> <CodeEditor plugin={plugin} /> </div> ) } export default Main 我们的“协作代码编辑器插件”的代码 😉 现已准备就绪。没有代码编辑器,第一个代码编辑器是怎么写出来的😂?开个玩笑,我们已经准备好我们的插件 🎉。 要结帐,请打开 并继续操作。输入您的姓名和会议标题以加入会议。点击加入会议。打开 插件,一切顺利。 staging.dyte.io Localhost Dev 第 7 步:发布我们的组件 🧑💻 现在,是时候发布我们的内容了,这是一个使用 的简单过程。为此,我们必须首先构建我们的插件,然后运行 命令。 Dyte CLI dyte plugins publish $ dyte plugins create $ npm run build $ cp dyte-config.json ./build/dyte-config.json $ cd build $ dyte plugins publish 第 8 步:开始使用我们的代码共享平台 现在我们已经构建了有助于我们在代码上进行协作的插件,我们可以开始构建使用该插件的平台。 让我们从客户端开始。在 文件夹中,我们将使用 设置一个新的 项目,并使用以下命令创建我们的 React 应用程序。 client create-react-app ReactJS $ npx create-react-app . 接下来,让我们通过运行以下命令来安装 和 的依赖项: Dyte code-editor $ npm i @dytesdk/react-ui-kit @dytesdk/react-web-core react-simple-code-editor 🎬 现在,让我们使用 npm start 启动我们的开发服务器: $ npm start 第 9 步:构建布局 让我们打开 文件夹中的 文件。我们将删除此文件的内容并添加以下代码片段👇。 src app.js import Layout from './components/Layout' function App() { return ( <Layout /> ); } export default App; 接下来,我们将编写 组件,我们将使用我们的徽标、标题和会议 UI 创建布局。 Layout 我们将使用多个库(包括 和 PrismJS)来构建协作代码编辑器和会议 UI。 DyteMeeting import Meet from "./Meeting" const Layout = () => { return ( <> <div style={{ padding: "30px", display: "flex", justifyContent: "space-between", alignItems: "center" }}> <img src="https://dyte.io/blog/content/images/2021/09/Dyte-Logo.svg" height={"70px"}/> <span style={{ fontSize: "30px", color: "#3e75fd" }}>Collaborative Code Editor</span> <img style={{ opacity: "0"}} src="https://dyte.io/blog/content/images/2021/09/Dyte-Logo.svg" height={"80px"}/> </div> <div style={{ height: "88vh" }} ><Meet /></div> </> ) } export default Layout 第 10 步:会议组件 🧑💻 首先,我们需要在文件 中创建一些实用函数 client/src/utils/api.js const createMeeting = async () => { const resp = await fetch("http://localhost:3000/meetings", { method: "POST", body: JSON.stringify({ title: "New Code pair" }), headers: { "Content-Type": "application/json" } }) const data = await resp.json() console.log(data) return data.data.id; } const joinMeeting = async (id) => { const resp = await fetch(`http://localhost:3000/meetings/${id}/participants`, { method: "POST", body: JSON.stringify({ name: "new user", preset_name: "group_call_host" }), headers: { "Content-Type": "application/json" } }) const data = await resp.json() console.log(data) return data.data.token; } export { createMeeting, joinMeeting } 这些功能与我们的后端对话以创建会议和添加参与者。对于会议创建,我们将 作为可选参数传递。 title 为了添加参与者,我们将 参数(可选)、 参数(可选)和 参数(必需)与 一起传递。 name picture preset_name meetingId 我们的会议组件的时间。为此,我们将使用 Dyte UI 工具包 ✨,它可以非常轻松地将实时音频/视频共享集成到您的应用程序中。是的,这 10-15 行代码完成了所有繁重的工作🏋🏼♂️。 import { useState, useEffect, useRef } from "react"; import { DyteMeeting, provideDyteDesignSystem } from "@dytesdk/react-ui-kit"; import { useDyteClient } from "@dytesdk/react-web-core"; import { createMeeting, joinMeeting } from "../utils/api"; const Meet = () => { const meetingEl = useRef(); const [meeting, initMeeting] = useDyteClient(); const [userToken, setUserToken] = useState(); const [meetingId, setMeetingId] = useState(); const createMeetingId = async () => { const newMeetingId = await createMeeting(); setMeetingId(newMeetingId); }; useEffect(() => { const id = window.location.pathname.split("/")[2]; if (!id) { createMeetingId(); } else { setMeetingId(id); } }, []); const joinMeetingId = async () => { if (meetingId) { const authToken = await joinMeeting(meetingId); await initMeeting({ authToken, modules: { plugin: true, devTools: { logs: true, plugins: [ { name: "Collaborative-code-editor", port: "5000", id: "<your-plugin-id>", }, ], }, }, }); setUserToken(authToken); } }; useEffect(() => { if (meetingId && !userToken) joinMeetingId(); }, [meetingId]); useEffect(() => { if (userToken) { provideDyteDesignSystem(meetingEl.current, { theme: "dark", }); } }, [userToken]); return ( <> {userToken && meetingId ? ( <DyteMeeting mode="fill" meeting={meeting} ref={meetingEl} /> ) : ( <div>Loading...</div> )} </> ); }; export default Meet; 我们现在已经准备好代码共享平台的 UI 🎉 第 11 步:准备好后端 🧑💻 Dyte提供了多种强大的API,提升开发者体验,满足广泛的开发者需求。 我们可以管理 Dyte 的组织、会议、会议、录音、webhook、直播、分析等等。 为了简化流程,我们将使用 Express with Node 创建一个后端,这将有助于身份验证、会议创建和添加参与者。 ✨ 要在项目文件夹中开始,请按照以下步骤操作: $ mkdir server && cd server 我们将从安装几个依赖项开始,cd 进入“服务器”目录,然后使用以下命令。 $ npm init -y $ npm install express cors axios dotenv $ npm install -g nodemon 首先,让我们创建一个 文件来将我们的 API 密钥存储在 中。您可以在 Dyte Dashboard 上找到这些密钥。 .env server/src DYTE_ORG_ID=<ID> DYTE_API_KEY=<KEY> 我们还添加一些脚本 ✍️ 来帮助我们运行我们的 应用程序。在您的 文件中的 标签内添加以下行。 server package.json scripts "start": "node dist/index.js", "dev": "nodemon src/index.js" 现在让我们创建我们的文件和文件夹。我们所有的代码都将位于 文件夹中。在 中创建另一个文件夹 。 server/src src utils 在 中初始化文件 ,在 中初始化 。现在让我们在 中添加我们的 文件,它将保存我们的 API 机密。 src index.js utils dyte-api.js src .env 打开 文件并向其中添加以下行。将占位符值替换为来自 Dyte 仪表板的 API 机密。 src/.env DYTE_ORG_ID=<YOUR-DYTE-ORG-ID> DYTE_API_KEY=<YOUR-DYTE-API-KEY> 我们现在可以开始编写代码了。让我们从创建用于访问 Dyte API 的 配置开始。 axios 打开 并输入以下代码。 utils/dyte-api.js 此代码将有助于与 Dyte API 和身份验证进行通信。 const axios = require('axios'); require('dotenv').config(); const DYTE_API_KEY = process.env.DYTE_API_KEY; const DYTE_ORG_ID = process.env.DYTE_ORG_ID; const API_HASH = Buffer.from( `${DYTE_ORG_ID}:${DYTE_API_KEY}`, 'utf-8' ).toString('base64'); const DyteAPI = axios.create({ baseURL: 'https://api.cluster.dyte.in/v2', headers: { Authorization: `Basic ${API_HASH}`, }, }); module.exports = DyteAPI; 接下来,我们将编写路由。 我们的前端将在这些路由上进行通信以创建会议并将参与者添加到会议中。 让我们打开 并添加以下代码片段。👇 index.js const express = require('express'); const cors = require('cors'); const DyteAPI = require('./utils/dyte-api') const PORT = process.env.PORT || 3000; const app = express(); app.use(cors("http://localhost:3001")); app.use(express.json()); app.post('/meetings', async (req, res) => { const { title } = req.body const response = await DyteAPI.post('/meetings', { title, }); return res.status(response.status).json(response.data); }); app.post('/meetings/:meetingId/participants', async (req, res) => { const meetingId = req.params.meetingId const { name, picture, preset_name } = req.body const client_specific_id = `react-samples::${name.replaceAll(' ', '-')}-${Math.random().toString(36).substring(2, 7)}`; const response = await DyteAPI.post(`/meetings/${meetingId}/participants`, { name, picture, preset_name, client_specific_id, }); return res.status(response.status).json(response.data); }); app.listen(PORT, () => { console.log(`Started listening on ${PORT}...`) }); 哒哒! 🎩✨ 我们做到了! 现在,我们终于可以尝试我们的代码共享平台,以便在与我们的朋友和队友编码时进行协作。 有了我们闪亮的新代码编辑器和 Dyte 满足所有设置,我们终于可以试用我们的平台了! 要在本地运行整个应用程序: 内部客户端类型 PORT=3001 npm start 内部插件类型 npm start 内部服务器类型 PORT=3000 npm run dev 就这样,应用内视频会议和与我们自己的“代码协作插件”的协作。 🧑💻可以试试代码分享平台 . 这里 结论 🎉哇哦!你已经走到最后了,我的朋友!我希望你今天学到了一两件事,并且一路上玩得很开心。 我们一起建立了一个时髦的实时结对编程和代码共享平台,完成了应用程序内的会议,所有这些都只需要一点 React 和一团 Dyte。谈论成功的秘诀! 我们用我们的插件模板和强大的 SDK 为您提供支持,让您轻松投入并构建您自己的协作杰作,就像我们今天一起制作的那样。 你还在等什么?前往 ,让您的创意源源不断!开始构建您自己的协作应用程序,您可能会创造下一件大事! 🚀 Dyte.io