Remix 是一个基于 React 的全栈式 Web 框架,利用分布式系统进行部署。Remix 的独特之处在于它从服务器加载数据和预渲染网页的方式。
对于 React 这样的纯客户端框架来说,这种方式有点奇怪。我们会使用服务器从加密凭证中生成 Token,并在声网 Web UIKit 这个客户端库中使用它们。
前期准备
- 声网开发者账户(点击这里免费注册)
- Node.js LTS
- 对 React 框架有深度了解
设置
创建一个新的 Remix 项目
大家可以在 GitHub 上找到完成版项目。创建 Remix 项目的步骤:打开终端,执行 npx create-remix@latest demo,选择下列选项,得到一个用 TypeScript 编写的基本 app 模板:
❯ npx create-remix@latest demo
? What type of app do you want to create? Just the basics
? Where do you want to deploy? Choose Remix if you're unsure, it's easy to change deployment targets. Remix App Server
? TypeScript or JavaScript? TypeScript
? Do you want me to run `npm install`? Yes
键入 cd demo,进入项目目录。执行下列代码,安装声网 Web UIKit 和 token 库:
注意:撰写本文时 agora-react-uikit 的最新版本是 v1.1.0。
npm i agora-react-uikit agora-access-token
设置声网证书
登录声网开发者账户,在声网控制台点击 Project Management tab;
- 点击“创建”;
- 输入项目名称;
- 选择安全模式;
- 将 .env.example 文件重命名为 .env.;
- 从声网项目页面复制你的 App ID 和 App 证书,如下:
APP_ID=c0cXXXXXXXXXXX
CERTIFICATE=c18XXXXXXXXXXX
设置完成!现在你可以执行 npm run dev,在 localhost:3000 上启动 Remix 服务器。
项目结构
模板结构如下:
├── app
│ ├── entry.client.tsx
│ ├── entry.server.tsx
│ ├── root.tsx
│ └── routes
│ └── index.tsx
├── package.json
├── public
│ ...
开始 Coding
Remix 的其中一个突出特点是嵌套路由。我们为视频通话创建一个动态路由,这样你就会有一个example.com/channel/<channelName>,进入同一 <channelName> 的用户可以相互交流。该路由从我们的声网凭证中生成并托管 Token。你可以增加一个安全层,限制认证用户对 /channel 路由的访问。
使用 Remix 和声网 Web UIKit,只需几分钟就可以将项目上线!
创建动态路由
要在 example.com/channel/<yourChannelName> 上托管动态视频通话,我们需要为该路由创建一个新文件 /app/routes/channel/$channel.tsx:
import { RtcRole, RtcTokenBuilder, RtmRole, RtmTokenBuilder } from "agora-access-token";
import { useEffect, useState } from "react";
import { json, LoaderFunction, useLoaderData } from "remix";
import Videocall from '~/components/videocall.client'
export type loaderData = {
rtcToken: string;
rtmToken: string;
appId: string;
channel: string;
username: number;
}
export const loader: LoaderFunction = async ({params}) => {
const { APP_ID, CERTIFICATE } = process.env as unknown as { APP_ID: string, CERTIFICATE: string }
console.log(APP_ID, CERTIFICATE)
const channel = params.channel as string
const username = Date.now()
const time = Math.floor(username / 1000) + 600
const rtcToken = RtcTokenBuilder.buildTokenWithUid(APP_ID, CERTIFICATE, channel, 0, RtcRole.PUBLISHER, time)
const rtmToken = RtmTokenBuilder.buildToken(APP_ID, CERTIFICATE, String(username), RtmRole.Rtm_User, time)
const data: loaderData = { rtcToken, appId: APP_ID, channel, rtmToken, username }
return json(data);
};
...
要生成视频通话组件的道具,需要创建一个 loader 函数,该函数使用 .env 文件中的 App ID 和证书生成 RTC 和 RTM Token。我们从 params 道具中获得路由 channel 的名称,从 data 对象中创建一个 JSON 字符串,从 loader 函数返回:
...
export default function Index() {
const [mounted, setMounted] = useState(false);
const jsonData: loaderData = useLoaderData()
const { rtcToken, rtmToken, appId, channel, username } = jsonData
useEffect(() => {
setMounted(true);
}, []);
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
<h1>Videocall</h1>
<div style={{ display: 'flex', flex: 1 }}>
{mounted && <Videocall appId={appId} channel={channel} rtcToken={rtcToken} rtmToken={rtmToken} username={username} />}
</div>
</div>
);
}
现在,我们来为频道路由创建 React 组件。我们将使用 mounted 状态变量,该状态变量在 useEffect Hook 里设置为 true。这样,只在文件在浏览器中渲染时,才会渲染 Videocall 组件。我们可以使用 Remix 的 userLoaderData Hook 来获取 jsonData。我们将从对象中提取值,并将这些值传递给一个名为 Videocall 的组件。最后,返回一些 JSX 来渲染我们接下来会创建的 <Videocall> 组件。
视频通话组件
创建一个新文件 /app/components/videocall.client.tsx,并使用声网 Web UIKit 来创建视频通话:
import AgoraUIKit, { layout } from 'agora-react-uikit';
import { loaderData } from '~/routes/channel/$channel';
export default function Videocall(props: loaderData) {
const { appId, channel, rtcToken, rtmToken, username } = props
return (
<div style={{display: 'flex', flex: 1, height: '80vh'}}>
<AgoraUIKit
rtcProps={{ appId, channel, token: rtcToken, layout: layout.grid}}
rtmProps={{ token: rtmToken, uid: String(username), displayUsername: true, username: 'User' + String(username).slice(-3) }}
/>
</div>
)
}
然后,访问我们传递给此组件的数据道具,并将它们传递给 <AgoraUIKit> 组件。 该组件负责处理视频通话的所有逻辑,不需要其他代码。如果你想了解如何自定义设计和功能(例如直播),可以查看这篇文章。
找到 localhost:3000/channel/test,查看你的视频通话用户界面。你可以在单独窗口中打开该网址,模拟视频通话并测试。
总结
欢迎在 GitHub 上为此 Remix demo 或为 UIKit 的功能请求开启拉动请求,或创建问题来报告错误。我们期待着大家的贡献。我们也有 Android、iOS、React Native 和 Flutter 版本的 UIKit,欢迎大家查看并试用。
原文作者:Ekaansh Arora
原文链接:https://www.agora.io/en/blog/adding-video-calling-to-a-remix-app-using-the-agora-web-uikit/