稍早我們見識到net.tcp不容易偵錯的黑暗面,但net.tcp的好處在於通訊協定簡單,較HTTP簡潔輕巧,資料採二進位格式,體積比SOAP XML小。由於資料傳輸較少,預期會有較好的執行效能。但以上所說都是按理推想,我對二者資料傳輸量的真實差異感到好奇,便用Microsoft Network Monitor幫它們做了一次斷層掃瞄,分享給對二者差異有興趣的朋友。
沿用先前的範例,在WCF Client端做一點修改:
程式透過HTTP及TCP各呼叫一次GetData(0),程式執行同時開啟MNM側錄網路封包。得到HTTP傳輸內容如下:
分析其傳輸過程為:
- 建立TCP連線:三個封包 52+52+40=144 bytes
- Client傳送HTTP Post Header:395 bytes
- Server回覆Status 100請Client繼續送:65 bytes
- Client送出Post本文,以SOAP包裝的Value參數0:197 bytes
- Server傳回以SOAP包裝的執行結果"You entered: 0":541bytes
排除TCP連線建立過程,整個呼叫涉及四個封包,總傳輸量為395+65+197+541=1198 bytes
接著來看TCP傳輸:
圖中出現的NMF是.Net Message Framing Portocol的縮寫,是一種可取代SOAP XML的二進位資料封裝格式,用於WCF TCP及MSMQ傳輸,它被定位成非公開的WCF內部實作黑箱,所幸在MSDN仍找得到相關文件,這堆封包才沒變成天書。
TCP呼叫的傳輸過程為:
- 建立TCP連線:三個封包 52+52+40=144 bytes
- Client送出一個NFM Preamble Message:93 bytes
- Server回應Preamble Ack Message:41 bytes (下一個TCP控制封包略過不計)
- Client送出內含呼叫參數的Sized Envelop Message:378 bytes
- Server回應內含執行結果"You entered: 0"的Sized Envelop Message:212 bytes (如下圖)
排除TCP連線建立過程,整個呼叫也涉及四個封包,總傳輸量為93+41+378+212=724 bytes
在這個單次呼叫案例中,TCP傳輸比HTTP傳輸少了474 bytes,資料量只有HTTP傳輸的60%。
接著我們再調整程式,建立Service1Client後連呼叫三次GetData()
比較二者傳輸:(我用紅黃藍底色標出三次呼叫的封包)
結果顯示NFM的Preamble Message及Preamble Ack Message只需傳送一次,之後每次GetData()只需兩個封包,而且我還注意到第二次跟第三次的Request與Response的封包都比第一次小(378->263、212->116),比對內容,第二、三次的封包省略掉某些內容(可能先前傳過就不再傳,而HTTP第一個封包也從395->371,其他未變),因此三次呼叫的傳輸量為:
HTTP:395+65+197+541+371+65+197+541+371+65+197+541=3546
TCP:93+41+378+212+263+116+264+116=1483
TCP的傳輸量只有HTTP的41.8%。由此可得,TCP在傳輸效率上大勝HTTP,不難想見此一資料量差距對執行效能的影響。
結論:WCF應用於Intranet時,若Client/Server未受防火牆阻隔,TCP是較佳的選擇。