WangShuXian6 / blog

FE-BLOG
https://wangshuxian6.github.io/blog/
MIT License
46 stars 10 forks source link

即时通信(Instant Messaging,IM) #197

Open WangShuXian6 opened 2 months ago

WangShuXian6 commented 2 months ago

即时通信(Instant Messaging,IM)

https://cloud.tencent.com/document/product/269

即时通信(Instant Messaging,IM)基于 QQ 底层 IM 能力开发,仅需植入 SDK 即可轻松集成聊天、会话、群组、资料管理能力,帮助您实现文字、图片、短语音、短视频等富媒体消息收发,全面满足通信需要。

WangShuXian6 commented 2 months ago

Taro 中使用 即时通信(Instant Messaging,IM)

注意: 开发版调试时,必须开启小程序的调试模式,否则图片无法上传至腾讯服务器,导致图片上传失败不显示。

安装

npm i @tencentcloud/chat tim-upload-plugin -S

引入官方userSig代码

需要从 TUIKit 组件 中复制

npm i @tencentcloud/chat-uikit-wechat
import { genTestUserSig }  from '../../TUIKit/debug/GenerateTestUserSig';

需要文件 GenerateTestUserSig.js lib-generate-test-usersig-es.min.js

修改 GenerateTestUserSig.js

import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min.js'

/**
 * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
 *
 * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId,
 * 它是腾讯云用于区分客户的唯一标识。
 */
// const SDKAPPID = 0;

/**
 * 签名过期时间,建议不要设置的过短
 * <p>
 * 时间单位:秒
 * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
 */
// const EXPIRETIME = 604800;

/**
 * 计算签名用的加密密钥,获取步骤如下:
 *
 * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个,
 * step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
 * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
 *
 * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
 * 文档:https://cloud.tencent.com/document/product/647/17275#Server
 */
// const SECRETKEY = '';

/*
 * Module:   GenerateTestUserSig
 *
 * Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。
 *           其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
 *
 * Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
 *
 *            本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
 *            这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
 *            一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
 *
 *            正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
 *            由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
 *
 * Reference:https://cloud.tencent.com/document/product/647/17275#Server
 */
export const genTestUserSig = (config) => {
  const { SDKAPPID, SECRETKEY, EXPIRETIME, userID } = config
  const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME)
  const userSig = generator.genTestUserSig(userID)

  return {
    sdkAppID: SDKAPPID,
    userSig
  }
}

配置IM

即时通信 IM 控制台 > 应用管理 获取 SDKAPPID、SECRETKEY 即时通信 IM 控制台 > 账号管理 创建账号并获取 userID 群组管理 - 消息服务 Chat - 即时通信 IM - 控制台 (tencent.com)

示例

src\pages\index\index.tsx

import React, { useCallback } from "react";
import { View, Text, Button, Image } from "@tarojs/components";
import { genTestUserSig } from "../../debug/GenerateTestUserSig";
import { createLogger } from "../..//utils/common";
import TencentCloudChat from "@tencentcloud/chat";
import { useLoad, useReady, useRouter, useUnload } from "@tarojs/taro";
import TIMUploadPlugin from "tim-upload-plugin";
import "./index.less";

const logger = createLogger();

const Config = {
  userID: "test1", // User ID
  SECRETKEY: "", // Your secretKey
  SDKAPPID: 0, // Your SDKAppID
  EXPIRETIME: 604800,
};

const userID2 = "test2";

const groupID = "@TGS#1XC7JZ5OY";

export type RouterParams = {
  userID: string;
};

// userID=test1
// userID=test2
const Index = () => {
  const { userID = Config.userID } = useRouter<RouterParams>().params;

  const chat = TencentCloudChat.create({
    SDKAppID: Config.SDKAPPID,
  });

  const userSig = genTestUserSig({ ...Config, userID }).userSig;

  useLoad(() => {
    logger.info("1页面加载");
    init();
  });

  useReady(() => {
    logger.info("1页面初次渲染完成");
  });

  useUnload(() => {
    logger.info("1页面卸载");
    chat.off(TencentCloudChat.EVENT.SDK_READY, onSDKReady, this);
    chat.logout();
  });

  const init = () => {
    chat.registerPlugin({ "tim-upload-plugin": TIMUploadPlugin });
    chat.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
    // chat.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用
    chat.on(TencentCloudChat.EVENT.SDK_READY, onSDKReady, this);
    chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, onMessageReceived);
    chat.login({
      userID,
      userSig,
    });
  };

  const onSDKReady = async (event) => {
    // 监听到此事件后可调用 SDK 发送消息等 API,使用 SDK 的各项功能。
    logger.info("sdk 准备就绪");

    const message = chat.createTextMessage({
      to: `${groupID}`,
      conversationType: "GROUP", //TencentCloudChat.TYPES.CONV_GROUP,
      payload: {
        text: `${userID}`,
      },
    });
    const result = await chat.sendMessage(message);
    logger.info("文字消息发送结果:", result);
  };

  const onMessageReceived = (event) => {
    // 收到推送的单聊、群聊、群提示、群系统通知的新消息,可通过遍历 event.data 获取消息列表数据并渲染到页面
    // event.name - TencentCloudChat.EVENT.MESSAGE_RECEIVED
    // event.data - 存储 Message 对象的数组 - [Message]
    logger.info("接受到消息:", event);
  };

  return <View className="wrapper"></View>;
};

export default Index;