Странное поведение обратного вызова - PullRequest
0 голосов
/ 21 сентября 2010

При выполнении простых вызовов методов для службы (без параметров или ожидаемого значения) все работает просто замечательно. Однако, если я вызову другой метод для обратного вызова, я получу большую неприятную ошибку. Вот контрактные интерфейсы:

        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.

Кроме того, все каналы неисправны, и никакие попытки вернуть их не будут работать, если вы не перезапустите программу. Есть идеи, что вызвало бы это странное поведение?

Ответы [ 2 ]

0 голосов
/ 22 сентября 2010

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

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

0 голосов
/ 21 сентября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...