決定用redis做爲cache服務器,要求其服務端和客戶端都支持跨平臺win和linux
但我發現redis(/做者)對windows態度極差,不考慮,不支持
微軟公司的閒人們主動靠過去,推出win版。這麼一來,redis的
服務端linux版和win版都有了,我就在個人win7上部署了一個win版的redis服務器作調試用,餘不累贅,之後另起課題討論
客戶端用hiredis,其
win版(/日後簡稱winV)在
https://github.com/texnician/hiredis-win32
原版master(日後簡稱masterV)在
https://github.com/redis/hiredislinux
下載來之,解開,對比它兩:
一、winV的examples.h/c直接和核心代碼混在根目錄上,組織亂
二、winV全面用預編譯宏_WIN32來區分平臺代碼,另闢代碼分別實現各個接口,網絡方面的改動最大
三、winV除了新闢的代碼,其它的
3.1 winV刪除了keepalive的接口
3.2 其它的跟masterV區別不大,有些許改動git
確保能編譯winV
一、新建目錄examples,把examples.h/c全趕進去
二、先無論winV其新闢的代碼,把其它的改動,從masterV merge到 winV裏
三、創建vc工程hiredis4win.vcxproj/sln(/下載包裏沒有),把除了test/example以外的全部代碼文件加入進去
四、編譯hiredis4win.vcxproj,發現一堆問題:
4.1 微軟的c編譯器(/c89)不支持c99,而hiredis直接在c99標準上作的,這引發n多的問題:
4.1.1 結構體的初始化的點語法
4.1.2 c89不支持關鍵字bool
4.1.3 c89的變量聲明必須置於做用域的最前頭
4.1.4 c89不支持inline
4.2 linux和win的平臺差別
4.2.1 win下沒有函數
va_copy
gettimeofday
4.2.2 linux以下函數
snprintf
strtoll(x,y,z)
strtoull(x,y,z)
vsnprintf
strcasecmp
strncasecmp
在win下相應有一樣簽名函數
_snprintf
_strtoi64(x,y,z)
_strtoui64(x,y,z)
_vsnprintf
_stricmp
strnicmp
4.4.3 ...github
確保能連接hiredis的test
一、創建hiredis_test.vcxproj/sln,把test.c加入該工程
二、確保hiredis_test.vcxproj能編譯連接redis
運行調試hiredis_test
一、在本地機上運行redis的win版
二、運行過程當中,shift+F5中斷之,結果下次運行的時候,總是報錯:
"Database #9 is not empty, test can not continue\n"
打開redis服務器控制檯,把db#9清空就行了
三、測試進行到
Testing against TCP connection
的時候,發生死鎖。問題因由:
winV函數redisContextSetTimeout的實現,用錯setsockopt。強制類型轉換是原罪!windows
運行hiredis_test的release版
一、死鎖
二、因由:test.c用的assert,在vc的release下是被discard的服務器
讓hiredis支持異步調用
一、hiredis的異步支持,其adapter有三個選擇
ae
libev
libevnet
我選擇libevent;livevent的編譯介紹在 http://my.oschina.net/jacobin/blog/146567
二、把adapters/libevent.h分拆開聲明和實現,實如今libevent.c(/新建)裏。除了redisLibeventAttach,其它函數都是內部函數static網絡