对 skynet http stream 代码的一些疑问,希望大家指点和探讨一下,谢谢 #1982
Replies: 4 comments 20 replies
-
另外,因 http stream 的疑问查看相关代码,产生了另外一个疑问:当调用 function socket.readall(id)
local s = socket_pool[id]
assert(s)
if not s.connected then
local r = driver.readall(s.buffer, s.pool)
return r ~= "" and r
end
assert(not s.read_required)
s.read_required = true
suspend(s)
assert(s.connected == false)
return driver.readall(s.buffer, s.pool)
end -- SKYNET_SOCKET_TYPE_DATA = 1
socket_message[1] = function(id, size, data)
local s = socket_pool[id]
if s == nil then
skynet.error("socket: drop package from " .. id)
driver.drop(data, size)
return
end
local sz = driver.push(s.buffer, s.pool, data, size)
local rr = s.read_required
local rrt = type(rr)
if rrt == "number" then
-- read size
if sz >= rr then
s.read_required = nil
if sz > BUFFER_LIMIT then
pause_socket(s, sz)
end
wakeup(s)
end
else
if s.buffer_limit and sz > s.buffer_limit then
skynet.error(string.format("socket buffer overflow: fd=%d size=%d", id , sz))
driver.close(id)
return
end
if rrt == "string" then
-- read line
if driver.readline(s.buffer,nil,rr) then
s.read_required = nil
if sz > BUFFER_LIMIT then
pause_socket(s, sz)
end
wakeup(s)
end
elseif sz > BUFFER_LIMIT and not s.pause then
pause_socket(s, sz)
end
end
end |
Beta Was this translation helpful? Give feedback.
-
我觉得这里给的 interface 是个未实现的功能组,应该是依赖数量越少越好。如果可以不依赖 readall 就不应该依赖。readall 本身也是一个不太正常的功能,我认为应该回避使用。 另外 steam 既然是流处理,也不应该把整个流的数据全部读完 (all) 再处理。 |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
我想了一下,目前解决这个问题伤害最小的改法还是加一个 interface.readany ,然后让 stream api 使用它。但以后在别的模块使用 readany 应该斟酌。 这样可以最小程度影响已有代码的行为,同时解决这个指定问题。 如果想兼容再好一些,当 readany 不存在时,转发到 read 更好。 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
新项目引入 etcd 组件,watch 监听需要使用 skynet http stream,由于 wiki 上没有相关说明,所以详细看了相关代码,有两点疑问想请教一下:
stream.connected
赋值为nil
和false
的目的是什么?stream_length
和stream_read
两函数的处理似乎不太一致?stream_all
使用stream_read
进行 padding 读取,而不是使用stream._interface.readall
进行一次性读取的原因?这里的说明 #1463 (comment) 结合代码,个人理解
stream.connected = nil
时应该是表示正常连接关闭的情况,而stream.connected = false
时表示出错的情况。对于
stream._interface.read
函数,对应 http/sockethelper.lua 中sockethelper.readfunc
return 的闭包函数,连接正常关闭时,stream._interface.read()
->readbytes()
->socket.read()
会返回false, ret
,根据代码,应该会直接 error 报错,则 stream_all 最后的读取会报错。不知道我理解是否有误?response_stream
代码如下,mode == "chunked"
会使用stream_chunked
分片读取,其他情况,若有 "content-length" 头字段表明数据长度,使用stream_length(length)
读取指定长度数据,否则再根据情况不读取stream_nobody
或读取所有剩余数据stream_all
。stream_length 、stream_all 和 stream_read
代码如下:sockethelper.readfunc
代码如下:@cloudwu 不清楚云大是否有时间指点一下?
或者其他熟悉相关代码的同学,若我理解有误,也恳请指点和指正一下,谢谢!
Beta Was this translation helpful? Give feedback.
All reactions