目录

如何引入

MIMC-Go-SDK的源码已经上传到github中,开发者可以下载至本地GOPATH下安装。

下载源码

    go get github.com/Xiaomi-mimc/mimc-go-sdk
    cd $GOPATH/src/github.com/Xiaomi-mimc/mimc-go-sdk
    go build
    go install

注:go get会从github上fetch所有的分支/tag,默认分支为master分支。

下载依赖库

MIMC-Go-SDK依赖proto buffer进行序列化与反序列化数据,在使用时,确保已经install了proto buffer。如未安装,可参考如下进行安装操作。

    go get github.com/golang/protobuf/proto
    // 进入下载目录
    cd $GOPATH/src/github.com/golang/protobuf/proto
    // 编译安装
    go build
    go install

引入包

在使用MIMC-Go-SDK时,仅需引入一个包即可。

     // 引入包路径, 该路径下引入了mimc包
     import "github.com/Xiaomi-mimc/mimc-go-sdk"

用户创建及初始化

用户登录前需要:创建用户->安全认证->用户在线状态回调->接收消息回调->初始化。

创建用户

    默认支持多设备登录
    import "github.com/XiaoMi-mimc/mimc-go-sdk"
    var appAccount string = "leijun"
    mcUser := mimc.NewUser(appAccount)

安全认证

参考安全认证文档实现:

    /**
     * 同步访问代理认证服务(appProxyService),
     * 从代理认证服务返回结果中解析[小米认证服务下发的原始数据]并返回
     **/
    type Token interface {
        FetchToken() *string
    }

实现该接口后,通过MCUser.registerTokenDelegate(tokenDeleget Token)方法实现token回调的注册, Token接口实现示例如下:

    type TokenHandler struct {
        httpUrl    string
        AppId      int64  `json:"appId"`
        AppKey     string `json:"appKey"`
        AppSecret  string `json:"appSecret"`
        AppAccount string `json:"appAccount"`
    }

    /**
     * 当前示例代码直接访问小米认证服务(TokenService)
     * 实际生产环境上,应该访问代理认证服务(appProxyService)
     **/
    func (this *TokenHandler) FetchToken() *string {
        jsonBytes, err := json.Marshal(*this)
        if err != nil {
            return nil
        }
        requestJsonBody := bytes.NewBuffer(jsonBytes).String()
        request, err := http.Post(this.httpUrl, "application/json", strings.NewReader(requestJsonBody))
        if err != nil {
            return nil
        }
        defer request.Body.Close()
        body, err := ioutil.ReadAll(request.Body)
        if err != nil {
            return nil
        }
        token := string(body)
        return &token
    }

用户在线状态回调

用户状态发生改变时,SDK通过用户在线状态回调来通知开发者进行处理,接口如下:

    type StatusDelegate interface {
        /**
        * @param[isOnline bool] true: 在线,false:离线
        * @param[errType *string] 登录失败类型
        * @param[errReason *string] 登录失败原因
        * @param[errDescription *string] 登录失败原因描述
        */
        HandleChange(isOnline bool, errType, errReason, errDescription *string)
    }

开发者在该接口中实现用户状态变化的业务逻辑,通过MCUser.registerStatusDelegate(statusDelegate StatusDelegate)方法实现用户在线状态回调的注册。

StatusDelegate接口实现示例如下:

    type StatusHandler struct {
    }
    func (this StatusHandler) HandleChange(isOnline bool, errType, errReason, errDescription *string) {
        if isOnline {
            logger.Info("status changed: online.")
            // to do something for online.
        } else {
            logger.Info("status changed: offline.")
            // to do something for offline.
        }
    }

初始化

MCUser初始化以及启动读、写协程。

    mcUser.InitAndSetup()

至此,用户就可以进行登录操作了。

登录

    mcUser.Login()

发送单聊消息

发送单聊消息的接口如下:

    /**
     * @param[toAppAccount string] 接收者
     * @param[msgByte []byte] 开发者自定义消息体
     * @return 客户端生成的数据包Id
     **/
    func (this *MCUser) SendMessage(toAppAccount string, msgByte []byte) string

发送单聊消息示例如下:

    packetId := mcUser.SendMessage("MiFen", []byte("Are you OK?"))

发送群聊消息

发送群聊消息的接口如下:

    /**
     * @param[topicId *int64] 群Id
     * @param[msgByte []byte] 开发者自定义消息体
     * @return 客户端生成的数据包Id
     **/
    func (this *MCUser) SendGroupMessage(topicId *int64, msgByte []byte) string

发送群聊消息示例如下:

    groupId := int64(123456789)
    packetId := mcUser.SendMessage(&groupid, []byte("Are you OK?"))

接收消息

接口概览

当MIMC-Go-SDK收到消息时,会通过消息回调来执行开发者的业务逻辑,主要包括5种回调:

1) 单聊消息回调 2) 群聊消息回调 3) 单聊消息超时回调 4) 群聊消息超时回调 5) 消息送达服务器响应回调

消息回调的接口如下:

type MessageHandlerDelegate interface {
    HandleMessage(packets *list.List)
    HandleGroupMessage(packets *list.List)
    HandleServerAck(packetId *string, sequence, timestamp *int64)
    HandleSendMessageTimeout(message *msg.P2PMessage)
    HandleSendGroupMessageTimeout(message *msg.P2TMessage)
}

在处理“接收单聊/群聊消息”、“单聊/群聊消息超时”以及“消息送达服务器”的业务逻辑时,开发者通过实现MessageHandlerDelegate接口的方法,并通过MCUser.RegisterMessageDelegate(msgDelegate MessageHandlerDelegate)方法实现接收消息回调的注册。

单聊消息回调

单聊消息回调的HandleMessage方法实现示例如下:

    type MsgHandler struct {
    }
    func (this MsgHandler) HandleMessage(packets *list.List) {
        for ele := packets.Front(); ele != nil; ele = ele.Next() {
            p2pmsg := ele.Value.(*msg.P2PMessage)
            logger.Info("[handle p2p msg]%v -> %v, pcktId: %v, timestamp: %v.", *(p2pmsg.FromAccount()), string(p2pmsg.Payload()), *(p2pmsg.PacketId()), *(p2pmsg.Timestamp()))
        }
    }

注:HandleMessage方法中参数packets是P2PMessage的集合。

P2PMessage的结构如下:

type P2PMessage struct {
    packetId     *string 数据包Id
    sequence     *int64  消息序列号
    timestamp    *int64  时间戳
    fromAccount  *string 发送者账号
    toAccount    *string 接收者账号
    payload      []byte  消息体
}

群聊消息回调

群聊消息回调的HandleGroupMessage方法实现示例如下:

    type MsgHandler struct {
    }
    func (this MsgHandler) HandleGroupMessage(packets *list.List) {
        for ele := packets.Front(); ele != nil; ele = ele.Next() {
            p2tmsg := ele.Value.(*msg.P2TMessage)
            logger.Info("[handle p2t msg]%v -> %v, pcktId: %v, timestamp: %v.", *(p2tmsg.FromAccount()), string(p2tmsg.Payload()), *(p2tmsg.PacketId()), *(p2tmsg.Timestamp()))
        }
    }

注:HandleGroupMessage方法中参数packets是P2TMessage的集合。

P2TMessage的结构如下:

type P2TMessage struct {
    packetId     *string 数据包Id
    sequence     *int64  消息序列号
    timestamp    *int64  时间戳
    fromAccount  *string 发送者账号
    groupId      *int64  群Id
    payload      []byte  消息体
}

单聊消息超时回调

单聊消息超时回调的HandleSendMessageTimeout方法的实现示例如下:

    type MsgHandler struct {
    }
    func (this MsgHandler) HandleSendMessageTimeout(message *msg.P2PMessage) {
        logger.Info("[handle p2pmsg timeout] packetId:%v, msg:%v, time: %v.", *(message.PacketId()), string(message.Payload()), time.Now())
    }

群聊消息超时回调

群聊消息超时回调的HandleSendGroupMessageTimeout方法的实现示例如下:

    type MsgHandler struct {
    }
    func (this MsgHandler) HandleSendGroupMessageTimeout(message *msg.P2TMessage) {
        logger.Info("[handle p2tmsg timeout] packetId:%v, msg:%v.", *(message.PacketId()), string(message.Payload()))
    }

消息送达服务器响应回调

消息送达服务器响应回调HandleServerAck方法实现示例如下:

    type MsgHandler struct {
    }
    func (this MsgHandler) HandleServerAck(packetId *string, sequence, timestamp *int64) {
        logger.Info("[handle server ack] packetId:%v, timestamp:%v.", *packetId, *timestamp)
    }

注:超时回调,保证消息比丢失;消息送达服务器时,服务会响应Ack,SDK收到Ack响应才说明消息送达。

退出

    mcUser.Logout()

示例代码

在MIMC-Go-SDK中提供了一个demo,实现两个用户收发消息,该Demo实现可分为以下几步:

1) 实现Token接口

2) 实现StatusDelegate接口

3) 实现MessageHandlerDelegate接口

4) 创建回调接口实现类以及用户

5) 登录、收发消息、退出

demo在MIMC-Go-SDK中的目录如下:

|-$GOPATH
    |-bin
    |-pkg
    |-src
        |-github.com
            |-Xiaomi-mimc
                |-mimc-go-sdk
                    |-demo
                        |-handler
                            |-TokenHandler.go
                            |-StatusHandler.go
                            |-MsgHandler.go
                        |-MCDemo.go

实现Token接口

TokenHandler.go中定义了实现Token接口的struct:TokenHandler。该文件在$GOPATH/src/github.com/Xiaomi-mimc/mimc-go-sdk/demo/handler目录。

实现StatusDelegate接口

StatusHandler.go中定义了实现StatusDelegate接口的struct:StatusHandler。该文件在$GOPATH/src/github.com/Xiaomi-mimc/mimc-go-sdk/demo/handler

实现MessageHandlerDelegate接口

MsgHandler.go中定义了实现MessageDelegate接口的struct:MsgHandler。该文件在$GOPATH/src/github.com/Xiaomi-mimc/mimc-go-sdk/demo/handler目录

创建回调接口实现类以及用户

// 创建三个回调接口的实现类
func createDelegates(appAccount *string) (*handler.StatusHandler, *handler.TokenHandler, *handler.MsgHandler) {
    return handler.NewStatusHandler(), handler.NewTokenHandler(&httpUrl, &apppKey, &appSecurt, appAccount, &appId), handler.NewMsgHandler()
}
// 创建用户
func createUser(appAccount *string) *mimc.MCUser {
    mcUser := mimc.NewUser(*appAccount)
    // 创建Token接口,StatusDelegate接口,MessageDelegate接口的实现类
    statusDelegate, tokenDelegate, msgDelegate := createDelegates(appAccount)
    // 将三个实现类注册给用户,并启动用户内部读写协程
    mcUser.StatusDelegate(statusDelegate).TokenDelegate(tokenDelegate).MsgDelegate(msgDelegate).InitAndSetup()
    return mcUser
}

MIMC-GO-SDK日志设置

import "github.com/Xiaomi-mimc/mimc-go-sdk/util/log"

func init() {
    // SET LOG LEVEL
    log.SetLogLevel(log.InfoLevel)
    // SET GO-SDK LOG PATH  
    log.SetLogPath("./mimc_demo.log")
}

登录、收发消息、退出

    // 创建用户
    leijun := createUser(&appAccount1)
    mifen := createUser(&appAccount2)

    // 用户登录
    leijun.Login()
    mifen.Login()
    mimc.Sleep(3000)

    // 互发消息
    leijun.SendMessage(appAccount2, []byte("Are you OK?"))
    mifen.SendMessage(appAccount1, []byte("I am Fine. Thanks!"))
    mimc.Sleep(15000)

    // 用户退出
    leijun.Logout()
    mifen.Logout()

    mimc.Sleep(3000)

回到顶部

results matching ""

    No results matching ""