探討WCF雙工服務時發現WsDualHttpBinding不實用(Server會回頭連Client的80 Port)、NetTcpBinding難穿防火牆,二者均難應用於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 設定即可覆寫這個行為:

  1. Always-這會強制使用 WebSockets,甚至用於要求-回覆合約。
  2. Never-這會避免使用 WebSockets。 嘗試將這個設定用於雙工合約會導致例外狀況。
  3. WhenDuplex-這是預設值,行為方式如上所述。

沿用前文的Timer.svc範例,要改用NetHttpBinding的很簡單,將endpoint的bind改成"netHttpBinding"、一切搞定!

    <services>
      <service name="WcfWas.Timer">
        <endpoint binding="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)。參考


Comments

# by Jerfong

WsDualHttpBinding不實用(Server會回頭連Client的80 Port)、NetHttpBinding(筆誤,應為NetTcpBinding)難穿防火牆

# by Jeffrey

to Jerfong, 特大號筆誤(暈),謝謝指正。

# by WangGang

请教一下MNM是什么工具?

# by wanggang

请教一下MNM是什么工具?

# by Jeffrey

to WangGang, Microsoft Network Monitor: https://dotblogs.com.tw/chou/archive/2010/06/29/16256.aspx

Post a comment