腾讯TIM实现即时通信 v3+ts实践

news2024/11/17 1:27:40

目录

初始化sdk

功能描述

初始化

准备 SDKAppID

调用初始化接口

 监听事件

发送消息

创建消息

创建文本消息

登录登出

功能描述

登录

登出

销毁

登录设置

获取会话列表

功能描述

获取会话列表

获取全量的会话列表

 历史消息

功能描述

拉取消息列表

分页拉取指定会话的消息列表

根据指定的消息 sequence 或消息时间跳拉会话的消息列表

 接收消息

功能描述

监听事件

取消监听事件

 总结


初始化sdk

功能描述

在使用 IM SDK 的各项功能前,必须先进行初始化。

初始化

初始化 SDK 需要操作以下步骤:

  1. 准备 SDKAppID。
  2. 调用 TIM.create 初始化 SDK。
  3. 添加 SDK 事件监听器。

下面我们将分步骤依次为您详细讲解。

准备 SDKAppID

您必须拥有正确的 SDKAppID,才能进行初始化。
SDKAppID 是腾讯云 IM 服务区分客户帐号的唯一标识。我们建议每一个独立的 App 都申请一个新的 SDKAppID。不同 SDKAppID 之间的消息是天然隔离的,不能互通。
您可以在 即时通信 IM 控制台 查看所有的 SDKAppID,单击 创建新应用,可以创建新的 SDKAppID。

调用初始化接口

操作完上述步骤后,您可以调用 TIM.create 初始化 SDK。

接口

TIM.create(options);

参数 options 为 Object 类型,包含的属性值如下:

NameTypeDescription
SDKAppIDNumber即时通信 IM 应用的 SDKAppID
        public tim: ChatSDK | undefined
        private initTimSdk(SDKAppID: number) {
        let options = {
            SDKAppID,// 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
        };
        // 创建 SDK 实例,`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
        let tim = TIM.create(options); // SDK 实例通常用 tim 表示

        // 设置 SDK 日志输出级别,详细分级请参见 setLogLevel https://web.sdk.qcloud.com/im/doc/zh-cn/SDK.html#setLogLevel 接口的说明</a>
        tim.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
        // tim.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用

        // 注册腾讯云即时通信 IM 上传插件
        tim.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin })
        this.tim = tim
    
    }

 监听事件

SDK 进入 ready 状态时触发,接入侧监听此事件,然后可调用 SDK 发送消息等 API,使用 SDK 的各项功能


    // 监听sdk准备完成的事件
    private bindTIMEvent() {
        this.tim?.on(TIM.EVENT.SDK_READY, this.handleSDKReady, this)
    }

  SDK 收到推送的单聊、群聊、群提示、群系统通知的新消息,接入侧可通过遍历 event.data 获取消息列表数据并渲染到页面

    private handleSDKReady = () => {
        console.log('sdk准备完成');
        this.onReady()

        console.log('执行');

        this.tim?.on(TIM.EVENT.MESSAGE_RECEIVED, this.handleMessageReceived, this)

    }
    private handleMessageReceived = (event: TextMessageEvent) => {
        console.log('接收到消息', event);
        this.messageReceived(event)

    }
    public messageReceived = (event: TextMessageEvent) => { }

发送消息

创建消息

创建文本消息

创建文本消息的接口,此接口返回一个消息实例,可以在需要发送文本消息时调用 发送消息 接口发送消息实例。

接口

tim.createTextMessage(options);

参数

参数 options 为 Object 类型,包含的属性值如下:

NameTypeDefaultDescription
toString-消息接收方的 userID 或 groupID
conversationTypeString-会话类型,取值TIM.TYPES.CONV_C2C(端到端会话)或TIM.TYPES.CONV_GROUP(群组会话)
priorityStringTIM.TYPES.MSG_PRIORITY_NORMAL消息优先级
payloadObject-消息内容的容器
cloudCustomDataString''消息自定义数据(云端保存,会发送到对端,程序卸载重装后还能拉取到,v2.10.2起支持)

payload 的描述如下:

NameTypeDescription
textString消息文本内容

返回值

消息实例 Message。

示例

        private getMessageOptions = (userID: string, payload: ITextPayload) => {
            return this.tim?.createTextMessage({
            to: userID,
            conversationType: TIM.TYPES.CONV_C2C,
            // 消息优先级,用于群聊(v2.4.2起支持)。如果某个群的消息超过了频率限制,后台会优先下发高优先级的消息,详细请参考:https://cloud.tencent.com/document/product/269/3663#.E6.B6.88.E6.81.AF.E4.BC.98.E5.85.88.E7.BA.A7.E4.B8.8E.E9.A2.91.E7.8E.87.E6.8E.A7.E5.88.B6)
            // 支持的枚举值:TIM.TYPES.MSG_PRIORITY_HIGH, TIM.TYPES.MSG_PRIORITY_NORMAL(默认), TIM.TYPES.MSG_PRIORITY_LOW, TIM.TYPES.MSG_PRIORITY_LOWEST
            // priority: TIM.TYPES.MSG_PRIORITY_NORMAL,
            payload,
            // v2.20.0起支持C2C消息已读回执功能,如果您发消息需要已读回执,需购买旗舰版套餐,并且创建消息时将 needReadReceipt 设置为 true
            needReadReceipt: true
            // 消息自定义数据(云端保存,会发送到对端,程序卸载重装后还能拉取到,v2.10.2起支持)
            // cloudCustomData: 'your cloud custom data'
        })
    }

       public sendMessage = async (userID: string, payload: ITextPayload) => {
        // 创建消息
        const messOption = this.getMessageOptions(userID, payload)
        await this.tim?.sendMessage(messOption!)
        console.log('发送成功');

    }
    public sendMessage = async (userID: string, payload: ITextPayload) => {
        // 创建消息
        const messOption = this.getMessageOptions(userID, payload)
        await this.tim?.sendMessage(messOption!)
        console.log('发送成功');

    }

返回  消息实例 Message。

登录登出

功能描述

用户登录 IM SDK 才能正常收发消息,登录需要用户提供 UserID、UserSig 等信息,具体含义请参见 登录鉴权。

登录

注意:

  • 登录成功,需等待 sdk 处于 ready 状态后(监听事件 TIM.EVENT.SDK_READY)才能调用 sendMessage 等需要鉴权的接口。
  • 如需支持多实例登录(允许在多个网页中同时登录同一帐号),请登录 即时通信 IM 控制台,找到相应 SDKAppID,选择应用配置>功能配置>登录与消息>登录设置>Web 端可同时在线个数配置实例个数。配置将在5分钟内生效。

接口

tim.login(options);

参数

参数 options 为 Object 类型,包含的属性值如下:

名称类型描述
userIDString用户 ID。
userSigString用户登录即时通信 IM 的密码,其本质是对 UserID 等信息加密后得到的密文。
具体生成方法请参见 生成 UserSig。

返回值

Promise 对象。

示例

    public timLogin = async (options: TIMCoreLoginParams) => {
        //第一步登录sdk
        await this.tim?.login(options)
        // 持久化相关密钥
        localStorage.setItem('TIMCoreLoginParams', JSON.stringify(options))
        this.userID = options.userID
        this.bindTIMEvent()
    }

实例生成后缓存登录态

    private persistedLogin = () => {
        console.log('缓存');

        const TIMCoreLoginParams = JSON.parse(localStorage.getItem('TIMCoreLoginParams') || '{}')
        if (TIMCoreLoginParams.userID) {
            console.log('存在登录');

            this.timLogin(TIMCoreLoginParams)
        }
    }

 

登出

登出即时通信 IM,通常在切换帐号的时候调用,清除登录态以及内存中的所有数据。

注意:

  • 调用此接口的实例会发布 SDK_NOT_READY 事件,此时该实例下线,无法收、发消息。
  • 如果您在即时通信 IM 控制台配置的“Web 端实例同时在线个数”大于 1,且同一帐号登录了a1a2两个实例(含小程序端),当执行a1.logout()后,a1会下线,无法收、发消息。而a2实例不会受影响。
  • 多实例被踢:基于第 2 点,如果“Web 端实例同时在线个数”配置为 2,且您的某一帐号已经登录了 a1a2两个实例,当使用此帐号成功登录第三个实例a3时,a1a2中的一个实例会被踢下线(通常是最先处在登录态的实例会触发),这种情况称之为“多实例被踢”。假设a1实例被踢下线,a1实例内部会执行登出流程,然后抛出KICKED_OUT事件,接入侧可以监听此事件,并在触发时跳转到登录页。此时a1实例下线,而a2a3实例可以正常运行。

接口

tim.logout();

参数

返回值

Promise 对象。

示例

let promise = tim.logout();
promise.then(function(imResponse) {
  console.log(imResponse.data); // 登出成功
}).catch(function(imError) {
  console.warn('logout error:', imError);
});

销毁

销毁 SDK 实例,包括:登出,断开长连接,并释放所有资源。

接口

tim.destroy();

参数

返回值

Promise 对象。

示例

tim.destroy().then(() => {
  console.log('sdk destroyed');
});

关闭监听

    public unBindTIMEvent = () => {
        this.tim?.off(TIM.EVENT.MESSAGE_RECEIVED, () => { })
        this.tim?.off(TIM.EVENT.SDK_READY, () => { })
    }

 

登录设置

默认情况下,不支持多实例登录,即如果此帐号已在其他页面登录,若继续在当前页面登录成功,有可能会将其他页面踢下线。用户被踢下线时会触发事件TIM.EVENT.KICKED_OUT,用户可在监听到事件后做相应处理。示例如下:

let onKickedOut = function (event) {
  console.log(event.data.type);
  // TIM.TYPES.KICKED_OUT_MULT_ACCOUNT(Web 端,同一帐号,多页面登录被踢)
  // TIM.TYPES.KICKED_OUT_MULT_DEVICE(同一帐号,多端登录被踢)
  // TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED(签名过期)
  // TIM.TYPES.KICKED_OUT_REST_API(REST API kick 接口踢出。v2.20.0起支持)
};
tim.on(TIM.EVENT.KICKED_OUT, onKickedOut);

获取会话列表

功能描述

用户在登录 App 后,可以像微信或 QQ 那样展示最近会话列表,方便找到目标会话。
会话列表如下图所示:

会话列表功能主要分为获取会话列表、监听会话列表更新事件。核心数据结构 Conversation。

获取会话列表

接入侧可通过调用 getConversationList 接口主动获取会话列表。

获取全量的会话列表

  // 获取会话列表
        async getSessionList() {
            console.log('aaaa');

            const { data: { conversationList } } = await this.timeCore.tim?.getConversationList()
            this.conversationList = conversationList
            console.log(this.conversationList, '数据');
            // 他没有回话并且不是客服
            if (conversationList.length == 0 && this.timeCore.userID !== 'admin') {
                this.conversationList.push({
                    lastMessage: {},
                    userProfile: {
                        userID: 'admin',

                    } as Profile
                })
            }
            const userId = this.conversationList[0].userProfile?.userID
            console.log(conversationList[0], '--------');

            if (userId) {
                this.selectedKeys = [userId]
                this.getMessageHistoryList(userId)
            }


        },

 历史消息

功能描述

SDK 既支持分页续拉消息列表,也支持根据指定的消息 sequence 或消息时间跳拉消息列表。

云端存储的历史消息有存储时长的限制:

  • 体验版:免费存储 7 天,不支持延长
  • 专业版:免费存储 7 天,支持延长
  • 旗舰版:免费存储 30 天,支持延长

说明:

  • 延长历史消息存储时长是增值服务,您可以登录 即时通信 IM 控制台 修改相关配置,具体计费说明请参加 增值服务资费 。
  • 富媒体消息(图片、文件、语音等)对应的文件存储时长,与历史消息存储时长保持一致。

拉取消息列表

分页拉取指定会话的消息列表

分页拉取指定会话的消息列表的接口,当用户进入会话首次渲染消息列表或者用户“下拉查看更多消息”时,需调用该接口。

注意:

该接口可用于"拉取历史消息",每次调用 SDK 最多返回20条消息。

接口

tim.getMessageList(options);

参数

参数 options 为 Object 类型,包含的属性值如下:

名称类型描述
conversationIDString会话 ID。会话 ID 组成方式:
  • C2C${userID}(单聊)
  • GROUP${groupID}(群聊)
  • GROUP${topicID}(话题)v2.19.1 起支持
  • @TIM#SYSTEM(系统通知会话)
nextReqMessageIDString | undefined用于分页续拉的消息 ID。第一次拉取时该字段不要填值,续拉时填入上次调用 getMessageList 接口返回的该字段的值。

返回值

Promise 对象。

示例

      async getMessageHistoryList(userId: string) {
            const data = await this.timeCore.tim?.getMessageList({ conversationID: `C2C${userId}` })
            this.historMessage = data.data.messageList
            console.log(data, '我是历史记录');

        }
// 下拉查看更多消息
let promise = tim.getMessageList({conversationID: 'C2Ctest', nextReqMessageID});
promise.then(function(imResponse) {
  const messageList = imResponse.data.messageList; // 消息列表。
  const nextReqMessageID = imResponse.data.nextReqMessageID; // 用于续拉,分页续拉时需传入该字段。
  const isCompleted = imResponse.data.isCompleted; // 表示是否已经拉完所有消息。
});

根据指定的消息 sequence 或消息时间跳拉会话的消息列表

根据指定的消息 sequence 或 消息时间拉取会话的消息列表的接口。

注意:

v2.20.0起支持。

接口

tim.getMessageListHopping(options);

参数

参数 options 为 Object 类型,包含的属性值如下:

名称类型描述
conversationIDString会话 ID。会话 ID 组成方式:
  • C2C${userID}(单聊)
  • GROUP${groupID}(群聊)
  • GROUP${topicID}(话题)v2.19.1 起支持
sequenceNumber | undefined用于拉群组会话漫游消息的起始 sequence。
timeNumber | undefined消息的服务端时间,用于拉 C2C 会话漫游消息的起始时间。
directionNumber消息拉取方向,默认 0。
  • 0 向上拉,拉更旧的消息
  • 1 向下拉,拉更新的消息
countNumber | undefined需要拉取的消息数量,默认值和最大值为15,即一次拉取至多返回15条消息。

返回值

Promise 对象。

示例

// 根据 sequence 拉群漫游消息,direction 0 向上拉,拉更旧的消息,direction 1 向下拉,拉更新的消息
let promise = tim.getMessageListHopping({conversationID: 'GROUPtest', sequence: xxx, count: 15, direction: 0});
promise.then(function(imResponse) {
  const messageList = imResponse.data.messageList; // 消息列表。
});
// 根据时间拉 C2C 会话漫游消息,direction 0 向上拉,拉更旧的消息,direction 1 向下拉,拉更新的消息
let promise = tim.getMessageListHopping({conversationID: 'C2Ctest', time: xxx, count: 15, direction: 0});
promise.then(function(imResponse) {
  const messageList = imResponse.data.messageList; // 消息列表。
});

 接收消息

功能描述

接收消息需要通过事件监听实现。

监听事件

注意:

请在调用 login 接口前调用此接口监听事件,避免漏掉 SDK 派发的事件。

接口

tim.on(eventName, handler, context);

参数

名称类型描述
eventNameString事件名称。所有的事件名称都存放在 TIM.EVENT 变量中,如需要查看可以使用 console.log(TIM.EVENT) 把所有的事件显示出来。事件列表。
handlerFunction处理事件的方法,当事件触发时,会调用此 handler 进行处理。
context* | undefined期望 handler 执行时的上下文

返回值

示例

let onMessageReceived = function(event) {
  // event.data - 存储 Message 对象的数组 - [Message]
  const messageList = event.data;
  messageList.forEach((message) => {
    if (message.type === TIM.TYPES.MSG_TEXT) {
      // 文本消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.TextPayload
    } else if (message.type === TIM.TYPES.MSG_IMAGE) {
      // 图片消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.ImagePayload
    } else if (message.type === TIM.TYPES.MSG_SOUND) {
      // 音频消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.AudioPayload
    } else if (message.type === TIM.TYPES.MSG_VIDEO) {
      // 视频消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.VideoPayload
    } else if (message.type === TIM.TYPES.MSG_FILE) {
      // 文件消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.FilePayload
    } else if (message.type === TIM.TYPES.MSG_CUSTOM) {
      // 自定义消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.CustomPayload
    } else if (message.type === TIM.TYPES.MSG_MERGER) {
      // 合并消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.MergerPayload
    } else if (message.type === TIM.TYPES.MSG_LOCATION) {
      // 地理位置消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.LocationPayload
    } else if (message.type === TIM.TYPES.MSG_GRP_TIP) {
      // 群提示消息 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.GroupTipPayload
    } else if (message.type === TIM.TYPES.MSG_GRP_SYS_NOTICE) {
      // 群系统通知 - https://web.sdk.qcloud.com/im/doc/zh-cn/Message.html#.GroupSystemNoticePayload
    }
  });
};
tim.on(TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived);

取消监听事件

接口

tim.off(eventName, handler, context, once);

参数

名称类型描述
eventNameString事件名称。所有的事件名称都存放在 TIM.EVENT 变量中,如需要查看可以使用 console.log(TIM.EVENT) 把所有的事件显示出来。事件列表。
handlerFunction处理事件的方法,当事件触发时,会调用此 handler 进行处理。
context* | undefined期望 handler 执行时的上下文
onceBoolean | undefined是否只解绑一次

返回值

示例

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

 总结

  • 引入pinia的聊天模块开始进行sdk初始化
  • 在登录完成后 完成tim的登录 并且持久化登录
  • 在顶层页面完成消息的接收,也就是监听消息的变化每次变化通知一下pina事件的分法
  • 在页面收到action发过来的消息后,要把消息主动放在当前聊天记录里面
  • 当选择一个新的联系人的时候要获取这个人的聊天信息
  • 每次发送消息要注意清空输入框,并且把最新消息手动push到当前聊天数组中
import TIM, { ChatSDK } from 'tim-js-sdk';
import TIMUploadPlugin from 'tim-upload-plugin';
import { ChartDefineStoreOptions, ITextPayload, TextMessageEvent, TIMCoreLoginParams } from './type';

export default class TIMCore {
    public tim: ChatSDK | undefined
    public userID = ''
    constructor(props: ChartDefineStoreOptions) {
        this.initTimSdk(props.SDKAppID)
    }
    private initTimSdk(SDKAppID: number) {
        let options = {
            SDKAppID,// 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
        };
        // 创建 SDK 实例,`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
        let tim = TIM.create(options); // SDK 实例通常用 tim 表示

        // 设置 SDK 日志输出级别,详细分级请参见 setLogLevel https://web.sdk.qcloud.com/im/doc/zh-cn/SDK.html#setLogLevel 接口的说明</a>
        tim.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
        // tim.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用

        // 注册腾讯云即时通信 IM 上传插件
        tim.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin })
        this.tim = tim
        this.persistedLogin()

    }
    public timLoginout = () => {

        //退出登录
        this.tim?.logout()
    }
    public unBindTIMEvent = () => {
        this.tim?.off(TIM.EVENT.MESSAGE_RECEIVED, () => { })
        this.tim?.off(TIM.EVENT.SDK_READY, () => { })
    }
    private persistedLogin = () => {
        console.log('缓存');

        const TIMCoreLoginParams = JSON.parse(localStorage.getItem('TIMCoreLoginParams') || '{}')
        if (TIMCoreLoginParams.userID) {
            console.log('存在登录');

            this.timLogin(TIMCoreLoginParams)
        }
    }

    public timLogin = async (options: TIMCoreLoginParams) => {
        //第一步登录sdk
        await this.tim?.login(options)
        // 持久化相关密钥
        localStorage.setItem('TIMCoreLoginParams', JSON.stringify(options))
        this.userID = options.userID
        this.bindTIMEvent()
    }
    // 监听sdk准备完成的事件
    private bindTIMEvent() {
        this.tim?.on(TIM.EVENT.SDK_READY, this.handleSDKReady, this)
    }
    private handleSDKReady = () => {
        console.log('sdk准备完成');
        this.onReady()

        console.log('执行');

        this.tim?.on(TIM.EVENT.MESSAGE_RECEIVED, this.handleMessageReceived, this)

    }
    public onReady = () => {


    }
    private handleMessageReceived = (event: TextMessageEvent) => {
        console.log('接收到消息', event);
        // 接收到消息后 最好手动设置成已读
        this.tim?.setMessageRead({
            conversationID: event.data[0].conversationID
        })
        this.messageReceived(event)

    }
    // 对外暴露接受消息的方法
    public messageReceived = (event: TextMessageEvent) => { }
    // 创建对应消息类型
    private getMessageOptions = (userID: string, payload: ITextPayload) => {
        return this.tim?.createTextMessage({
            to: userID,
            conversationType: TIM.TYPES.CONV_C2C,
            // 消息优先级,用于群聊(v2.4.2起支持)。如果某个群的消息超过了频率限制,后台会优先下发高优先级的消息,详细请参考:https://cloud.tencent.com/document/product/269/3663#.E6.B6.88.E6.81.AF.E4.BC.98.E5.85.88.E7.BA.A7.E4.B8.8E.E9.A2.91.E7.8E.87.E6.8E.A7.E5.88.B6)
            // 支持的枚举值:TIM.TYPES.MSG_PRIORITY_HIGH, TIM.TYPES.MSG_PRIORITY_NORMAL(默认), TIM.TYPES.MSG_PRIORITY_LOW, TIM.TYPES.MSG_PRIORITY_LOWEST
            // priority: TIM.TYPES.MSG_PRIORITY_NORMAL,
            payload,
            // v2.20.0起支持C2C消息已读回执功能,如果您发消息需要已读回执,需购买旗舰版套餐,并且创建消息时将 needReadReceipt 设置为 true
            needReadReceipt: true
            // 消息自定义数据(云端保存,会发送到对端,程序卸载重装后还能拉取到,v2.10.2起支持)
            // cloudCustomData: 'your cloud custom data'
        })
    }
    public sendMessage = async (userID: string, payload: ITextPayload) => {
        // 创建消息
        const messOption = this.getMessageOptions(userID, payload)
        await this.tim?.sendMessage(messOption!)
        console.log('发送成功');

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/375956.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自动驾驶自主避障概况

文章目录前言1. 自主避障在自动驾驶系统架构中的位置2. 自主避障算法分类2.1 人工势场法&#xff08;APF&#xff09;2.1.1引力势场的构建2.1.2斥力势场的构建2.1.3人工势场法的改进2.2 TEB&#xff08;Timed-Eastic-Band, 定时弹性带&#xff09;2.3 栅格法2.4 向量场直方图(V…

Linux 之 大数据定制篇-shell 编程

文章目录1 为什么要学习 Shell 编程2 Shell 是什么&#xff1f;3 Shell 脚本的执行方式3.1 脚本格式要求3.2 编写第一个 Shell 脚本3.3 脚本的常用执行方式4 Shell 的变量4.1 Shell 变量介绍4.2 shell 变量的定义4.3 shell 变量的定义5 设置环境变量5.1 基本语法5.2 快速入门6 …

【AI绘画】秒级出图 快速生成大师级画作

最近闲来无事&#xff0c;在网上体验了一下各种AI绘画工具。 根据输入的描述语快速生成自己想要的图片&#xff0c;听着还是很不错的&#xff01;想要啥图片就可以生成啥图片&#xff1f;于是&#xff0c;期待满满的搞起来了~ 可是真当体验了一下之后… 这生成的啥呢&#xf…

广泛运用在工业、轨道交通、监狱的ip对讲终端

ip网络对讲系统是不同于传统广播、调频寻址广播和数控广播的产品&#xff0c;它是基于IP数据网络&#xff0c;将音频信号经过数字编码以数据包形式按TCP\IP协议在局域网或广域网上传送&#xff0c;再由终端解码的纯数字化单向&#xff0c;双向及多向音频扩声系统。 本产品是新一…

多表left join 慢sql问题

作为个人记录&#xff0c;后续再填坑a对p是1对多 ,p对llup 1对多SELECTa.id,p.id,t1.id FROMliv_series_product aINNER JOIN liv_product p ON p.id a.product_idLEFT JOIN ( SELECT llup.id, llup.product_id, llup.room_id FROM liv_live_user_product llup WHERE llup.ro…

超声功率放大器原理(超声功率放大器的作用是什么)

超声功率放大器是电子实验室中比较常见的测量仪器&#xff0c;虽然很多工程师频繁使用&#xff0c;但是对于超声功率放大器的了解却不够。下面就让安泰电子来为大家科普超声功率放大器原理和作用的内容。超声功率放大器是什么&#xff1a;超声功率放大器是一种用于提高超声波能…

requests---(2)session简介与自动写博客

目录&#xff1a;导读 session简介 session登录 自动写博客 获取登录cookies 抓取写博客接口 requests自动写博客 写在最后 http协议是无状态的&#xff0c;也就是每个请求都是独立的。那么登录后的一系列动作&#xff0c;都需要用cookie来验证身份是否是登录状态&#…

C++将派生类赋值给基类(向上转型)

1.将派生类对象赋值给基类对象 #include <iostream> using namespace std;//基类 class A{ public:A(int a); public:void display(); public:int m_a; }; A::A(int a): m_a(a){ } void A::display(){cout<<"Class A: m_a"<<m_a<<endl; }//…

一文解读电压放大器(电压放大器原理)

关于电压放大器的科普知识&#xff0c;之前讲过很多&#xff0c;今天为大家汇总一篇文章来详细的讲解电压放大器&#xff0c;希望大家对于电压放大器能有更清晰的认识。电压放大器是什么&#xff1a;电压放大器是一种常用的电子器件&#xff0c;它的主要作用是把输入信号的振幅…

计算机网络-- 分类、体系结构(day03)

计算机网络的分类 计算机网络的性能指标 速率 数据块&#xff08;文件&#xff09;的大小单位是以2^10(1024)为一个级别递增。 例如&#xff1a; 1MB大小的文件&#xff0c;在网速为1Mbps发送的时间需要多少 文件大小的M是2进制来表示的&#xff0c;网速的M为10进制来表示的 …

zabbix4.0-自定义脚本钉钉告警

目录 1、自定义一个钉钉群组 2、自定义脚本告警 3、创建媒体类型 4、为用户指定媒介类型 5、更改触发器表达式进行测试 1、自定义一个钉钉群组 群组里面添加一个自定义机器人 会有一个webhook地址&#xff0c;这个地址要记住 安全设置暂时选择自定义关键词&#xff0c;定义…

第四阶段02-酷鲨商城项目Mybatis相关的配置

14. 添加与Mybatis相关的配置 在每个项目中&#xff0c;当需要使用Mybatis实现数据库编程时&#xff0c;都需要添加2项一次性配置&#xff1a;配置Mapper接口所在的包&#xff08;package&#xff09;、配置XML文件在哪里。 关于配置Mapper接口所在的包&#xff0c;可以&…

BPMN2.0是什么,BPMN能解决企业流程管理中哪些问题?

一、前言&#xff1a; 在任何行业和企业中&#xff0c;一定存在着各式各样的流程&#xff0c;请假流程、报销流程、入职流程、离职流程、出差流程、合同审批流程、出入库流程等等…… 无论是管理者、技术人员还是业务人员&#xff0c;每天肯定也在使用各种流程&#xff0c;但…

《MySQL学习》 索引失效的三种特殊情况

一.条件字段使用函数 explain select * from bpm_proc_instance bpi where CREATED_AT > 2022-06-01 CREATED_AT 字段建立了索引&#xff0c;此时explain分析的结果表明能使用到索引 但如果我们对 CREATED_AT 字段使用函数 explain select * from bpm_proc_instance bpi w…

【强烈建议收藏:计算机网络面试专题:URL地址栏中输入网址到页面展示的全过程DNS域名解析的过程】

一.面试官:我们就来问一下关于计算机网络相关的专业知识吧 面试官:好的&#xff0c;那我们yyyy-mm-dd就在腾讯会议上面试吧; 卑微的你:好的。 卑微的你:到了面试的时间了&#xff0c;守时的你一定早早的进入了视频会议&#xff0c;等待着面试官&#xff0c;心里慌的一批&#…

Elasticsearch7.8.0版本进阶——文档处理

目录一、文档冲突1.1、文档冲突的概述1.2、在数据库领域中如何确保并发更新时变更不会丢失1.2.1、悲观并发控制1.2.2、乐观并发控制二、乐观并发控制2.1、Elasticsearch 的概述2.2、Elasticsearch 如何确保文档的旧版本不会覆盖新的版本2.3、Elasticsearch 如何解决相互冲突的变…

洛谷P5738 【深基7.例4】歌唱比赛 C语言/C++

【深基7.例4】歌唱比赛 题目描述 n(n≤100)n(n\le 100)n(n≤100) 名同学参加歌唱比赛&#xff0c;并接受 m(m≤20)m(m\le 20)m(m≤20) 名评委的评分&#xff0c;评分范围是 000 到 101010 分。这名同学的得分就是这些评委给分中去掉一个最高分&#xff0c;去掉一个最低分&…

拍摄的风景视频中,如何快速有效地去除视频中的杂物?

我们在外游玩拍摄的短视频&#xff0c;视频中出现的不必要杂物&#xff0c;比如垃圾、广告或其他不相关的人&#xff0c;会影响视频内容的传达&#xff0c;会降低视频的观感质量。因此&#xff0c;需要去除这些杂物&#xff0c;使得视频更加干净、整洁。让观众更容易理解视频的…

性能分析工具的使用

在数据库调优中&#xff0c;我们的目标就是响应时间更快&#xff0c;吞吐量更大。利用宏观的监控工具和微观的日志分析可以帮我们快速找到调优的思路和方式。 1.数据库服务器优化步骤 数据库调优流程图 整个流程划分成了**观察(Show status&#xff09;和行动&#xff08;Ac…

行测-判断推理-图形推理-样式规律-属性规律-曲直性

左边的图全是由曲线构成的选C1 3 5全是由曲线构成的2 4 6全是由直线构成的第三行的图形有曲有直选A1 3 5有曲有直2 4 6全是直线选D图形有曲有直&#xff0c;排除B D外曲内直->内曲外直->外曲内直->内曲外直->外曲内直->内曲外直所以问号出的图形应该是内曲外直选…