2010-09-21 7 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? Можете ли вы показать, как клиент вызывает услугу? Кроме того, зачем использовать обратные вызовы? Почему бы не использовать ошибки для сообщения об ошибках? –

+0

Клиент - это winform, говорящий с Сервисом. Мы говорим об IP/Radio на ПК на транспортных средствах, а обратный вызов - когда драйвер отправляет сообщение, и его нужно доставлять клиентам. Я хотел избежать опроса. – Jasonthemasonkcch

ответ

0

Это просто догадка прямо сейчас, но возвращаемый объект имеет переменную типа System.Exception, и это может быть не так легко сериализованная ...

0

Я также не понимаю, почему вы используете дуплексную связь а не основной запрос ответа.

Если у вас двусторонняя связь с двухсторонним обменом сообщениями, вы должны быть осторожны, когда вы вызываете операцию двустороннего обратного вызова из сервисной операции. По умолчанию это вызывает тупик. Вы можете пометить реализацию своей службы атрибутом ServiceBehavior и установить ConcurrencyMode в Reentrant. Это также можно установить в CallbackBehavior, но это не обязательно.

+0

В настоящее время он установлен для реентера. Вы предлагаете установить атрибут обратного вызова «IsOneWay: = True»? – Jasonthemasonkcch

Смежные вопросы