Hello!
2015-12-30 17:06 GMT-08:00 黄川:
> 刚遇到一个关于receiveuntil还有iterator的问题,我有一个简单的coroutine,其不断通过cosocket从upstream读json数据,upstream用python
> sendall在送数据,当json数据比较长的时侯,receiveutil的iterator会把消息分成几个部分读出来。
> 比如: upstream 发送conn.sendall(A+delimiter),receiveutil iterator会读到A1,A2
> (A1+A2=A)
>
> 两个问题:
> -这是expected的行为吗?因为我以为receiveutil会等到给定的delimitor才返回,如果这个分段是expected的行为,我就会专门写个循环去等delimiter;
> -最长消息的长度是可以设定的吗?还是固定的?
你这里的用法不会有长度限制。我刚在我本地测试了一个 10MB 的例子,中间并没有发生截断。考虑下面这个最小化的完整示例:
server {
listen 8080;
server_tokens off;
location = /t {
content_by_lua_block {
local sock = ngx.socket.tcp()
local ok, err = sock:connect("127.0.0.1", 8080)
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected: ", ok)
local req = "GET /foo HTTP/1.0\r\nHost:
localhost\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send request: ", err)
return
end
ngx.say("request sent: ", bytes)
local readline = sock:receiveuntil("\r\n")
local line, err, part
for i = 1, 7 do
line, err, part = readline()
if line then
ngx.say("read: ", line)
else
ngx.say("failed to read a line: ", err, " [", part, "]")
end
end
ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
}
}
location = /foo {
content_by_lua_block {
ngx.header["Foo"] = string.rep("a", 1024 * 1024 * 10) .. "b"
ngx.say("foo")
}
more_clear_headers Date;
}
}
你可以在你本地测试一下。
你 100% 确定你的 JSON 数据里面没有出现你所选取的终结标记?
如果你仍然觉得是 ngx_lua 模块的问题,请提供一个类似上面那样的最小化的完整示例,以便我们大家可以很方便地在本地运行和测试。
多谢!
Best regards,
-agentzh