gpt4 book ai didi

c# - WCF服务如何检测客户端断开连接

转载 作者:行者123 更新时间:2023-12-03 08:50:06 25 4
gpt4 key购买 nike

我有以下完整的程序(可以复制粘贴构建并运行。您可能需要添加一些引用)。该程序的目标是让服务检测(例如,接收某种形式的 SocketExceptionIOException 或通过某些事件处理在代码中尝试)连接的客户端(从 Web 浏览器测试/测试)具有在响应完全传递之前断开连接(参见方法 return 中的 Talk(string animal) 语句)。为了重现该问题,有一个可配置的参数(参见 new AnimalTalkService(3)),它指示服务响应给定请求需要多长时间。在此时间范围内,我可以关闭浏览器以引发客户端断开事件(参见类 ClientDisconnected() 中的方法 ClientConnectionTracker )。我无法在服务的实现中抛出任何异常或获取 ClosedFaulted触发的事件。有人会知道如何去(实现)获得预期的效果吗?

// Code:

using System;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using System.Threading;

namespace TestClientDisconnect
{
class ClientConnectionTracker : IChannelInitializer
{
public void Initialize(IClientChannel channel)
{
channel.Closed += ClientDisconnected;
channel.Faulted += ClientDisconnected;
}

private void ClientDisconnected(object sender, EventArgs e)
{
Console.WriteLine("Client Disconnected");
throw new NotImplementedException();
}
}

class ClientConnectionTrackerEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.ChannelDispatcher.ChannelInitializers.Add(new ClientConnectionTracker());
}

public void Validate(ServiceEndpoint endpoint)
{
}
}

[ServiceContract]
interface IAnimalTalkService
{
[OperationContract]
[WebInvoke(UriTemplate = "/{animal}", Method = "GET")]
string Talk(string animal);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class AnimalTalkService : IAnimalTalkService
{
private int delayInSeconds;

public AnimalTalkService(int delayInSeconds = 0)
{
this.delayInSeconds = delayInSeconds;
}

public string Talk(string animal)
{
Console.WriteLine("Creating sentence for animal {0} ...", animal);
if (delayInSeconds > 0)
{
// Simulate heavy duty work:
Thread.Sleep(1000 * delayInSeconds);
}

switch(animal.ToLower())
{
case "sheep":
return "baa";
case "dog":
return "woof";
case "cat":
return "miao";
default:
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
return null;
}
}
}

class Program
{
static void Main(string[] args)
{
AnimalTalkService serviceInstance = new AnimalTalkService(3);
Uri address = new Uri("http://127.0.0.1:1234/");
WebServiceHost host = new WebServiceHost(serviceInstance, address);
WebHttpBinding binding = new WebHttpBinding();
ServiceEndpoint endPoint = host.AddServiceEndpoint(typeof(IAnimalTalkService), binding, "");
endPoint.EndpointBehaviors.Add(new WebHttpBehavior() { DefaultOutgoingResponseFormat = WebMessageFormat.Json });
endPoint.EndpointBehaviors.Add(new ClientConnectionTrackerEndpointBehavior());
host.Open();

Console.WriteLine("Service is running at {0}. Press Enter key to exit", host.BaseAddresses[0]);
Console.ReadLine();
}
}
}

提前致谢。

最佳答案

“断开连接”这个词意味着一个 session ,不是吗?

在我看来,最好的方法是拥有使用显式 session id 显式创建和终止 session 的方法(这里我使用了任意类型):

[ServiceContract]
public interface IWebService
{
[OperationContract]
SessionId BeginNewSession();
[OperationContract]
void DoSomething(SessionId id, ...);
[OperationContract]
void EndSession(SessionId id);
}

对于不支持传输级 session 的 HTTP 协议(protocol),这当然是推荐的。

在这种情况下,您可以编写另一个类,它将管理尚未关闭的过时 session 。

如果您使用支持传输级 session 的绑定(bind),还有另一个选项 - 设置 session 绑定(bind)服务实例管理(并使用相应的绑定(bind)),实现 IDisposable服务类中的接口(interface),并将相关代码放入 Dispose()方法:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class TheService : IService, IDisposable
{
...
public void Dispose()
{
// code of session termination
...
}
}

最后,您可以通过使用 [OperationContract(IsTerminating = true)] 标记显式 session 终止方法来组合这两个选项。属性:
[ServiceContract(..., SessionMode=SessionMode.Required)]
public interface IService
{
[OperationContract(IsTerminating = true)]
void Close();
...
}

关于c# - WCF服务如何检测客户端断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43450271/

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