3

自定义IM消息类型

 3 years ago
source link: https://my.oschina.net/u/4581100/blog/4837442
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
自定义IM消息类型 - 时信魔方的个人空间 - OSCHINA - 中文开源技术交流社区

在进行应用程序开发时,对于不同的场景我们往往需要设计不同的消息,一般的,我们使用 消息类型 来描述不同的消息形式,比如文字信息的消息我们定义为 “文本消息” ,消息里包含了图片数据的消息我们定义为 “图片消息” 等等。

在 Cube 里可以通过 Plugin System 插件系统实现自定义消息,通过定义消息的负载格式来标记不同类型的消息。

教程演示程序截图△ 自定义消息示例程序截图

Cube 的 Plugin 基于事件通知机制来实现插件对特定事件的响应和处理。也就是说,Cube 的每个模块会根据自身的技术特点,在必要的工作流程里加入 Hook 来通知插件进行必要的数据干预。

消息模块的插件会接收到来自消息模块内部的消息实例对象 Message ,调用插件之后插件需要返回被处理的 Message 实例以便消息模块继续后续的处理流程。下图是 MessagePluginSent 事件时响应 onInstantiate 事件的流程。

Flow

通过这个流程,最终监听器收到 Sent 事件时接收参数就是由插件分化的消息实例了。

自定义消息

为了能让我们的插件识别不同的消息类型,我们在消息的负载数据里定义一个 "type" 字段来表示消息的类型,并约定好 text 表示文本消息,image 表示图片消息。这样,文本消息的负载格式就是:

{
    "type": "text",
    "content": "这里是文本内容"
}

图片消息的负载格式就是:

{
    "type": "image"
}

图片文件数据由 Message 的文件附件功能进行处理。

文本消息从 Message 继承,以便符合消息模块插件的处理机制,即插件需要返回一个有效的 Message 实例。

TextMessage

JavaScript 代码:

var TextMessage = Class(Message, {

    /** 构造函数 */
    ctor: function(param) {
        if (typeof param === 'string') {
            $super.call(this, Message, { "type": "text", "content" : param });
        }
        else {
            $super.call(this, Message, param);
        }
    }

    /**
     * @returns {string} 返回消息类型。
     */
    getType: function() {
        return this.getPayload().type;
    }
});

在这里我们使用了两个辅助函数 Class()$super() 帮我们快速创建 JavaScript 类。

同样的,图片消息也需要从 Message 继承。我们在图片消息里,启动消息附件的生成缩略图功能,就能让 Cube 自动生成消息附件里图片的缩略图。使用消息文件附件 FileAttachmentgetDefaultThumbURL() 就能得到缩略图文件的 URL 地址。

ImageMessage

JavaScript 代码:

var ImageMessage = Class(Message, {

    /** 构造函数 */
    ctor: function(param) {
        $super.call(this, Message, param);
        this.setPayload({ "type": "image" });

        // 启用缩略图功能
        this.getAttachment().enableThumb();
    },

    /**
     * @returns {string} 返回消息类型。
     */
    getType: function() {
        return this.getPayload().type;
    }
});

在这里我们使用了两个辅助函数 Class()$super() 帮我们快速创建 JavaScript 类。

消息类型分类插件

定义好我们需要的消息之后,我们就需要让插件按照我们制定的类型就行消息实例的分化,这样应用程序就能根据不同的消息类型就行消息处理和展示了。

创建我们的插件类 MessageTypePlugin,并从 MessagePlugin 继承。

MessageTypePlugin

MessageTypePlugin 的代码:

JavaScript 代码:

var MessageTypePlugin = Class(MessagePlugin, {
    /** 构造函数 */
    ctor: function() {
        $super.call(this, MessagePlugin);
    },

    /**
     * 当消息需要实例化(分化)时调用该回调。
     * @param {Message} message 原始消息实例。
     * @returns {*} 消息实例。
     */
    onInstantiate: function(message) {
        var payload = message.getPayload();

        if (undefined !== payload.type) {
            if (payload.type == 'text') {
                return new TextMessage(message);
            }
            else if (payload.type == 'image') {
                return new ImageMessage(message);
            }
        }

        return message;
    }
}

我们已经有了插件和消息类,现在就可以把插件注册到消息模块。

JavaScript 代码:

cube.messaging.register(new MessageTypePlugin());

插件可以在调用 Cube start() 之前注册。

插件注册之后,当消息模块需要实例化消息实体时就会触发 onInstantiate 获得实例化的消息对象,这样我们就通过插件将我们自定义的 TextMessageImageMessage 对象返回给消息模块进行处理,并由消息模块事件发送给应用程序,这样应用程序就获得具体的带消息类型的消息实例对象了。

> 作者:徐江威 > > 日期:2020年12月24日


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK