2010-09-21 98 views
0

當對一個服務進行簡單的方法調用時(沒有參數或期望的返回值),一切工作都很好。但是,如果我在回調中調用另一種方法,則會出現一個嚴重的錯誤。這裏有合同接口:奇怪的回調行爲

 Namespace Net.Wcf.Contracts 
    #Region "Message Responder Wcf Contracts" 
     ''' <summary> 
     ''' Interface defining the methods that the Responder Inbox must implement. 
     ''' </summary> 
     <ServiceContract(CallbackContract:=GetType(IRccUserInterfaceCallback), SessionMode:=SessionMode.Required)> _ 
     Public Interface IRccUserInterface 
      <OperationContract()> Function IsReady() As Boolean 
      <OperationContract()> Function Login(ByVal UserInfo As Collections.UserInterface.RccUserInfo) As Boolean 
      <OperationContract(IsOneWay:=True)> Sub LogOut(ByVal UserInfo As Collections.UserInterface.RccUserInfo) 
      <OperationContract()> Sub AudioConnecting(ByVal Key As Integer, ByVal MaxTime As Integer, ByVal Priority As MessagePriority, ByVal User As String) 
      <OperationContract()> Sub AudioDisconnecting(ByVal Key As Integer, ByVal UserName As String) 
      <OperationContract()> Sub ProcessTaitSimpleMessage(ByVal Msg As Messages.Tait.TaitSimpleMessage) 
      <OperationContract()> Sub ProcessGeneralMessage(ByVal Msg As Messages.General.Message) 
      <OperationContract()> Sub KeepAlive(ByVal RccAddress As Address) 
      <OperationContract()> Sub SetCurrentAudioState(ByVal UserName As String, ByVal state As RccAudioState) 
      <OperationContract()> Sub UpdateQueueItemStatus(ByVal args As RccQueueStateChangeArgs) 
      <OperationContract()> Sub RadioDiverted(ByVal UserName As String, ByVal AddressDivertedTo As Address) 
      <OperationContract()> Sub RadioDivertCancelled(ByVal UserName As String) 
     End Interface 
    ''' <summary> 
    ''' Methods available to the Cad Server to inform an Rcc Station that it is Online or Offline. 
    ''' </summary> 
    ''' <remarks></remarks> 
    Public Interface IRccUserInterfaceCallback 
     <OperationContract(IsOneWay:=True)> Sub CadServerOffline() 
     <OperationContract(IsOneWay:=True)> Sub CadServerOnline() 
     <OperationContract()> Sub ReceiveGeneralMessage(ByVal Msg As Messages.General.Message) 
     <OperationContract()> Sub ReceiveSendFailedReport(ByVal args As Gui.Controls.SendResultsEventArgs) 
     <OperationContract()> Sub VehicleStateUpdate(ByVal args As Collections.MdcStateChangeEventArgs) 
     <OperationContract()> Sub UpdateQueueItemStatusCallback(ByVal args As RccQueueStateChangeArgs) 
    End Interface 
#End Region 
End Namespace 

要啓動服務,我把以下內容:

Public Sub StartServiceHost() 
      'Publish the Wcf Service endpoint. 
      Try 
       shRccUserInterface = New ServiceHost(Me._RccInboxService) 
       AddHandler shRccUserInterface.Faulted, AddressOf OnChannelFaulted 
       AddHandler shRccUserInterface.Closed, AddressOf OnChannelClosed 
       AddHandler shRccUserInterface.Opened, AddressOf OnChannelOpened 
       AddHandler shRccUserInterface.Opening, AddressOf OnChannelOpening 
       AddHandler shRccUserInterface.UnknownMessageReceived, AddressOf OnUnknownMessageReceived 

       Me.bndRccUserInterface = New NetTcpBinding("ReliableDuplexBinding") 
       Dim bndMex As ServiceModel.Channels.Binding = Description.MetadataExchangeBindings.CreateMexHttpBinding() 
       Dim ep As Description.ServiceEndpoint 
       With shRccUserInterface 
        ep = .AddServiceEndpoint(GetType(Cad.Net.Wcf.Contracts.IRccUserInterface), bndRccUserInterface, "net.tcp://localhost:55555/RccInterface") 
        .AddServiceEndpoint(GetType(Description.IMetadataExchange), bndMex, String.Empty) 
        RaiseEvent ShowUserMessageEvent(Me, "Opening Endpoint: " & ep.Address.ToString, UtaCommon.Interfaces.StatusListEntryType.Information) 
        .Open() 
       End With 
       Me.blnServiceHostOpen = True 
       RaiseEvent ServiceHostOpenEvent(Me) 
      Catch exWcf As Exception 
       log.Write_Error("RccGuiComm", "StartServiceHost()", exWcf) 
       RaiseEvent SendUtaEmailEvent("Wcf Problem", exWcf.ToString, System.Net.Mail.MailPriority.High) 
      End Try 
     End Sub 

我可以再創建一個服務引用,並一切正常,只要我只有我調用「KeepAlive」方法。當我嘗試通過「ProcessGeneralMessage」發送消息對象時,行爲應該是,如果未達到目標地址,則會通過回調方法「ReceiveSendFailedReport(ByVal args As Gui.Controls)」通知用戶該錯誤。 SendResultsEventArgs)」出現這種情況的奇怪的是,通知用戶,但是從服務門鎖呼叫,最終將拋出一個異常:

This request operation sent to http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous did not receive a reply within the configured timeout (00:00:14.7815986). 
The time allotted to this operation may have been a portion of a longer timeout. 
This may be because the service is still processing the operation or because the service was unable to send a reply message. 
Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client. 

此外,所有通道故障,並沒有試圖把他們帶回來會除非重新啓動程序才能工作。任何想法會導致這種奇怪的行爲?

+0

你的客戶端是什麼類型的代碼?的WinForms?你能展示客戶如何調用服務?另外,爲什麼使用回調?爲什麼不使用故障報告錯誤狀況? – 2010-09-21 19:48:46

+0

客戶端是與服務交談的winform。我們正在通過IP /無線電與PC上的交通工具進行交談,回調是當駕駛員發送消息時,它需要交付給客戶。我想避免投票。 – Jasonthemasonkcch 2010-09-21 21:14:23

回答

0

這只是一種預感權利,但返回的對象有一個System.Exception的類型變量,而這可能不是那麼容易連載...

0

我也想不明白爲什麼要使用全雙工通信而不是基本的請求響應。

當您使用雙向消息進行雙工通信時,從服務操作調用雙向回調操作時必須小心。這會導致默認情況下發生死鎖。您可以使用ServiceBehavior屬性標記您的服務實現,並將ConcurrencyMode設置爲Reentrant。這也可以在CallbackBehavior中設置,但不應該需要。

+0

它目前設置爲Reentrant。你是否建議設置回調屬性「IsOneWay:= True」? – Jasonthemasonkcch 2010-09-21 21:15:30