gpt4 book ai didi

c# - 检测 WCF 双工契约(Contract)中的客户端死亡

转载 作者:IT王子 更新时间:2023-10-29 04:09:44 27 4
gpt4 key购买 nike

我正在尝试构建一个 SOA,其中客户端可以在服务器上执行长时间运行的查询,并且服务器使用回调进行响应。

我希望能够检测客户端是否断开连接(通过用户启动的关闭、未处理的异常或网络连接丢失),以便服务器可以选择取消昂贵的请求。

我正在测试各种失败案例,但我似乎无法触发某些事件处理程序。

测试失败案例:请求后杀死客户端进程。使用像 CurrPorts 这样的程序来关闭 TCP 连接。

测试代码:

using System;
using System.ServiceModel;
using System.Threading;

namespace WCFICommunicationObjectExperiments
{
class Program
{
static void Main(string[] args)
{
var binding = new NetTcpBinding(SecurityMode.None);

var serviceHost = new ServiceHost(typeof (Server));
serviceHost.AddServiceEndpoint(typeof (IServer), binding, "net.tcp://localhost:5000/Server");
serviceHost.Open();
Console.WriteLine("Host is running, press <ENTER> to exit.");
Console.ReadLine();
}

}

[ServiceContract(CallbackContract = typeof(IClient))]
public interface IServer
{
[OperationContract]
void StartProcessing(string Query);
}

public interface IClient
{
[OperationContract]
void RecieveResults(string Results);
}

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Server : IServer
{

public void StartProcessing(string Query)
{
Thread.Sleep(5000);

//Callback Channel
var clientCallback = OperationContext.Current.GetCallbackChannel<IClient>();
var clientCallbackCommunicationObject = ((ICommunicationObject) clientCallback);
EventHandler faultedHandlerCallback = (o, s) => Console.WriteLine("Client Channel Faulted.");
EventHandler closedHandlerCallback = (o, s) => Console.WriteLine("Client Channel Closed.");
clientCallbackCommunicationObject.Faulted += faultedHandlerCallback;
clientCallbackCommunicationObject.Closed += closedHandlerCallback;

//Request Channel
var requestChannel = OperationContext.Current.Channel;
EventHandler faultedHandlerRequest = (o, s) => Console.WriteLine("Request Channel Faulted.");
EventHandler closedHandlerRequest = (o, s) => Console.WriteLine("Request Channel Closed.");
requestChannel.Faulted += faultedHandlerRequest;
requestChannel.Closed += closedHandlerRequest;

try
{
clientCallback.RecieveResults("42.");
}
catch (CommunicationObjectAbortedException ex)
{
Console.WriteLine("Client Aborted the connection");
}
catch (CommunicationObjectFaultedException ex)
{
Console.WriteLine("Client Died.");
}
clientCallbackCommunicationObject.Faulted -= faultedHandlerCallback;
clientCallbackCommunicationObject.Faulted -= closedHandlerCallback;
requestChannel.Faulted -= faultedHandlerRequest;
requestChannel.Closed -= closedHandlerRequest;
}
}

public class ClientToTestStates : IClient
{
private IServer m_Server;

private readonly ManualResetEvent m_ReceivedEvent = new ManualResetEvent(false);
private readonly ManualResetEvent m_ChannelFaulted = new ManualResetEvent(false);
private readonly ManualResetEvent m_ChannelClosed = new ManualResetEvent(false);

public ClientToTestStates()
{
var binding = new NetTcpBinding(SecurityMode.None);
var channelFactory = new DuplexChannelFactory<IServer>(this, binding, new EndpointAddress("net.tcp://localhost:5000/Server"));
m_Server = channelFactory.CreateChannel();
((ICommunicationObject)m_Server).Open();
((ICommunicationObject)m_Server).Faulted += ChannelFaulted;
((ICommunicationObject)m_Server).Closed += ChannelClosed;

m_Server.StartProcessing("What is the answer?");

WaitHandle.WaitAny(new WaitHandle[] {m_ReceivedEvent, m_ChannelFaulted, m_ChannelClosed});
}

void ChannelFaulted(object sender, EventArgs e)
{
m_ChannelFaulted.Set();
Console.WriteLine("Channel Faulted.");
}

void ChannelClosed(object sender, EventArgs e)
{
m_ChannelClosed.Set();
Console.WriteLine("Channel Closed.");
}


public void RecieveResults(string results)
{
m_ReceivedEvent.Set();
Console.WriteLine("Recieved Results {0}", results);
}
}
}

处理这类失败案例的最佳做法是什么?我希望能够使用底层的 tcp 连接来检测其中的一些东西。

最佳答案

在他的“Programming WCF Services”一书中,Juval Lowy 解释说 WCF 不提供管理服务回调的机制,这必须由服务和客户端显式管理。如果服务尝试调用已在客户端关闭的回调,则会在服务 channel 上抛出 ObjectDisposedException。

他建议在服务契约中添加 Connect 和 Disconnect 方法 - 因为在调用这些方法时必须向服务提供回调,服务可以管理客户端回调。然后由客户端确保它在不再希望从服务接收回调时调用 Disconnect,并且服务必须在调用客户端回调时处理任何异常。

关于c# - 检测 WCF 双工契约(Contract)中的客户端死亡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1427926/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com