From 32d1c295ac763fdf069ac6915d772c0b92818fc4 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 12 Oct 2013 22:33:13 +0000 Subject: VK: - notification thread now works as expected; - message reading works ok too; - notification about new messages also works ok git-svn-id: http://svn.miranda-ng.org/main/trunk@6467 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/VKontakte/src/misc.cpp | 11 ++++++ protocols/VKontakte/src/version.h | 4 +-- protocols/VKontakte/src/vk_proto.cpp | 18 +++++++++- protocols/VKontakte/src/vk_proto.h | 7 +++- protocols/VKontakte/src/vk_thread.cpp | 65 ++++++++++++++++++++++++++++------- 5 files changed, 88 insertions(+), 17 deletions(-) (limited to 'protocols/VKontakte/src') diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp index b4f27823cb..2d7cc09fca 100644 --- a/protocols/VKontakte/src/misc.cpp +++ b/protocols/VKontakte/src/misc.cpp @@ -59,6 +59,17 @@ HANDLE CVkProto::FindUser(LPCSTR pUserid, bool bCreate) return hNewContact; } +bool CVkProto::CheckMid(int msgid) +{ + for (int i=m_sendIds.getCount()-1; i >= 0; i--) + if (m_sendIds[i] == (HANDLE)msgid) { + m_sendIds.remove(i); + return true; + } + + return false; +} + LPCSTR findHeader(NETLIBHTTPREQUEST *pReq, LPCSTR szField) { for (int i=0; i < pReq->headersCount; i++) diff --git a/protocols/VKontakte/src/version.h b/protocols/VKontakte/src/version.h index e035ffeb5d..4cf96d5613 100644 --- a/protocols/VKontakte/src/version.h +++ b/protocols/VKontakte/src/version.h @@ -1,6 +1,6 @@ #define __MAJOR_VERSION 0 -#define __MINOR_VERSION 0 -#define __RELEASE_NUM 1 +#define __MINOR_VERSION 1 +#define __RELEASE_NUM 0 #define __BUILD_NUM 1 #define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp index 2ef53906ea..07740f4725 100644 --- a/protocols/VKontakte/src/vk_proto.cpp +++ b/protocols/VKontakte/src/vk_proto.cpp @@ -20,6 +20,7 @@ along with this program. If not, see . CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) : PROTO(szModuleName, ptszUserName), m_arRequestsQueue(10), + m_sendIds(3, PtrKeySortT), m_msgId(1) { InitQueue(); @@ -146,13 +147,28 @@ int CVkProto::SendMsg(HANDLE hContact, int flags, const char *msg) { "message", szMsg }, { "access_token", m_szAccessToken } }; - PushAsyncHttpRequest(REQUEST_GET, "/method/messages.send.json", true, NULL, SIZEOF(params), params); + PushAsyncHttpRequest(REQUEST_GET, "/method/messages.send.json", true, &CVkProto::OnSendMessage, SIZEOF(params), params); ULONG msgId = ::InterlockedIncrement(&m_msgId); ForkThread(&CVkProto::SendMsgAck, new TFakeAckParams(hContact, msgId)); return msgId; } +void CVkProto::OnSendMessage(NETLIBHTTPREQUEST *reply, void*) +{ + debugLogA("CVkProto::OnSendMessage %d", reply->resultCode); + if (reply->resultCode != 200) + return; + + JSONROOT pRoot(reply->pData); + if ( !CheckJsonResult(pRoot)) + return; + + JSONNODE *pResponse = json_get(pRoot, "response"); + if (pResponse != NULL) + m_sendIds.insert((HANDLE)json_as_int(pResponse)); +} + ////////////////////////////////////////////////////////////////////////////// int CVkProto::SetStatus(int iNewStatus) diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index a0a7cbb708..14c4e6b354 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -100,12 +100,14 @@ struct CVkProto : public PROTO void RetrieveUnreadMessages(); void OnReceiveMessages(NETLIBHTTPREQUEST*, void*); + void OnSendMessage(NETLIBHTTPREQUEST*, void*); void RetrievePollingInfo(); void OnReceivePollingInfo(NETLIBHTTPREQUEST*, void*); void __cdecl PollingThread(void*); int PollServer(); + void PollUpdates(JSONNODE*); void OnReceivePolling(NETLIBHTTPREQUEST*, void*); int SetServerStatus(int); @@ -164,6 +166,9 @@ private: UINT_PTR m_timer; ptrA m_pollingServer, m_pollingKey, m_pollingTs; - HANDLE m_hPollingThread; + HANDLE m_pollingConn; ULONG m_msgId; + + LIST m_sendIds; + bool CheckMid(int msgid); }; diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp index dccb5ae658..20a4cbde22 100644 --- a/protocols/VKontakte/src/vk_thread.cpp +++ b/protocols/VKontakte/src/vk_thread.cpp @@ -346,7 +346,7 @@ void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, void*) JSONNODE *pMsgs = json_as_array( json_get(pResponse, "msgs")); if (pMsgs == NULL) - return; + pMsgs = pResponse; CMStringA mids; @@ -360,7 +360,7 @@ void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, void*) int datetime = json_as_int( json_get(pMsg, "date")); int isOut = json_as_int( json_get(pMsg, "out")); int uid = json_as_int( json_get(pMsg, "uid")); - int isRead = json_as_int( json_get(pMsg, "uid")); + int isRead = json_as_int( json_get(pMsg, "read_state")); ptrT ptszBody( json_as_string( json_get(pMsg, "body"))); char szUserid[40], szMid[40]; @@ -426,30 +426,64 @@ void CVkProto::OnReceivePollingInfo(NETLIBHTTPREQUEST *reply, void*) ///////////////////////////////////////////////////////////////////////////////////////// +void CVkProto::PollUpdates(JSONNODE *pUpdates) +{ + debugLogA("CVkProto::PollUpdates"); + + CMStringA mids; + int msgid; + + JSONNODE *pChild; + for (int i=0; (pChild = json_at(pUpdates, i)) != NULL; i++) { + JSONNODE *pArray = json_as_array(pChild); + if (pArray == NULL) + continue; + + switch (json_as_int( json_at(pArray, 0))) { + case 4: // new message + msgid = json_as_int( json_at(pArray, 1)); + if ( !CheckMid(msgid)) { + if ( !mids.IsEmpty()) + mids.AppendChar(','); + mids.AppendFormat("%d", msgid); + } + break; + } + } + + if ( !mids.IsEmpty()) { + HttpParam params[] = { + { "mids", mids }, + { "access_token", m_szAccessToken } + }; + PushAsyncHttpRequest(REQUEST_GET, "/method/messages.getById.json", true, &CVkProto::OnReceiveMessages, SIZEOF(params), params); + } +} + int CVkProto::PollServer() { debugLogA("CVkProto::PollServer"); - RetrieveUnreadMessages(); NETLIBHTTPREQUEST req = { sizeof(req) }; req.requestType = REQUEST_GET; req.szUrl = NEWSTR_ALLOCA(CMStringA().Format("%s?act=a_check&key=%s&ts=%s&wait=25&access_token=%s", m_pollingServer, m_pollingKey, m_pollingTs, m_szAccessToken)); - req.flags = NLHRF_DUMPASTEXT | NLHRF_SSL | NLHRF_HTTP11; - req.timeout = 3600; + req.flags = NLHRF_NODUMP | NLHRF_HTTP11 | NLHRF_PERSISTENT; + req.nlc = m_pollingConn; + req.timeout = 30000; NETLIBHTTPREQUEST *reply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req); if (reply == NULL) return 0; - int retVal = -1; + int retVal = 0; if (reply->resultCode = 200) { JSONROOT pRoot(reply->pData); if ( CheckJsonResult(pRoot)) { - JSONNODE *pResponse = json_get(pRoot, "response"); - if (pResponse != NULL) { - m_pollingTs = mir_t2a( ptrT( json_as_string( json_get(pResponse, "ts")))); - retVal = 1; - } + m_pollingTs = mir_t2a( ptrT( json_as_string( json_get(pRoot, "ts")))); + JSONNODE *pUpdates = json_get(pRoot, "updates"); + if (pUpdates != NULL) + PollUpdates(pUpdates); + retVal = 1; } else retVal = 0; } @@ -460,11 +494,16 @@ int CVkProto::PollServer() void CVkProto::PollingThread(void*) { - m_hPollingThread = GetCurrentThread(); + NETLIBOPENCONNECTION nloc = { sizeof(nloc) }; + nloc.flags = NLOCF_HTTP | NLOCF_V2; + nloc.szHost = m_pollingServer; + nloc.wPort = 80; // shame! shame! shame! + if ((m_pollingConn = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)m_hNetlibUser, (LPARAM)&nloc)) == NULL) + return; while (!m_bTerminated) if (PollServer() == -1) break; - m_hPollingThread = NULL; + CallService(MS_NETLIB_CLOSEHANDLE, (WPARAM)m_pollingConn, 0); } -- cgit v1.2.3