Lua HTTP套接字超时

11
LuaSocket的HTTP模块文档表示可以在HTTP连接上设置超时时间: 以下常量可用于控制HTTP模块的默认行为: PORT:用于连接的默认端口; PROXY:用于连接的默认代理; TIMEOUT:设置所有I/O操作的超时时间; USERAGENT:报告给服务器的默认用户代理。 http://w3.impa.br/~diego/software/luasocket/http.htm 我该如何在lua脚本中设置这些常量?

1
将您的解决方案作为答案并接受它,这样问题就会得到解决。 - Alexander Gladysh
我尝试了,但在第一篇帖子发布后,我必须等待8个小时才能回答自己的问题。我会在今晚(欧洲中部时间)回答。 - ripat
现在您已经拥有10个声望点,该限制应该已经消失了。 - BMitch
不行。我仍然看到同样的提示:新用户需要等待8小时才能回答自己的问题。请使用评论或编辑您的问题。 - ripat
2个回答

15

比我想象的要容易。只需

local mysocket = require("socket.http")
mysocket.TIMEOUT = 5

2
这是否具有“副作用”,即在执行 require 的文件之外更改 http socket 配置?(例如,在同一程序但在另一个执行其自己的 http.socket require 的文件中的代码) - josinalvo
1
@josinalvo:是的,程序中所有文件在 package.loaded 下共享它们的公共模块实例。参见 我的回答 以了解如何避免副作用。 - Stuart P. Bentley

13
您可以这样设置单个请求的超时时间,而不是整个HTTP模块:
local socket = require "socket"
local http = require "socket.http"
response = http.request{url=URL, create=function()
  local req_sock = socket.tcp()
  req_sock:settimeout(5)
  return req_sock
end}

请注意,:settimeout 的默认行为以及全局设置如 http.TIMEOUT,会为请求中的任何单个操作设置一个时间限制 - 换句话说,这是在没有任何活动的情况下操作可以持续的时间。如果您希望为操作设置一个总的上限 - 无论有没有活动,整个请求不能超过一定时间 - 您应该将第二个参数作为 't' 的模式参数传递给 :settimeout,例如:
local socket = require "socket"
local http = require "socket.http"
response = http.request{url=URL, create=function()
  local req_sock = socket.tcp()
  -- note the second parameter here
  req_sock:settimeout(5, 't')
  return req_sock
end}

作为一个例子来说明这两种模式之间的区别,想象一下,在您发出请求后,服务器每秒钟响应一次响应块,总共需要七秒钟才能完成。使用req_sock:settimeout(5, 'b')(或只是req_sock:settimeout(5))设置为5秒的阻塞超时,这个请求将顺利进行,因为没有底层I/O操作超过了五秒钟:然而,使用req_sock:settimeout(5, 't')设置为五秒钟的总体超时,请求将在五秒钟后失败
当然,对于这两个持续时间都设置限制可能是有意义的,既有短暂的不活动超时,也有更长的总体超时。因此,根据文档,您可以进行两个单独的调用来指定两者
local socket = require "socket"
local http = require "socket.http"
response = http.request{url=URL, create=function()
  local req_sock = socket.tcp()
  req_sock:settimeout(5, 'b')
  req_sock:settimeout(30, 't')
  return req_sock
end}

我不确定我理解这个。使用我找到的解决方案(现在下面发布),我真的改变了所有新HTTP套接字的超时吗?如果是这样,连接成功后我可以将其值重置为默认的60秒。你能解释一下你的片段,特别是create = function()部分吗? - ripat
我刚刚做了一些测试,实际上,当我使用 mysocket.TIMEOUT 修改超时时间后,除非再次更改,否则它将为所有新创建的 HTTP 套接字保持该值。按照你的建议,难道不会创建两个套接字吗?一个是 HTTP 的,另一个是 TCP 的吗? - ripat
1
@ripat 请求中的 create 参数指定了用于创建 TCP 套接字以执行 HTTP 请求(HTTP应用层通过TCP传输层)。如果您没有指定创建函数,http.request 将默认使用普通的 tcp() 调用(请参阅手册)。 - Stuart P. Bentley
1
哦,我明白了。虽然在脚本的整个模块中设置默认值通常不是问题,但你的解决方案可以更好地控制HTTP套接字。谢谢Stuart。 - ripat
第二行的 require "socket.tcp" 和第四行的 local socket = tcp()无效的。应该删除第二行并将第四行改为 local socket = socket.tcp() - user600838
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接