使用mysql_udf與curl庫完成http_post通訊模組示例
使用mysql_udf與curl庫完成http_post通訊模組(mysql_udf,multi_curl,http,post)
這個模組其目前主要用於xoyo江湖的sns與kingsoft_xoyo自主研發的TCSQL資料庫做資料同步,當有feed插入sns資料庫,使用觸 發器呼叫該模組,向tcsql資料庫傳送同步資料。也可以使用該模組與其它使用socket介面的資料庫或程式做轉發與同步。
http_post模組主要使用mysql_udf介面,與curl庫兩部分技術。
mysql_udf是mysql為c語言提供的一個介面,透過這個介面,使用者可以自定義mysql的函式,透過呼叫這些mysql函式,呼叫相應的c語言 模組來執行特定功能,實現mysql資料與外部應用的互動。curl庫是一個比較常用的應用層網路協議庫,主要用到的是其中的curl_multi非同步通 信api,用來進行網路傳輸。
首先參考mysql官方提供的udf_example.c檔案,建立3個主要的介面函式,分別是初始化函式,執行函式與解構函式。
複製程式碼 程式碼如下:
//args是sql語句傳回的引數,message是返回出錯資訊使用這些都是規定好的。
my_bool http_post_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
//主函式體
longlong http_post(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error);
//解構函式體
void http_post_deinit(UDF_INIT *initid);
//args是sql語句傳回的引數,message是返回出錯資訊,使用這些都是規定好的。
//初始化函式體 my_bool http_post_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
//主函式體 longlong http_post(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error);
//解構函式體 void http_post_deinit(UDF_INIT *initid);
在mysql_udf介面中,主函式體中是不允許使用new或malloc動態分配記憶體,所以如果需要申請記憶體空間,必須用xxxx_init()函式申 請並將申請的地址賦給initid->ptr指標,然後在主函式體中使用,並在xxxx_deinit解構函式體中釋放。另外對於 mysql_udf介面的呼叫好像當併發量超過一定程度,如果是使用動態分配記憶體,會出現double free的錯誤,為了避免這個錯誤,所以在我的程式裡使用靜態空間與動態申請空間相結合的方式,這樣如果資料較小,併發量較大,不會出現double free錯誤。對於靜態申請空間,最大約在160000~170000byte左右,我這裡使用的160000,當mysql傳送的資料大於這個數的時 候,才動態申請記憶體。初始化函式體如下:
複製程式碼 程式碼如下:
my_bool http_post_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count != 2)
{
strcpy(message,"Wrong arguments to http_post; ");
return 1;
}
if(args->arg_count == 2 && args->args[1]!=NULL)
{
int flexibleLength = strlen(args->args[1]);
if(flexibleLength > 160000)
{
int allocLength = 200 + flexibleLength;
if (!(initid->ptr=(char*) malloc(allocLength) ) )
{
strcpy(message,"Couldn't allocate memory in http_post_init");
return 1;
}
return 0;
}
else
{
initid->ptr=NULL;
}
}
return 0;
}
其中http_post_init需要返回my_bool型。這個函式目的是給使用者提供一個方式,檢驗由mysql引數傳進來的資料是否正確,如果正確則 返回0,則mysql會自動呼叫定義的主函式,如果返回1,則mysql列印message資訊退出,不會呼叫主函式。所以在設定返回值的時候一定注意。
主函式如下:
複製程式碼 程式碼如下:
longlong http_post( UDF_INIT *initid, UDF_ARGS *args,
char *is_null __attribute__((unused)),
char *error __attribute__((unused)))
{
char* sendBuffer=NULL;
CURL *curl;
CURLM *multi_handle;
int still_running;
int times=0;//try times if select false
int TRY_TIMES=25;
struct timeval timeout;//set a suitable timeout to play around with
timeout.tv_sec = 0;
timeout.tv_usec = 100000;
char sendArray[160000] = "
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3034/viewspace-2804376/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Android 使用Socket完成程式間通訊Android
- 使用4G通訊模組和MQTT協議,完成物聯網裝置開發。MQQT協議
- Flutter與Native通訊示例及原始碼分析Flutter原始碼
- CoreData:使用CoreData完成一個通訊錄儲存
- Linux TCP通訊示例LinuxTCP
- QT使用 http 協議通訊的實現示例QTHTTP協議
- curl 安裝與使用
- socket 完成簡單的通訊
- JavaScript和Macromedia Flash的通訊示例JavaScriptMac
- DBI 資料庫模組剖析:Perl DBI 資料庫通訊模組規範,工作原理和例項資料庫
- 模組化通訊方式對比
- python 多程式通訊模組Python
- 在K8S中,各模組如何與APlServer通訊?K8SServer
- Android模組化改造以及模組化通訊框架Android框架
- NetCore WebSocket 即時通訊示例NetCoreWeb
- linux環境程式設計(2): 使用pipe完成程式間通訊Linux程式設計
- 移遠 EC20 模組(4G通訊模組)AT指令測試 TCP 通訊過程TCP
- curl常用引數詳解及示例
- Python模組 adorner 的使用示例Python
- Python非同步通訊模組asynchatPython非同步
- Python非同步通訊模組asyncorePython非同步
- linux環境程式設計(3): 使用POSIX IPC完成程式間通訊Linux程式設計
- Binder通訊機制與IPC通訊.md
- 使用者層與驅動層通訊
- 安卓開發之Fragment的使用與通訊安卓Fragment
- Vue使用JSBridge與原生APP通訊VueJSAPP
- 從Android到ReactNative開發(二、通訊與模組實現)AndroidReact
- ES系列(三):網路通訊模組解析
- Golang | 簡介channel常見用法,完成goroutin通訊Golang
- c++ primer 訊息處理示例+課後習題完成C++
- 使用CURL獲取速賣通詳情的API介面API
- 通過示例學習使用 netstat
- 序列通訊與並行通訊的區別並行
- php curl使用PHP
- Fragment與Activity通訊Fragment
- PHP 中 CURL 使用之 CURL 詳解!PHP
- 組態王與Access資料庫通訊--④資料庫測試資料庫
- 巴圖自動化Profinet協議轉Modbus協議模組接稱重模組與PLC通訊協議