2010-09-21 8 views
0

Lorsque vous effectuez des appels de méthode simples sur un service (aucun paramètre ou valeur de retour attendue), tout fonctionne parfaitement. Cependant, si j'appelle une autre méthode sur le rappel, je reçois une grosse erreur. Voici les interfaces contrat:Comportement de rappel bizarre

 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 

Pour démarrer le service, j'appelle les éléments suivants:

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 

Je peux alors créer une référence de service, et tout fonctionne bien aussi longtemps que je suis seulement appelant la méthode "KeepAlive". Lorsque je tente d'envoyer un objet message via "ProcessGeneralMessage" le comportement devrait être que si une adresse cible n'est pas atteinte, l'utilisateur sera informé de l'erreur via la méthode de rappel "ReceiveSendFailedReport (ByVal args As Gui.Controls. SendResultsEventArgs) » la chose étrange qui se produit est que l'utilisateur est informé, mais l'appel des verrous de service et éventuellement lancer une exception:

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. 

de plus, tous les canaux sont blâmés et aucune tentative de les ramener seront travaillez à moins de redémarrer le programme. Des idées ce qui causerait ce comportement bizarre?

+0

Quel type de code est votre client? Winforms? Pouvez-vous montrer comment le client appelle le service? Aussi, pourquoi utiliser les rappels? Pourquoi ne pas utiliser les erreurs pour signaler les conditions d'erreur? –

+0

Le client est un winform qui parle à un service. Nous parlons de l'IP/Radio aux PC sur les véhicules, et le rappel est pour quand un conducteur envoie un message, et il doit être livré aux clients. Je voulais éviter les sondages. – Jasonthemasonkcch

Répondre

0

Il est juste une intuition en ce moment, mais l'objet retourné a une variable de type System.Exception, et qui ne peut pas être si facilement sérialisé ...

0

Je ne comprends pas pourquoi utilisez-vous la communication duplex et pas de réponse à la requête de base. Lorsque vous communiquez en mode duplex avec la messagerie bidirectionnelle, vous devez faire attention lorsque vous appelez une opération de rappel bidirectionnel à partir d'une opération de maintenance. Cela provoque un blocage par défaut. Vous pouvez marquer votre implémentation de service avec l'attribut ServiceBehavior et définir ConcurrencyMode sur Reentrant. Cela peut également être défini dans CallbackBehavior mais il ne devrait pas être nécessaire.

+0

Il est actuellement défini sur Réentrant. Suggérez-vous de définir l'attribut de rappel "IsOneWay: = True"? – Jasonthemasonkcch