teamtalk实现给指定用户或者群发送消息的http接口
teamtalk实现给指定用户或者群发送消息的http接口
应用场景
- 后台推送消息
- 第三方对接接口
- 系统消息
基本流程
只是说个大概 可以继续改进以便支持更好 用起来更方便
http_msg_server => db_proxy_server
db_proxy_server => http_msg_server
http_msg_server => route_server
route_server => msg_server
原理很简单 只是把原来msg_server的角色换成了 http_msg_server
过程一样 包装一个IMMsgData
实现(最简实现)
1 http_msg_server复用加密操作
httpmsgserver.conf
# add aes_key
aesKey=12345678901234567890123456789012
http 请求 数据体通常是明文字符串或者其他 我们都得格式化成msg_server类似的格式 所以发送的消息内容是要加密的 所以上面我们饮用了类似的方式 配置加密密钥
2 加密实例
file:http_msg_server.cpp
char* str_aes_key = config_file.GetConfigName("aesKey");
if (!str_aes_key || strlen(str_aes_key)!=32) {
log("aes key is invalied");
return -1;
}
pAes = new CAes(str_aes_key);
3 声明
file:HttpQuery.h
// add private methods to class CHttpQuery
static void _SendMessage(const string& strAppKey,Json::Value& post_json_obj, CHttpConn* pHttpConn,int msg_type);
static void _SendSingleMessage(const string& strAppKey,Json::Value& post_json_obj, CHttpConn* pHttpConn);
static void _SendGroupMessage(const string& strAppKey,Json::Value& post_json_obj, CHttpConn* pHttpConn);
// add end
4 实现
file:HttpQuery.cpp
void CHttpQuery::_SendMessage(const string& strAppKey,Json::Value& post_json_obj, CHttpConn* pHttpConn,int msg_type)
{
HTTP::CDBServConn *pConn = HTTP::get_db_serv_conn();
if (!pConn) {
log("no connection to MsgServConn ");
char* response_buf = PackSendResult(HTTP_ERROR_SERVER_EXCEPTION, HTTP_ERROR_MSG[9].c_str());
pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
pHttpConn->Close();
return;
}
if(checkValueIsNullForJson(post_json_obj, "from_user_id") ||
checkValueIsNullForJson(post_json_obj, "session_id") ||
//checkValueIsNullForJson(post_json_obj, "create_time") ||
checkValueIsNullForJson(post_json_obj, "msg") ) {
char* response_buf = PackSendResult(HTTP_ERROR_PARMENT, HTTP_ERROR_MSG[1].c_str());
pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
pHttpConn->Close();
return;
}
try
{
uint32_t user_id = post_json_obj["from_user_id"].asUInt();
uint32_t to_id = post_json_obj["to_user_id"].asUInt();
uint32_t create_time = time(NULL);
string msgContent;
if(post_json_obj["msg"].isString())
{
msgContent = post_json_obj["msg"].asString();
}else if(post_json_obj["msg"].isObject())
{
msgContent = post_json_obj["msg"].toStyledString();
}
char* msg_out = NULL;
uint32_t msg_out_len = 0;
if(pAes->Encrypt(msgContent.c_str(),msgContent.length(),&msg_out,msg_out_len) == 0)
{
msgContent = string(msg_out, msg_out_len);
}
pAes->Free(msg_out);
CDbAttachData attach_data(ATTACH_TYPE_HANDLE, pHttpConn->GetConnHandle());
IM::Message::IMMsgData msg;
msg.set_from_user_id(user_id);
msg.set_to_session_id(to_id);
msg.set_msg_data(msgContent);
msg.set_msg_id(1);
msg.set_msg_type((IM::BaseDefine::MsgType)msg_type);
msg.set_create_time(create_time);
msg.set_attach_data(attach_data.GetBuffer(), attach_data.GetLength());
CImPdu pdu;
pdu.SetPBMsg(&msg);
pdu.SetSeqNum(pHttpConn->GetConnHandle());
pdu.SetServiceId(IM::BaseDefine::SID_MSG);
pdu.SetCommandId(IM::BaseDefine::CID_MSG_DATA);
pConn->SendPdu(&pdu);
}
catch (std::runtime_error msg)
{
log("parse json data failed.");
char* response_buf = PackSendResult(HTTP_ERROR_PARMENT, HTTP_ERROR_MSG[1].c_str());
pHttpConn->Send(response_buf, (uint32_t)strlen(response_buf));
pHttpConn->Close();
}
}
void CHttpQuery::_SendSingleMessage(const string& strAppKey,Json::Value& post_json_obj, CHttpConn* pHttpConn)
{
_SendMessage(strAppKey,post_json_obj,pHttpConn,IM::BaseDefine::MSG_TYPE_SINGLE_TEXT);
}
void CHttpQuery::_SendGroupMessage(const string& strAppKey,Json::Value& post_json_obj, CHttpConn* pHttpConn)
{
_SendMessage(strAppKey,post_json_obj,pHttpConn,IM::BaseDefine::MSG_TYPE_GROUP_TEXT);
}
db写入成功后 转发route_server 让route_server分发到msg_server进而发到客户端
class:DBServConn
// new method
void CDBServConn::_HandleMsgClient(CImPdu *pPdu)
{
IM::Message::IMMsgData msg;
CHECK_PB_PARSE_MSG(msg.ParseFromArray(pPdu->GetBodyData(), pPdu->GetBodyLength()));
CRouteServConn* pRouteConn = get_route_serv_conn();
if (pRouteConn) {
pRouteConn->SendPdu(pPdu);
}
uint32_t msg_id = 0;
if(msg.has_msg_id())
{
msg_id = msg.msg_id();
}
CDbAttachData attach_data((uchar_t*)msg.attach_data().c_str(), msg.attach_data().length());
uint32_t http_handle = attach_data.GetHandle();
CHttpConn* pHttpConn = FindHttpConnByHandle(http_handle);
if(!pHttpConn)
{
log("no http connection");
return;
}
const int bufferSize = 4096;
char response_buf[bufferSize] = {0};
uint32_t outSize = PackSendResult(HTTP_ERROR_SUCCESS, HTTP_ERROR_MSG[0].c_str(),msg_id, response_buf , bufferSize);
pHttpConn->Send(response_buf, outSize);
pHttpConn->Close();
}