2012-09-14 48 views
2

我正在製作一個Winamp插件,它具有將通過HTTP播放的歌曲的詳細信息發送到網頁/網絡服務器的單一功能。我找不到像這樣的實際工作,所以決定第一次進入C++並自己做。在DLL中使用最簡單的C++ PUSH通知/ POST解決方案?

該插件是一個C++ DLL文件。我已經得到的地步,我可以輸出每一個新的歌曲播放時間(不壞的C++第一次使用!)歌名到Windows消息框)

我在哪裏卡住:

我找不到任何東西讓我在C++方向AT ALL的推送通知中。

我試過,沒有任何成功,將HTTP庫包含到我的DLL中,以便嘗試發送請求。 libcurl,這library here,和this library也 - 但無法讓他們任何工作!我只是不斷收到鏈接錯誤,然後一些錯誤。幾個小時後,我放棄了。

我是一個非常熟練的JavaScript程序員,所以我認爲可能使用JS連接到推送通知服務可以解決,但在C++中運行JS看起來對我來說太複雜了。也許我錯了?底線,我不知道哪個解決方案更好(閱讀:更容易)實施 - 推送通知或發佈請求?

我很欣賞任何解決方案/輸入/方向/信息或任何你得到的。我可以發佈代碼,但我擁有的唯一代碼是從Winamp獲取歌曲信息的部分,並且該部分有效。

在此先感謝。

編輯:我想這值得注意我正在使用新的VS2012?

+0

Libcurl似乎是一個很好的HTTP實現。嘗試使用它時會出現什麼錯誤? – lvella

+0

你能描述你如何試圖包含HTTP庫嗎?如果你不確切地知道你在做什麼,那麼這些是你最好的一個簡單解決方案的希望,鏈接庫可能會非常棘手。 – Wutz

+0

感謝您的超級及時回覆傢伙。與此同時,我使用名爲Sharpamp的庫從C++轉移到C#。儘管如此,我仍然想解決這個問題,所以我會盡快釋放一些時間,然後回覆你。乾杯。 – pilau

回答

2

可以使用這些類型的庫,但在談到C++時,我主要想到「純代碼」,所以我喜歡本地風格來做某件事,而不需要庫的幫助。

考慮到這一點,我可以提供一個關於如何使用微軟的winsock2庫發送HTTP POST請求的例子。

首先,我想指出我使用this link的基礎上如何使用winsock2.h。

好了,現在能上的代碼,你需要這些包括:

#include <string> 
#include <sstream> 
#include <winsock2.h> 

您還需要鏈接的Winsock2庫(或在您的項目設置中指定,當你使用VS2012):

#pragma comment(lib, "ws2_32.lib") 

現在,我從鏈接編輯的功能(我剛剛修改它,使它看起來更加簡單,同時也做了一些錯誤檢查和適當的清理):

int http_post(char *hostname, char *api, char *parameters, std::string& message) 
{ 
    int result; 

    WSADATA wsaData; 
    result = WSAStartup(MAKEWORD(1, 1), &wsaData); 

    if(result != NO_ERROR) 
    { 
     //printf("WSAStartup failed: %d\n", result); 
     return 0; 
    } 

    sockaddr_in sin; 

    int sock = socket(AF_INET, SOCK_STREAM, 0); 
    if(sock == INVALID_SOCKET) 
    { 
     //printf("Error at socket(): %ld\n", WSAGetLastError()); 
     WSACleanup(); 
     return 0; 
    } 

    sin.sin_family = AF_INET; 
    sin.sin_port = htons(80); 

    struct hostent *host_addr = gethostbyname(hostname); 
    if(host_addr == NULL) 
    { 
     //printf("Unable to locate host\n"); 
     closesocket(sock); 
     WSACleanup(); 
     return 0; 
    } 

    sin.sin_addr.s_addr = *((int *)*host_addr->h_addr_list); 

    if(connect(sock, (const struct sockaddr *)&sin, sizeof(sockaddr_in)) == SOCKET_ERROR) 
    { 
     //printf("Unable to connect to server: %ld\n", WSAGetLastError()); 
     closesocket(sock); 
     WSACleanup(); 
     return 0; 
    } 

    std::stringstream stream; 
    stream << "POST " << api << " HTTP/1.0\r\n" 
      << "User-Agent: Mozilla/5.0\r\n" 
      << "Host: " << hostname << "\r\n" 
      << "Content-Type: application/x-www-form-urlencoded;charset=utf-8\r\n" 
      << "Content-Length: " << strlen(parameters) << "\r\n" 
      << "Accept-Language: en-US;q=0.5\r\n" 
      << "Accept-Encoding: gzip, deflate\r\n" 
      << "Accept: */*\r\n" 
      << "\r\n" << parameters 
    ; 

    if(send(sock, stream.str().c_str(), stream.str().length(), 0) == SOCKET_ERROR) 
    { 
     //printf("send failed: %d\n", WSAGetLastError()); 
     closesocket(sock); 
     WSACleanup(); 
     return 0; 
    } 

    if(shutdown(sock, SD_SEND) == SOCKET_ERROR) 
    { 
     //printf("shutdown failed: %d\n", WSAGetLastError()); 
     closesocket(sock); 
     WSACleanup(); 
     return 0; 
    } 

    char buffer[1]; 

    do 
    { 
     result = recv(sock, buffer, 1, 0); 
     if(result > 0) 
     { 
      //printf("Bytes received: %d\n", result); 
      message += buffer[0]; 
     } 
     else if(result == 0) 
     { 
      //printf("Connection closed\n"); 
     } 
     else 
     { 
      //printf("recv failed: %d\n", WSAGetLastError()); 
     } 
    } 
    while(result > 0); 

    closesocket(sock); 
    WSACleanup(); 

    return 1; 
} 

當您使用DLL時,我將printf s註釋掉了,因此您可以根據Winamp插件API使用正確的輸出函數。

現在,使用的功能,這是不言自明:

std::string post; 
http_post("www.htmlcodetutorial.com", "/cgi-bin/mycgi.pl", "user=example123&artist=The Beatles&music=Eleanor Rigby", post); 

通過這樣做,並檢查函數的返回數量(1成功或0失敗),您可以分析結果字符串從網站返回,並檢查是否一切正常。

關於您最後的問題,使用POST請求是可以的,但作爲網站管理員,您知道可能會「濫用」此選項,例如請求氾濫等。但它確實是最簡單的方法。

如果您在服務器端部分正確解析數據,並檢查是否有任何不正確的請求使用,那麼您可以毫無問題地使用此方法。最後,因爲你是C++初學者,所以你需要知道如何操作std::string來安全地解析歌曲名稱和藝術家到POST POST消息字符串,如果你還不知道,我推薦this link

+1

奇妙的答案!我總是認爲自己做的事情是爲了最好的解決方案,但是因爲我幾乎沒有C++的線索,所以我不忠心地使用了圖書館..諷刺的是,我無法讓他們工作得很好,哈哈,我仍然有這麼多我最終使用了一個名爲Sharpamp的庫,它使用C#編寫Winamp插件,並將PubNub作爲推送通知服務。由於我必須在我的系統中使用PN無論如何,我決定從進程中刪除Web服務器,直接從DLL本身發送通知。乾杯! – pilau