对 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.
-
新项目引入 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