简体   繁体   中英

handle service shutdown in WCF duplex session hosted in windows service

I have a Windows service hosting a WCF service that broadcasts information to several clients. I would like to gracefully handle a service shutdown from the client, ie detect that the service has dissapeared or wants to close, pop up a message and close the app. Currently if I shut down the service at the close line I get the following.

"The ServiceHost close operation timed out after 00:00:09.9910000. This could be because a client failed to close a sessionful channel within the required time. "

QUESTION: How do I detect the close request and shut the client down?

After the service closes on the client I get "Socket Exception ocurred An existing connection was forcibly closed by the remote host"

here is the close code.

If Not (_LivePricingHost Is Nothing) Then
    _LivePricingHost.Close()
    _LivePricingHost = Nothing
End If

Here is the class I use to set up the duplex sessions, I have removed the boilerplate dispose code and the events I am raising up to the client.

Imports System.ServiceModel

Public Class NotificationCallback
    ' Implements LivePricingService.IMessageCallback
    Implements IDisposable

    Private _ns As LivePricingService.MessageClient

    Public Sub New()
        Dim context = New InstanceContext(Me)

        _ns = New LivePricingService.MessageClient(context)
        _ns.SubscribeForBroadcast()
        '    _ns.AddMessage("PING")
    End Sub

 #End Region

End Class

The solution is to add an "Unsubscribe" method to the callback interface. Then the client can unsubscribe. So when the service is stopping it asks the clients to disconnect.

   Protected Overrides Sub OnStop()
        pollTimer.Stop()
        _LivePricingWCFService.UnsubscribeAll()
        If Not (_LivePricingHost Is Nothing) Then
            _LivePricingHost.Close()
            _LivePricingHost = Nothing
        End If
    End Sub

On the WCF service

   Public Sub UnsubscribeAll()
        Try
            RemoveClosedSubscribers()

            For Each callback As IMessageCallback In _subscribers
                If DirectCast(callback, ICommunicationObject).State = CommunicationState.Opened Then
                    callback.ShutDown() 'request that the client disconnect
                    _subscribers.Remove(callback)
                End If
            Next
        Catch ex As Exception
            Logging.Logger.LogMessage(ex:=)
        End Try
    End Sub

and on the client

Public Sub ShutDown() Implements LivePricingService.IMessageCallback.ShutDown
    _ns.Close()
    Globals.LastException = New Exception("The Live Pricing Serice has shut down.")

End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM