.NET Remoting 內建支援雙向通訊,讓伺服器端物件在執行期間回呼客戶端物件方法。本文以「計算機回呼顯示結果」為例,逐步建構完整方案。
| 專案 | 類型 | 職責 |
|---|---|---|
Artech.DuplexRemoting.Contract | Class Library | 定義遠端物件與回呼介面 |
Artech.DuplexRemoting.Remoting | Class Library | 實作遠端物件 |
Artech.DuplexRemoting.Hosting | Console App | Self-Host 遠端物件 |
Artech.DuplexRemoting.Client | Console App | 實作回呼物件並呼叫遠端 |
// IDuplexCalculator.cs
public interface IDuplexCalculator
{
void Add(double x, double y, ICalculatorCallback callback);
}
// ICalculatorCallback.cs
public interface ICalculatorCallback
{
void ShowResult(double x, double y, double result);
}
public class DuplexCalculatorRemoting : MarshalByRefObject, IDuplexCalculator
{
public void Add(double x, double y, ICalculatorCallback callback)
{
Console.WriteLine($"Invoke Add({x}, {y})");
double result = x + y;
callback.ShowResult(x, y, result); // 回呼客戶端
}
}
<configuration>
<system.runtime.remoting>
<application name="Calculator">
<service>
<wellknown mode="SingleCall"
type="Artech.DuplexRemoting.Remoting.DuplexCalculatorRemoting, Artech.DuplexRemoting.Remoting"
objectUri="DuplexCalculator.soap" />
</service>
<channels>
<channel ref="http" port="8080">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="binary" typeFilterLevel="Full" /> <!-- 關鍵 -->
</serverProviders>
<clientProviders>
<formatter ref="binary" />
</clientProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
關鍵點:
typeFilterLevel="Full":預設 Low 會拒絕反序列化 MarshalByRefObject 衍生類別 (回呼物件)。public class CalculatorCallbackHandler : MarshalByRefObject, ICalculatorCallback
{
public void ShowResult(double x, double y, double result)
{
Console.WriteLine($"x + y = {result} where x = {x} and y = {y}");
}
}
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="http" port="0"> <!-- 0 = 動態配埠 -->
<clientProviders>
<formatter ref="binary" />
</clientProviders>
<serverProviders> <!-- 客戶端也需 serverProviders 接收回呼 -->
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
RemotingConfiguration.Configure("Client.exe.config", false);
IDuplexCalculator proxy = (IDuplexCalculator)Activator.GetObject(
typeof(IDuplexCalculator), "https://localhost:8080/Calculator/DuplexCalculator.soap");
proxy.Add(1, 2, new CalculatorCallbackHandler());
Console.Read();
Web.config,內容同 Hosting 的 system.runtime.remoting 區段,補充 system.web/assemblies 參考。https://localhost/虛擬目錄/DuplexCalculator.soap,無需 Hosting 專案即可運作。typeFilterLevel="Full"。