I have a WCF self-hosted service with a net.tcp DuplexChannel. On the server I run the following to disconnect a client:
((ICommunicationObject)client.CallbackChan开发者_如何转开发nel).Close();
This works fine but how do I detect on the client that it has been disconnected?
Ive hooked up to Closed and Faulted-events on both the InstanceContext of the callback and the channel to the server:
InstanceContext callback = new InstanceContext(callbackImp);
callback.Closed += new EventHandler(callback_Closed);
and
((ICommunicationObject)Channel).Closed += new EventHandler(Channel_Closed);
But nothing works. I never get notified. The workaround Im using now is to have a method in the callback that triggers a disconnect from the client-side instead. But I rather not do it this way. I especially dont want to let the server wait for a user to disconnect.
EDIT
I just realized that when disconnecting from client-side I run a method in the service-contract which is marked with IsTerminating = true:
[OperationContract(IsTerminating = true)]
void Disconnect();
I figured it would be the same on the callback-contract then? I tried adding the same method to my callback and it did terminate the callback-channel from the server point of view but I still didnt got notified on the client-side...weird
EDIT
I found out some more info about this:
When the server aborts the callback channel, a fault travels back to the client, the client faults and we get the Faulted event on the client.
When the server closes the callback channel, the session is still open until the client issues the close.
Once the client closes the channel you'll see the Closed event.
According to this statement the Close-event is not triggered mearly by closing the callbackchannel from the server, the client has to close it as well. So I could run Close on the client in the terminating Disconnect-method of the callback. Or I could use the Abort-method on the callback server-side and skip using a Disconnect-method on the callback. I dont know which one I preffer honestly. Hmmmm.
EDIT
I went with the Abort-approach. It seemed like the most logical method and it works really well. The client gets notified with the Faulted-event on the callback-instancecontext. Nice.
I went with the Abort-approach. It seemed like the most logical method and it works really well. The client gets notified with the Faulted-event on the callback-instancecontext.
You can simply do a callback just before closing the callback channel telling the client you're closing the channel.
So just before this line of code:
((ICommunicationObject)client.CallbackChannel).Close();
精彩评论