目录
编译
编译工具
编译工具使用bazel
下载源码
git clone git@github.com:Xiaomi-mimc/mimc-cpp-sdk.git
编译库
cd mimc-cpp-sdk
bazel build :mimc_cpp_sdk
编译示例代码
即时消息
cd mimc-cpp-sdk
bazel build :mimc_cpp_demo
实时流
cd mimc-cpp-sdk
bazel build :rts_cpp_demo
编译测试用例
即时消息
cd mimc-cpp-sdk
bazel build :mimc_cpp_test
实时流
cd mimc-cpp-sdk
bazel build :rts_cpp_test
用户创建及初始化
注意:此流程务必全部走完,否则无法登录!
创建用户
/**
* @param[appId]: 应用ID,小米开放平台申请分配
* @param[appAccount]: 用户在APP账号系统内的唯一账号ID
* @param[resource]: 用户设备的标识
* 如不指定,SDK自动生成并支持多设备登录
* 如开发者指定,则需支持多设备登录:
* 同一台设备,resource要保持不变
* 不同设备,resource要相互不同
* @param[cachePath]: 用户配置信息缓存的路径
* 如不指定,则默认以当前运行路径为缓存路径
* 如开发者指定,则以此路径为缓存路径
*/
User(int64_t appId, std::string appAccount, std::string resource = "", std::string cachePath = "");
#include <mimc/user.h>
std::string appId = "2882303761517479657";
std::string appAccount1 = "LeiJun";
User* user = new User(atoll(appId.c_str()), appAccount1);
注册回调函数
安全认证
参考安全认证文档实现:
class MIMCTokenFetcher {
public:
/**
* 同步访问代理认证服务(appProxyService),
* 从代理认证服务返回结果中获取[小米认证服务下发的原始数据]并返回
*/
virtual std::string fetchToken() = 0;
};
#include <mimc/tokenfetcher.h>
#include <curl/curl.h>
···
using namespace std;
class TestTokenFetcher : public MIMCTokenFetcher {
public:
string fetchToken() {
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
CURLcode res;
/**
* 当前示例代码直接访问小米认证服务(TokenService)
* 实际生产环境上,应该访问代理认证服务(appProxyService)
*/
const string url = "https://mimc.chat.xiaomi.net/api/account/token";
const string body = "{\"appId\":\"" + this->appId + "\",\"appKey\":\"" + this->appKey + "\",\"appSecret\":\"" + this->appSecret + "\",\"appAccount\":\"" + this->appAccount + "\"}";
string result;
if (curl) {
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
···
res = curl_easy_perform(curl);
···
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return result;
}
TestTokenFetcher(string appId, string appKey, string appSecret, string appAccount)
{
this->appId = appId;
this->appKey = appKey;
this->appSecret = appSecret;
this->appAccount = appAccount;
}
private:
string appId;
string appKey;
string appSecret;
string appAccount;
};
user->registerTokenFetcher(new TestTokenFetcher(appId, appKey, appSecret, appAccount1));
用户在线状态变化通知
class OnlineStatusHandler {
public:
/**
* @param[status]: 登录状态,Online 在线,Offline 离线
* @param[type]: 状态变化类型
* @param[reason]: 状态变化原因
* @param[desc]: 状态变化描述信息
*/
virtual void statusChange(OnlineStatus status, std::string type, std::string reason, std::string desc) = 0;
};
#include <mimc/onlinestatus_handler.h>
#include <XMDLoggerWrapper.h>
class TestOnlineStatusHandler : public OnlineStatusHandler {
public:
void statusChange(OnlineStatus status, std::string type, std::string reason, std::string desc) {
XMDLoggerWrapper::instance()->info("In statusChange, status is %d, type is %s, reason is %s, desc is %s", status, type.c_str(), reason.c_str(), desc.c_str());
}
};
user->registerOnlineStatusHandler(new TestOnlineStatusHandler());
消息通知
class MessageHandler {
public:
/**
* @param[MIMCMessage]: 单聊消息
* MIMCMessage.packetId: 消息ID
* MIMCMessage.sequence: 服务器为消息分配的递增ID,可用于去重/排序
* MIMCMessage.fromAccount: 发送方账号
* MIMCMessage.fromResource: 发送方设备标识
* MIMCMessage.toAccount: 接收方账号
* MIMCMessage.toResource: 接收方设备标识
* MIMCMessage.payload: 消息体
* MIMCMessage.bizType: 消息类型
* MIMCMessage.timestamp: 发送时间戳
*/
//接收单聊消息通知
virtual void handleMessage(std::vector<MIMCMessage> packets) = 0;
/**
* @param[MIMCGroupMessage]: 群聊消息
* MIMCGroupMessage.packetId: 消息ID
* MIMCGroupMessage.sequence: 服务器为消息分配的递增ID,可用于去重/排序
* MIMCGroupMessage.fromAccount: 发送方账号
* MIMCGroupMessage.fromResource: 发送方设备标识
* MIMCGroupMessage.topicId: 群ID
* MIMCGroupMessage.payload: 消息体
* MIMCGroupMessage.bizType: 消息类型
* MIMCGroupMessage.timestamp: 发送时间戳
*/
//接收群聊消息通知
virtual void handleGroupMessage(std::vector<MIMCGroupMessage> packets) = 0;
/**
* @param[packetId]: 客户端生成的消息ID
* @param[sequence]: 服务器为消息分配的递增ID,可用于去重/排序
* @param[timestamp]: 消息发送到服务器的时间(单位:ms)
* @param[desc]: 服务器返回的描述信息
*/
//发送消息成功或失败通知
virtual void handleServerAck(std::string packetId, int64_t sequence, time_t timestamp, std::string desc) = 0;
//发送单聊消息超时通知
virtual void handleSendMsgTimeout(MIMCMessage message) = 0;
//发送群聊消息超时通知
virtual void handleSendGroupMsgTimeout(MIMCGroupMessage groupMessage) = 0;
};
#include <mimc/message_handler.h>
#include <mimc/threadsafe_queue.h>
#include <mimc/mimc_group_message.h>
class TestMessageHandler : public MessageHandler {
public:
void handleMessage(std::vector<MIMCMessage> packets) {
std::vector<MIMCMessage>::iterator it = packets.begin();
for (; it != packets.end(); ++it) {
messages.push(*it);
}
}
void handleGroupMessage(std::vector<MIMCGroupMessage> packets) {
std::vector<MIMCGroupMessage>::iterator it = packets.begin();
for (; it != packets.end(); ++it) {
groupMessages.push(*it);
}
}
void handleServerAck(std::string packetId, int64_t sequence, time_t timestamp, std::string desc) {
packetIds.push(packetId);
}
void handleSendMsgTimeout(MIMCMessage message) {
···
}
void handleSendGroupMsgTimeout(MIMCGroupMessage groupMessage) {
...
}
MIMCMessage* pollMessage() {
MIMCMessage *messagePtr;
messages.pop(&messagePtr);
return messagePtr;
}
MIMCGroupMessage* pollGroupMessage() {
MIMCGroupMessage *groupMessagePtr;
groupMessages.pop(&groupMessagePtr);
return groupMessagePtr;
}
std::string* pollServerAck() {
std::string *packetIdPtr;
packetIds.pop(&packetIdPtr);
return packetIdPtr;
}
private:
ThreadSafeQueue<MIMCMessage> messages;
ThreadSafeQueue<MIMCGroupMessage> groupMessages;
ThreadSafeQueue<std::string> packetIds;
};
TestMessageHandler* messageHandler = new TestMessageHandler();
user->registerMessageHandler(messageHandler);
登录
user->login(); //此处会检查相关回调函数是否均已注册,如果有回调函数尚未注册,则返回false
发送消息
发送单聊消息
/**
* @param[toAppAccount]: 消息接收者在APP账号系统内的唯一账号ID
* @param[payload]: 开发者自定义消息体,最大不超过15KB
* @param[bizType]: 开发者自定义消息类型,默认为空
* @param[isStore]: 消息是否存储在mimc服务端,true 存储,false 不存储,默认存储
* @return: 客户端生成的消息ID
* 返回空串:消息未进入发送队列
*/
std::string sendMessage(const std::string& toAppAccount, const std::string& payload, const std::string& bizType = "", const bool isStore = true);
string payload1 = "With MIMC, We can communicate with each other much easier!";
string packetId_sent1 = user->sendMessage(toAppAccount, payload1);
发送群聊消息
/**
* @param[topicId]: 群ID
* @param[payload]: 开发者自定义消息体,最大不超过15KB
* @param[bizType]: 开发者自定义消息类型,默认为空
* @param[isStore]: 消息是否存储在mimc服务端,true 存储,false 不存储,默认存储
* @return: 客户端生成的消息ID
* 返回空串:消息未进入发送队列
*/
std::string sendGroupMessage(int64_t topicId, const std::string& payload, const std::string& bizType = "", const bool isStore = true);
string payload1 = "With MIMC, We can communicate with each other much easier!";
string packetId_sent1 = user->sendGroupMessage(topicId, payload1);
接收消息
接收单聊消息
#include <mimc/mimcmessage.h>
#include <XMDLoggerWrapper.h>
MIMCMessage *message;
while (message = messageHandler->pollMessage())
{
XMDLoggerWrapper::instance()->info("Message from %s to %s is %s", message->getFromAccount().c_str(), message->getToAccount().c_str(), message->getPayload().c_str());
}
接收群聊消息
#include <mimc/mimc_group_message.h>
#include <XMDLoggerWrapper.h>
MIMCGroupMessage *groupMessage;
while (groupMessage = messageHandler->pollGroupMessage())
{
XMDLoggerWrapper::instance()->info("Message from %s to topic %llu is %s", groupMessage->getFromAccount().c_str(), groupMessage->getTopicId(), groupMessage->getPayload().c_str());
}
注销
user->logout();