diff options
author | George Hazan <ghazan@miranda.im> | 2018-12-24 22:11:02 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2018-12-24 22:11:02 +0300 |
commit | 6e439e6cab64aaefc5220facac6df88cccef6cf7 (patch) | |
tree | e980249724bde79cd83fd4ca48f012cbc1d8594d /protocols/Icq10 | |
parent | 47e705ac05b2572a687741af3a4141e560caf5d6 (diff) |
Icq10: long poll thread implementation
Diffstat (limited to 'protocols/Icq10')
-rw-r--r-- | protocols/Icq10/src/proto.cpp | 8 | ||||
-rw-r--r-- | protocols/Icq10/src/proto.h | 9 | ||||
-rw-r--r-- | protocols/Icq10/src/server.cpp | 83 |
3 files changed, 86 insertions, 14 deletions
diff --git a/protocols/Icq10/src/proto.cpp b/protocols/Icq10/src/proto.cpp index 95ac9478da..2bf99132f6 100644 --- a/protocols/Icq10/src/proto.cpp +++ b/protocols/Icq10/src/proto.cpp @@ -241,14 +241,6 @@ int CIcqProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre) } //////////////////////////////////////////////////////////////////////////////////////// -// RecvMsg - -MEVENT CIcqProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT* pre) -{ - return 0; -} - -//////////////////////////////////////////////////////////////////////////////////////// // SendContacts int CIcqProto::SendContacts(MCONTACT hContact, int, int nContacts, MCONTACT *hContactsList) diff --git a/protocols/Icq10/src/proto.h b/protocols/Icq10/src/proto.h index 82e65dcfcc..3239d4b7a1 100644 --- a/protocols/Icq10/src/proto.h +++ b/protocols/Icq10/src/proto.h @@ -62,7 +62,10 @@ class CIcqProto : public PROTO<CIcqProto> void ProcessBuddyList(const JSONNode&); void ProcessEvent(const JSONNode&); + void ProcessHistData(const JSONNode&); void ProcessMyInfo(const JSONNode&); + void ProcessPresence(const JSONNode&); + void ProcessTyping(const JSONNode&); HNETLIBCONN m_ConnPool[CONN_LAST]; CMStringA m_szSessionKey; @@ -95,7 +98,10 @@ class CIcqProto : public PROTO<CIcqProto> // threads HANDLE m_hWorkerThread; - void __cdecl ServerThread(void*); + void __cdecl ServerThread(void*); + + HANDLE m_hPollThread; + void __cdecl PollThread(void*); ////////////////////////////////////////////////////////////////////////////////////// // services @@ -131,7 +137,6 @@ class CIcqProto : public PROTO<CIcqProto> HWND CreateExtendedSearchUI(HWND owner) override; int RecvContacts(MCONTACT hContact, PROTORECVEVENT*) override; - MEVENT RecvMsg(MCONTACT hContact, PROTORECVEVENT*) override; int SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) override; HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) override; diff --git a/protocols/Icq10/src/server.cpp b/protocols/Icq10/src/server.cpp index beb829fef7..3743e983a1 100644 --- a/protocols/Icq10/src/server.cpp +++ b/protocols/Icq10/src/server.cpp @@ -181,8 +181,7 @@ void CIcqProto::OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*) for (auto &it : data["events"]) ProcessEvent(it); - m_fetchBaseURL.Append("&first=1"); - Push(new AsyncHttpRequest(CONN_FETCH, REQUEST_GET, m_fetchBaseURL, &CIcqProto::OnFetchEvents)); + m_hPollThread = ForkThreadEx(&CIcqProto::PollThread, 0, 0); } void CIcqProto::OnReceiveAvatar(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) @@ -275,9 +274,43 @@ void CIcqProto::ProcessEvent(const JSONNode &ev) CMStringW szType = ev["type"].as_mstring(); if (szType == L"buddylist") ProcessBuddyList(pData); + else if (szType == L"histDlgState") + ProcessHistData(pData); else if (szType == L"myInfo") ProcessMyInfo(pData); + else if (szType == L"presence") + ProcessPresence(pData); + else if (szType == L"typing") + ProcessTyping(pData); +} + +void CIcqProto::ProcessHistData(const JSONNode &ev) +{ + DWORD dwUin = _wtol(ev["sn"].as_mstring()); + IcqCacheItem *pCache = FindContactByUIN(dwUin); + if (pCache == nullptr) + return; + + for (auto &it : ev["tail"]["messages"]) { + CMStringA msgId(it["msgId"].as_mstring()); + CMStringW type(it["mediaType"].as_mstring()); + if (type != "text") + continue; + + MEVENT hDbEvent = db_event_getById(m_szModuleName, msgId); + if (hDbEvent == 0) { + bool bIsOutgoing = it["outgoing"].as_bool(); + ptrA szUtf(mir_utf8encodeW(it["text"].as_mstring())); + + PROTORECVEVENT pre = {}; + pre.flags = (bIsOutgoing) ? PREF_SENT : 0; + pre.szMsgId = msgId; + pre.timestamp = it["time"].as_int(); + pre.szMessage = szUtf; + ProtoChainRecvMsg(pCache->m_hContact, &pre); + } + } } void CIcqProto::ProcessMyInfo(const JSONNode &ev) @@ -296,6 +329,30 @@ void CIcqProto::ProcessMyInfo(const JSONNode &ev) } } +void CIcqProto::ProcessPresence(const JSONNode &ev) +{ + DWORD dwUin = _wtol(ev["aimId"].as_mstring()); + int iStatus = StatusFromString(ev["state"].as_mstring()); + + IcqCacheItem *pCache = FindContactByUIN(dwUin); + if (pCache) + setDword(pCache->m_hContact, "Status", iStatus); +} + +void CIcqProto::ProcessTyping(const JSONNode &ev) +{ + DWORD dwUin = _wtol(ev["aimId"].as_mstring()); + CMStringW wszStatus = ev["typingStatus"].as_mstring(); + + IcqCacheItem *pCache = FindContactByUIN(dwUin); + if (pCache) { + if (wszStatus == "typing") + CallService(MS_PROTO_CONTACTISTYPING, pCache->m_hContact, 60); + else + CallService(MS_PROTO_CONTACTISTYPING, pCache->m_hContact, PROTOTYPE_CONTACTTYPING_OFF); + } +} + void CIcqProto::OnFetchEvents(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*) { JsonReply root(pReply); @@ -309,6 +366,24 @@ void CIcqProto::OnFetchEvents(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*) for (auto &it : data["events"]) ProcessEvent(it); - - Push(new AsyncHttpRequest(CONN_FETCH, REQUEST_GET, m_fetchBaseURL, &CIcqProto::OnFetchEvents)); } + +void __cdecl CIcqProto::PollThread(void*) +{ + debugLogA("Polling thread started"); + bool bFirst = true; + + while (!m_bTerminated) { + CMStringA szUrl = m_fetchBaseURL; + if (bFirst) { + bFirst = false; + szUrl.Append("&first=1"); + } + else szUrl.Append("&timeout=60000"); + + ExecuteRequest(new AsyncHttpRequest(CONN_FETCH, REQUEST_GET, szUrl, &CIcqProto::OnFetchEvents)); + } + + debugLogA("Polling thread ended"); + m_hPollThread = nullptr; +}
\ No newline at end of file |