簡體   English   中英

WCF雙工服務頻道關閉

[英]WCF Duplex Service Channel Close

我有一個基於WCF雙工服務的應用程序。 當用戶“重新啟動”應用程序所做的工作時,我遇到了問題......客戶端關閉了與WCF服務的連接並創建了另一個。 服務合同的定義是這樣的......

[ServiceContract(Namespace="net.tcp://namespace.MyService",
    SessionMode=SessionMode.Required,
    CallbackContract=typeof(IServiceCallback))]
public interface IMyService
{
    [OperationContract(IsOneWay=true)]
    void DoWork();
}


public interface IServiceCallback
{
    [OperationContract(IsOneWay=true)]
    void SendMessage(string message);
}

實現定義為:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,
    InstanceContextMode = InstanceContextMode.PerSession,
    UseSynchronizationContext = false,
    IncludeExceptionDetailInFaults = true)]
public class MyService : IMyService
{
    public void DoWork()
    {
        var callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();
        callback.SendMessage("Hello, world.");
    }
}

客戶端的配置如下:

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="net.tcp" receiveTimeout="02:00:00" sendTimeout="02:00:00" maxReceivedMessageSize="2147483647">
          <security mode="None"/>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://localhost:8000/MyService/MyService"
          binding="netTcpBinding" bindingConfiguration="net.tcp" contract="ExternalServiceReference.IMyService">
      </endpoint>
    </client>
  </system.serviceModel>

配置服務:

<system.serviceModel>
<behaviors>
  <serviceBehaviors>
    <behavior name="serviceBehaviour">
      <serviceMetadata />
    </behavior>
  </serviceBehaviors>
</behaviors>
<bindings>
  <netTcpBinding>
    <binding name="netTcp" sendTimeout="01:00:00" receiveTimeout="01:00:00" >
      <security mode="None">
      </security>
    </binding>
  </netTcpBinding>
</bindings>
<services>
  <service behaviorConfiguration="serviceBehaviour" name="MyService.MyService">
    <endpoint address="MyService" binding="netTcpBinding" bindingConfiguration="netTcp" name="net.tcp" contract="MyService.IMyService" />
    <endpoint binding="mexTcpBinding" bindingConfiguration="" name="net.tcp" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8000/MyService" />
      </baseAddresses>
    </host>
  </service>
</services>

在客戶端的構造函數中:

var callback = new CallbackImplementation();
_context = new InstanceContext(callback);
_proxy = new MyServiceProxy(_context);

在建立新連接之前,我正在嘗試以下操作:

        try
        {
            if (_context != null)
            {
                _context.ReleaseServiceInstance();
                _context.Close();                    
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            if (_context != null)
            {
                _context.Abort();
            }
        }

我看到的問題是_context.Close()調用總是超時並拋出異常。 雖然我當時正在中止頻道,但這對我來說感覺不對,而且我認為這是我申請中凍結的原因。 有人知道為什么Close()調用失敗了嗎?

編輯:我之前錯過了關於我的回調實現可能相關的內容。 它看起來像這樣:

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Single, 
    UseSynchronizationContext = false, 
    IncludeExceptionDetailInFaults = true)]
public class CallbackImplementation : IServiceCallback
{
    public void SendMessage(string message)
    {
        // Do something with the message
    }
}

異常消息是“ServiceHost關閉操作在00:00:30之后超時。這可能是因為客戶端未能在所需時間內關閉會話通道。分配給此操作的時間可能是較長超時的一部分“。 沒有內在的例外。

謝謝

我沒有立即看到問題,但我經常發現在客戶端和服務器上運行跟蹤並檢查結果通常會指向我的解決方案。 將它放在.config文件(客戶端和服務器)中,確保路徑指向存在的文件夾。 運行您的應用程序,獲取失敗,然后關閉所有內容並運行SvcTraceViewer.exe以讀取結果。

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Information,ActivityTracing"
        propagateActivity="true">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add initializeData="C:\logs\TracingAndLogging-service.svclog" type="System.Diagnostics.XmlWriterTraceListener"
        name="xml" />
    </sharedListeners>
    <trace autoflush="true" />
</system.diagnostics>

你試過receiveTimeout =“無限”,看看你是否仍然收到錯誤。 您可能只是發現創建錯誤的超時不是。 您是否考慮過創建一個基本客戶端類,它可以自動保持連接活動直到物理關閉?

猜測,它可能是使用ConcurrencyMode.Single引起的死鎖。

可能發生的是服務器在處理原始請求時嘗試回調客戶端(反之亦然)。 因此服務器正在嘗試回調客戶端,但客戶端正在阻塞,因為它仍在等待來自服務器的響應。 嘿presto,僵局,最終超時。

http://msdn.microsoft.com/en-us/library/system.servicemodel.concurrencymode.aspx

問題不僅是並發性,還有綁定類型。

確保服務和回調的並發模式是朝着正確方向邁出的一步。 但是將netTcpBinding的綁定更改為wsDualHttpBinding最終解決了這個問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM