虎牙开放平台文档

小程序消息

本章节介绍如何使用小程序消息通道,在主播端小程序下发消息给观众端小程序。通常的场景是:

  • 主播端设置一些参数,例如提示语、礼物设置等等;
  • 观众端根据这些参数做一些操作,例如显示提示语、渲染礼物按钮供用户送礼等等。

为了满足上面的业务场景,虎牙小程序平台提供了两条小程序消息通信通道,分别为:

  1. 主播端到观众端的单向通道,通过JS SDK通信

  2. 业务服务端到主播端/观众端的单向通道,通过小程序API通信

    • 业务服务器通过小程序API给主播端/观众端下发消息;
    • 主播端/观众端通过hyExt.observer.on监听小程序响应消息;
    • 如果需要观众端反馈消息到主播端,则需要:
      • 观众端调用hyExt.request通知业务服务器
      • 业务服务器通过小程序API转推到主播端
      • 并不支持直接从观众端下发消息给主播端

2021 12 08 10 20 56

以下是两种通信方式的简单示例:

方式一:通过SDK通信

此模块主要介绍 主播端调用hyExt.observer.emit SDK 给观众端下发消息,观众端调用hyExt.observer.on SDK 监听小程序响应消息,这是一条单向通道,实现主播端向观众端下发消息。

准备工作

参考创建小程序项目,初始化一个小程序项目,其中小程序类型选择:

  • 虎牙直播主站-面板
  • 虎牙直播APP-面板
  • PC主播端-面板

参考创建小程序,创建一个小程序和创建一个开发版本。

新增示例组件

streamer主播端和viewer观众端各新增两个文件,共新增四个文件

  • 新增streamer/common.js
import React, { useState, useEffect } from "react"; import { UI } from "@hyext/hy-ui"; import "./common.hycss"; const { View, Text, Input, Button } = UI; export const Example = () => { const [sendMessage, setSendMessage] = useState(""); const [sendResult, setSendResult] = useState("暂无发送"); const emitMessage = function () { hyExt.observer .emit("message-push", `${JSON.stringify(sendMessage)}`) .then((res) => { setSendResult("向客户端小程序广播信息成功!"); }) .catch((err) => { setSendResult("内容包含敏感信息,广播消息失败!"); }); }; return ( <View className="container"> <View className="section"> <Text>请在输入框输入数据</Text> <Input className="input" blurOnSubmit={false} placeholder="输入数据并发送" value={sendMessage} onChange={(v) => setSendMessage(v)} /> </View> <View className="section"> <Button className="button" onPress={() => emitMessage()}> 发送数据至观众端 </Button> </View> <Text className="text">发送结果:{sendResult}</Text> </View> ); };
  • 新增streamer/common.hycss:
.container{ flex: 1; align-items: center; margin-top: 200px; } .section { margin: 20px auto; } .button { height: 100px; width: 400px; background-color: rgb(253, 69, 69); border-radius: 50px; } .input { width: 600px; height: 80px; border: gray solid 3px; border-radius: 20px; } .text{ margin-top: 10px; }
  • 新增viewer/common.js
import React, { useState, useEffect } from "react"; import { UI } from "@hyext/hy-ui"; import "./common.hycss"; const { View, Text } = UI; export const Example = () => { const [receiveMessage, setReceiveMessage] = useState("暂无消息"); useEffect(() => { hyExt.observer.on("message-push", (content) => setReceiveMessage(JSON.parse(content))); }, []); return ( <View className="container"> <Text>监听到的消息:{receiveMessage}</Text> </View> ); };
  • 新增viewer/common.hycss:
.container { display: flex; flex: 1; justify-content: center; align-items: center; }

其中:

  • 使用React.useState()记录主播端需要广播的文本信息、广播的结果,观众端监听接收到的响应信息;
  • 主播端点击按钮触发自定义的emitMessage()方法,调用hyExt.observer.emit SDK 后,首先会自动向虎牙平台发起文本的秩序审核,审核通过的信息会被成功广播;
  • 观众端使用React.useEffect()调用hyExt.observer.on SDK 监听主播端发送的小程序消息。

在小程序中使用组件

修改streamer/app.jsviewer/app.js两个文件

  • 修改streamer/app.js
--- a/streamer/app.js +++ b/streamer/app.js @@ -1,5 +1,6 @@ import { UI } from '@hyext/hy-ui' import React, { Component } from 'react' +import { Example } from './common' import './app.hycss' const { View, Text } = UI @@ -7,7 +8,9 @@ const { View, Text } = UI class App extends Component { render () { return ( - <View className="container"><Text>hello world</Text></View> + <View className="container"> + <Example /> + </View> ) } }
  • 修改viewer/app.js
--- a/viewer/app.js +++ b/viewer/app.js @@ -1,5 +1,6 @@ import { UI } from '@hyext/hy-ui' import React, { Component } from 'react' +import { Example } from './common' import './app.hycss' const { View, Text } = UI @@ -7,7 +8,9 @@ const { View, Text } = UI class App extends Component { render () { return ( - <View className="container"><Text>hello world</Text></View> + <View className="container"> + <Example /> + </View> ) } }

在直播间中预览

参考在直播间预览的方式,运行npm start,启动开发服务,在直播间添加并打开 开发版小程序:

  • PC主播端

2022 04 07 11 25 51

  • 虎牙主站

2022 04 07 12 07 52

通过文本的秩序审核,广播消息成功

  • PC主播端

2022 04 07 14 15 53

  • 虎牙主站

2022 04 07 14 16 12

  • 虎牙直播APP

2022 04 07 14 24 13

未通过文本的秩序审核,发送失败,观众端无法正常接收消息

2022 04 07 14 26 17

方式二:通过小程序API通信

此模块主要介绍通过小程序API实现观众端向主播端反馈消息,这是一条单向通道,总体实现流程如下:

  1. 观众端调用hyExt.request通知业务服务器;
  2. 业务服务器通过小程序API转推到主播端;
  3. 主播端通过hyExt.observer.on监听小程序响应消息。

下面将会演示利用Express搭建一个简单的业务服务器,并对方式一中的小程序进行简单改造,实现观众端向主播端反馈消息。

搭建业务服务器

  1. 创建项目文件夹,运行npm init创建package.json文件;
  2. 安装Expressrequestjsonwebtokencors,并保存在依赖列表中; npm install express --save npm install jsonwebtoken --save npm install request --save npm install cors --save npm install body-parser --save
  • 安装jsonwebtoken依赖用于JWT统一鉴权
    • 调用jwt.verify()方法,对观众端调用hyExt.request SDK 请求的数据进行解码,获得profileIdroomId等信息
    • 调用jwt.sign()方法,会根据Header.Payload.Signature的格式生成鉴权签名
  • 安装request依赖用于向小程序API https://apiext.huya.com 发送请求,具体接口可查看小程序API列表
  • 安装cors依赖用于处理跨域问题
  • 安装body-parser依赖用于解析body数据,不解析无法读取req.body
  1. 新增app.js文件;

    const express = require("express"); const cors = require("cors"); const app = express(); const request = require("request"); const jwt = require("jsonwebtoken"); const bodyParser = require("body-parser"); // 跨域处理 app.use(cors()); // 解析body内的数据 app.use(bodyParser.json()); app.use("/", async (req, res, next) => { /** * 从小程序观众端获得请求信息 * 需要对authorization进行解密 */ const authorization = req.headers.authorization; // appSecret【填入自己专属的appSecret】 const appSecret = "xxxxxx"; // 解析观众端的请求信息 let decodeData = jwt.verify(authorization, appSecret); // 需要请求的数据 const { iat, exp, appId, extUuid, profileId, roomId } = decodeData; const { event, message } = req.body; /** * 生成签名Authorization * 格式:Header.Payload.Signature */ // 1. header:调用jwt.sign()方法之后会编码成"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"字符串(可在jwt.io验证) const header = { // alg属性表示签名的算法,字符串类型,默认是HS256(HMACSHA256) alg: "HS256", // typ属性表示token的类型,字符串类型,统一为JWT typ: "JWT", }; // 2.Payload:实际需要传递的数据 const payload = { iat, // token生成时间戳(秒) exp, // 过期时间戳(秒) appId, // 小程序开发者appid extUuid, // 小程序uuid }; // 3. Signature(同上appSecret)【填入自己专属的appSecret】 const signature = appSecret; // 4. 生成签名 const Authorization = jwt.sign(header + "." + payload, signature); /** * 发送请求 */ await request( { url: `https://apiext.huya.com/message/deliverByProfileId?appId=${appId}&extUuid=${extUuid}`, method: "POST", headers: { Authorization }, json: true, body: { profileId, roomId, event, message, }, }, (error, response, body) => { if (!error && response.statusCode == 200) { res.send("广播成功!"); } } ); }); // 监听端口、启动程序 app.listen(3001, (err) => { if (err) throw err; console.log("http://localhost:3001"); console.log("启动成功!"); });

改造方式一的示例小程序

  1. 修改streamer/common.js文件
  • 添加requestServer()方法 const requestServer = function () { hyExt .request({ url: "http://localhost:3001", // 本地业务服务器 method: "POST", data: {"event": "message-push", "message": sendMessage}, dataType: "text", isDirect: true, }) .then((res) => { setSendResult("向业务服务器发送数据成功!", res); }) .catch((err) => { setSendResult("向业务服务器发送数据失败!", err); }); };
  • 删除原先的"发送数据至观众端"按钮,添加"发送数据到主播端"按钮 return ( <View className="container"> <View className="section"> <Text>请在输入框输入数据</Text> <Input className="input" blurOnSubmit={false} placeholder="输入发送输入" value={sendMessage} onChange={(v) => setSendMessage(v)} /> </View> <View className="section"> <Button className="button" onPress={() => requestServer()}> 发送数据至主播端 </Button> </View> <Text className="text">发送结果:{sendResult}</Text> </View> );

在小程序中使用组件

streamer/app.js中使用viewer/common.js组件,在viewer/app.js中使用streamer/common.js组件。

  • 修改streamer/app.js
--- a/streamer/app.js +++ b/streamer/app.js @@ -1,5 +1,6 @@ import { UI } from '@hyext/hy-ui' import React, { Component } from 'react' -import { Example } from './common' +import { Example } from '../viewer/common' import './app.hycss' const { View, Text } = UI class App extends Component { render () { return ( <View className="container"> <Example /> </View> ) } }
  • 修改viewer/app.js
--- a/viewer/app.js +++ b/viewer/app.js @@ -1,5 +1,6 @@ import { UI } from '@hyext/hy-ui' import React, { Component } from 'react' -import { Example } from './common' +import { Example } from '../streamer/common' import './app.hycss' const { View, Text } = UI class App extends Component { render () { return ( <View className="container"> <Example /> </View> ) } }

在直播间中预览

参考在直播间预览的方式,运行npm start,启动小程序开发服务,在直播间添加并打开 开发版小程序。同时运行node app.js命令启动业务服务器。

  • 虎牙主站

2022 04 11 16 41 17

  • PC主播端

2022 04 11 16 43 11

注意事项

相关链接