BOOL MessageModule_Impl::getHistoryMessage(IN const std::string& sId, IN UInt32 nMsgCount , IN BOOL scrollBottom, OUT std::vector<MessageEntity>& msgList) { //step 0 get message id from cache module::SessionEntity sessEntity; if (!module::getSessionModule()->getSessionEntityBySId(sId, sessEntity)) { LOGA__(ERR,"getSessionEntityBySId failed,sessionId:%s",util::stringToCString(sId)); return FALSE; } UInt32 topMsgId = _getSessionTopMsgId(sId); if (0 == topMsgId) { topMsgId = sessEntity.latestmsgId; } //step 1 query history message from local db std::vector<MessageEntity> msgListTemp; module::getDatabaseModule()->sqlGetHistoryMessage(sId, topMsgId, nMsgCount, msgListTemp); //step 2 compare the topMsgId to latest local db msgId and check which is sequential if (!msgListTemp.empty()) { //todo 还有优化的余地,取出的比msgCount+1的数量,看是否连续的。 MessageEntity& latestMsgEntity = msgListTemp.front(); MessageEntity& firstMsgEntity = msgListTemp.back(); if ((topMsgId == latestMsgEntity.msgId) && ((firstMsgEntity.msgId + nMsgCount - 1) == latestMsgEntity.msgId)) { msgList = msgListTemp; setSessionTopMsgId(sId, firstMsgEntity.msgId-1); return TRUE; } } //final fetch history message from server db imcore::IMLibCoreStartOperationWithLambda( [=]()mutable { LOG__(APP, _T("IMGetMsgListReq history message ,sessionId = %s,sessionName=%s,last msgId = %d,Count = %d") , util::stringToCString(sessEntity.sessionID) ,sessEntity.getName() ,topMsgId, nMsgCount); IM::Message::IMGetMsgListReq imGetMsgListReq; imGetMsgListReq.set_user_id(module::getSysConfigModule()->userId()); imGetMsgListReq.set_session_type((IM::BaseDefine::SessionType)sessEntity.sessionType); imGetMsgListReq.set_session_id(sessEntity.getOriginIntegerSessionId()); imGetMsgListReq.set_msg_id_begin(topMsgId);//服务端是包含当前的那一条的 imGetMsgListReq.set_msg_cnt(nMsgCount); UInt16 reserved = (TRUE == scrollBottom) ? imcore::RESERVED_TYPE_HISTORY_SCROLLBOTTOM_MESSAGE : imcore::RESERVED_TYPE_HISTORY_MESSAGE; module::getTcpClientModule()->sendPacket(IM::BaseDefine::SID_MSG , IM::BaseDefine::CID_MSG_LIST_REQUEST, reserved , &imGetMsgListReq); } ); return FALSE; }
void CImConn::OnRead() { for (;;) { uint32_t free_buf_len = m_in_buf.GetAllocSize() - m_in_buf.GetWriteOffset(); if (free_buf_len < READ_BUF_SIZE) m_in_buf.Extend(READ_BUF_SIZE); int ret = netlib_recv(m_handle, m_in_buf.GetBuffer() + m_in_buf.GetWriteOffset(), READ_BUF_SIZE); if (ret <= 0) break; m_in_buf.IncWriteOffset(ret); while (m_in_buf.GetWriteOffset() >= imcore::HEADER_LENGTH) { uint32_t len = m_in_buf.GetWriteOffset(); uint32_t length = CByteStream::ReadUint32(m_in_buf.GetBuffer()); if (length > len) break; try { imcore::TTPBHeader pbHeader; pbHeader.unSerialize((byte*)m_in_buf.GetBuffer(), imcore::HEADER_LENGTH); LOG__(NET, _T("OnRead moduleId:0x%x,commandId:0x%x"), pbHeader.getModuleId(), pbHeader.getCommandId()); if (m_pTcpSocketCB) m_pTcpSocketCB->onReceiveData((const char*)m_in_buf.GetBuffer(), length); LOGBIN_F__(SOCK, "OnRead", m_in_buf.GetBuffer(), length); } catch (std::exception& ex) { assert(FALSE); LOGA__(NET, "std::exception,info:%s", ex.what()); if (m_pTcpSocketCB) m_pTcpSocketCB->onReceiveError(); } catch (...) { assert(FALSE); LOG__(NET, _T("unknown exception")); if (m_pTcpSocketCB) m_pTcpSocketCB->onReceiveError(); } m_in_buf.Read(NULL, length); } } }
void CImConn::onConnect() { LOGA__(NET, "connect done hanle:%d", m_handle); if (m_pTcpSocketCB) m_pTcpSocketCB->onConnectDone(); }