c# - Keep-Alive 出现在 Debian/Mono 的 HTTP header 中 - 而不是 Windows

标签 c# mono debian servicestack keep-alive

我的任务是在 Debian 7 上设置一个基于 ServiceStack 的 C# 应用程序。

该应用程序是使用 .NET 4.5.2 编译的,我已经在 Debian 上安装了 mono 4.4.2(使用 mono 的 Debian 存储库)。

应用程序启动正常(在它自己的用户下)。当我启动一个与该服务通信的客户端(使用 POST,在这个问题的末尾有更多相关信息)时,客户端在尝试传输它的第二个 POST(也是向服务器发送的第二条总消息)时崩溃。

如果我在传输第二条消息之前等待约 15 秒,它就会起作用。使用 Wireshark 查看时,很明显发生了什么:

Debian/Mono 上,在客户端确认最后一条 HTTP 消息(TCP“ACK”)后约 15 秒后发送一个 TCP“FIN/ACK”信号。在查看正在传输的 HTTP 包时,我能够看到两件事:

  • Keep-Alive 出现在 HTTP header 中 (Keep-Alive: timeout=15,max=100)
  • 指定的HTTPAPI不同(Mono-HTTPAPI/1.0)

我不认为 HTTPAPI 是个问题,因为如果我在两次 POST 之间等待 15 秒,我就可以很好地传输数据。由于这 15 秒的事情,我倾向于相信 Keep-Alive 是这里的罪魁祸首。

如果我在Windows/.NET 4.5.2 机器同一客户端 之间传输数据,则没有Keep-Alive 在 HTTP header 中标记,并且 HTTPAPI 读取 Microsoft-HTTPAPI/2.0。当然,我也可以发送多个 POST 而不会发生异常并且连接不会断开。

我不知道 Debian/mono 机器从哪里提取 Keep-Alive 的东西,也不知道如何更改它。在大多数 SO 问题上,人们要么被要求更改他们的 IIS 设置(这是自托管的,因此在 Linux 上不起作用,呃),要么在 HttpWebRequest 上设置它(我无权访问/isn'在那里。)。

所以,我的问题是:如何删除该超时?

啊,差点忘了:

客户端 站点 XmlServiceClient.Post(SomeObjectOfClass); 用于传输消息。在 15 秒内执行两次会导致出现 ObjectDisposedException,由不存在/未处置的 Socket 触发。

服务器站点WebServiceHost.Init().Start("http://*:1234/");用于启动服务。包含一堆 Any 方法的类似乎可以处理创建响应。

最佳答案

看起来服务器在发送响应后关闭了连接(忽略 keep-alive header ),而客户端仍然认为连接已打开并尝试向关闭的套接字发送消息。

要解决此问题,您可以按照推荐的方式在linux上使用Nginx+HyperFastCGI安装ServiceStack。文档可用here它是为 Ubuntu linux 编写的,但对于 Debian 应该没有太大的不同。

另一种选择:您可以简单地安装 nginx 并将其用作 reverse proxy到您的 WebServiceHost。在这种情况下,您可以在服务器端使用保持事件设置。

  • 您可以使用 keepalive_disable 指令(参见 nginx docs)完全禁用客户端代理的保持事件状态

  • 使用 keepalive-timeout 指令限制保持事件超时(参见 nginx docs )

  • 使用 proxy_set_header Connection ""; 指令将其发送到 WebServiceHost 时清除 Connection header (参见 nginx docs )

此外,为了确定问题的原因,如果您提供小型可重现样本,它会显示它并告诉您的客户端在哪个操作系统上运行,这将是很好的选择。

关于c# - Keep-Alive 出现在 Debian/Mono 的 HTTP header 中 - 而不是 Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39293474/

相关文章:

c# - 编译特定版本的 DotNetOpenAuth 并进行小改动,签名问题

c# - 如何避免 C# Azure API 在上传大型 Blob 时耗尽内存?

macos - OS X 上的 Monodevelop 并显示 UTF-8

c# - TeeChart for Mono Android 无法编译

regex - sed -E 和 sed -e 有什么区别

c# - 当我使用 MVVM 模型时,如何在 WPF 中使用 WndProc?

c# - Internet 上的客户端-服务器应用程序消息交换

java - 简单的跨平台 GUI 应用程序

linux - 从命令行保存某个字符串

elasticsearch - Elasticsearch path.repo阻止服务启动