探討WCF雙工服務時發現WsDualHttpBinding不實用(Server會回頭連Client的80 Port)、NetHttpBinding難穿防火牆,二者均難應用於Internet,有實作Polling的Silverlight版Binding又無法用於其他程式,查了資料,才發現.NET 4.5+增加了一個神奇的NetHttpBinding,支援WebSocket!
為什麼在研究預設Binding時會沒看到它?難道是我人呆眼瞎?重看.NET 4.5的Configuring System-Provided Bindings文件,還真的沒有耶 :P 猜想是.NET 4.5直接沿用舊版文件,沒補上新項目的緣故。用力再查過一回,在System-Provided Bindings發現另一份更完整的版本,就包NetHttpBinding、NetHttpsBinding等幾個先前未提過的Binding,這部分日後再來補完。
而依據文件的介紹:
NetHttpBinding 是為了使用 HTTP 或 WebSocket 服務而設計的繫結,其預設會使用二進位編碼,並會偵測其所搭配使用的是要求-回覆合約還是雙工合約,改變行為配合,也就是針對要求-回覆合約使用 HTTP,並針對雙工合約使用 WebSockets。 使用 WebSocketTransportUsage 設定即可覆寫這個行為:
- Always-這會強制使用 WebSockets,甚至用於要求-回覆合約。
- Never-這會避免使用 WebSockets。 嘗試將這個設定用於雙工合約會導致例外狀況。
- WhenDuplex-這是預設值,行為方式如上所述。
沿用前文的Timer.svc範例,要改用NetHttpBinding的很簡單,將endpoint的bind改成"netHttpBinding"、一切搞定!
<services>
<servicename="WcfWas.Timer">
<endpointbinding="netHttpBinding"contract="WcfWas.ITimer"/>
</service>
</services>
照慣例,開啟MNM觀察封包驗證效果:
觀察到二者建立連線後沒多久,Server便傳回HTTP 101,Switching procotols,要求升級成WebSocket。
之後Server端每秒一次的Callback,傳送的內容已不再是HTTP。第一次Callback傳回140 Bytes:
第二次起降到95 Bytes:
由以上結果,證實NetHttpBinding採二進位編碼並可使用WebSocket協定的特性,是可用於Internet的WCF雙工服務解決方案。
註:要使用WebSocket,Client、Server需為Windows 8、Windows Server 2012以上版本(或IIS Express 8 on Windows 2008 R2)。參考