首先感謝永和兄提供c++的webservice伺服器端及客戶端,並且陪我一起熬夜;然後是火石和我做介面的兄弟,雖然都不知道你叫什麼,如果沒有你的合作,東西也沒那麼快完成。
一、由於公司運營火石的《西遊q記》,火石採用的是c++作為開發語言,unix平台,而我們一直使用windows操作平台,.net快速開發。我們之間需要資料的通訊,所以需要利用webservice實現跨平台的資料通訊。儘管webservice是跨平台的,但是實現起來卻並不容易。
二、用c#實現webservice是相當簡單的事情,我們只要建立乙個web服務程式,在方法名上面加上[webmethod],部署到iis上,就能像訪問web站點一樣訪問webservice。用c#編寫客戶端時,只需要將webservice新增到引用,就能像呼叫本地方法一樣去呼叫webservice。像這樣的例子也比比皆是,在這就不多講。
三、用c++實現webservice,一般會用到gsoap,具體方法見:
四、當做完了這些之後,並不代表webservice就能相互通訊了,現在我簡單列舉一下問題:
1、c#提供的webservice的url一般形如:http://localhost/webservice.asmx,但是,c++能提供的只能是:http://localhost/。c++做客戶端的時候呼叫沒有問題,但是當c#做客戶端的時候,引用c++提供的rul時,會提示沒用執行方法(http get method not implemented)。做c#開發的大部分會認為c++方提供的不是webservice,或者說提供的webservice根本就不全,都不帶.asmx檔案。做c++開發的會認為他傳輸的資料符合soap協議,靠http傳輸資料,他就是webservice。
2、當我們解決了第一步後,緊接著會發現另外乙個問題。當我們需要傳輸自定義資料型別時(在c++中稱結構體,在c#中稱實體),從c++返回的資訊中,c#無法構建出實體類。
3、當傳輸的資訊中帶有中文字元時,亂碼滿天飛。
五、為了解決這些問題,我們先簡單了解一下webservice。
web service互操作協議棧:
、服務發現 (uddi)
、服務描述(wsdl)
、服務呼叫(soap)
、訊息編碼 (xml)
、傳輸網路層(http, tcp/ip)
其中wsdl描述webservice都有什麼方法、方法有什麼引數,什麼返回值等。soap(簡單物件訪問協議(****** object access protocol)是一種輕量的、簡單的、基於xml的協議。傳輸的資料就需要遵循這個協議。我比較簡單得認為傳輸的資料需要遵循這種格式。
借用微軟的這個圖描述下webservice的呼叫過程:
六、開始解決問題。作為.net開發人員,我們根本就接觸不到底層的東西,全被封裝了。
c++做的確實是webservice,只是他們需要給提供乙個描述文件,即.wsdl檔案。使用.net提供的wsdl.exe工具,使用命令:wsdl /o: c:\webservice.cs c:\webservice.wsdl。通過webservice.wsdl文件,生成**類,將**類寫入webservice.cs檔案中。我們拷貝這個cs檔案到專案中,將url指向
http://localhost/,就能像以往那樣使用webservice了。
當出現無法傳遞複雜型別資料時,是因為使用gsoap生成的wsdl檔案與.net中生成的wsdl檔案不一樣。具體**如下:
以上為gsoap生成的。返回實體result,實體有兩個屬性:a,b。
以上是.net生成的。
在下面的檔案中,多出
這個便是.net中用來構造實體的。當我們出現情況4.2時,gsoap中盡量使用.net生成的wsdl文件,生成.h檔案,以避免c++中的結構無法在c#中轉換成實體。
第三個問題,我們是通過將中文轉換成16進製制後傳輸過來,然後再轉換成中文。下面提供c#轉換的**:
///
/// 從16進製制轉換成漢字
///
///
///
public static string getchsfromhex(string hex)
// 需要將 hex 轉換成 byte 陣列。
byte bytes = new byte[hex.length / 2];
for (int i = 0; i < bytes.length; i++)
catch }
// 獲得 gb2312,chinese simplified。
system.text.encoding chs = system.text.encoding.getencoding("gb2312");
return chs.getstring(bytes);
}///
/// 從漢字轉換到16進製制
///
///
///
public static string gethexfromchs(string s)
system.text.encoding chs = system.text.encoding.getencoding("gb2312");
byte bytes = chs.getbytes(s);
string str = "";
for (int i = 0; i < bytes.length; i++)
", bytes[i]);
}return str;
}注:以上來轉換**源於網路,c++中轉換的**也可以在網上找到。
三大難題到此結束,其實在整個過程中還有個最大的難題,那就是人與人的交流。因為一方使用c++,一方使用c#,語言不同,各自想問題的方式也不一樣,所以需要相互理解,相互站在對方的角度想問題。多交流、多溝通才是解決問題之道。請不要抱怨c#弱智,也請不要怪c++繁瑣,語言既然存在則有他的價值。
webservice 寫的載入url並返回json
寫了乙個介面實現呼叫別人的介面返回json資料,在自己的介面裡輸出json字串。下面有關於json字串返回值的中文亂碼問題。using system using system.collections.generic using system.io using system.linq using sy...
C C 寫時拷貝
何為寫時拷貝?前面我說過深拷貝淺拷貝,今天我們來 一下寫時拷貝。深拷貝是補充了淺 拷貝的不足,寫時拷貝其實也 就是補充一點深拷貝的不 足。其實寫時拷貝的意思就是 當你讀 取到這個空間的時候,並不會開闢出乙個一 模一樣的空間出 來給你,當你真正需要拷貝的時候,那 麼他就會開闢出空間 給你。也就是拖延版...
關於ticktuple定時寫hbase相關問題
關於 ticktuple 定時寫hbase 相關問題 問題描述 storm為5 臺節點,如果 ticktuple 所屬bolt 的並行度為 2,則只會在這兩台節點上對 bufferemutator 進行初始化,導致其餘三颱節點不會觸發定時寫操作 解決方案 設定 ticktuple 定時bolt 的並...