stream-lua-nginx-module icon indicating copy to clipboard operation
stream-lua-nginx-module copied to clipboard

我在preread_by_lua_file 阶段进行 sock 的 peek 操作,我想优雅的获取缓冲区的所有数据该怎么实现

Open wjsw1781 opened this issue 9 months ago • 2 comments

local peek_num=1
  while true do
      local chunk, err =sock:peek(peek_num)
      ngx.log(ngx.ERR,"peek ..." ,chunk, ' == ',peek_num ,err )
      -- ngx.log(ngx.ERR,"peek ..." ,#chunk, ' == ',peek_num ,err,bytes_to_hex(chunk) )
      peek_num=peek_num+1
  end
 ngx.log(ngx.ERR,"退出循环 ..."  )

这样会卡死在最后一个缓冲区的下一个

但是当我添加了 preread_timeout 1s;


stream {
    preread_timeout 1s;

    server {
        listen 0.0.0.0:3889;  #监听本机地址和端口,当使用keeplived的情况下使用keeplived VIP
        preread_by_lua_file /root/socks_ss_gfw_ss_socks/nginx_redis_lua/test_socks.lua;
        proxy_pass backend; #
    }
    upstream backend{  
        server 127.0.0.2:1101;  # 爱写啥写啥  反正下面的代码也给你改了
        balancer_by_lua_file /root/socks_ss_gfw_ss_socks/nginx_redis_lua/balancer_by_lua_file.lua;
    } 

}
此时

        local chunk, err =pcall(function() return sock:peek(peek_num) end) 


这里的 pcall 还是捕获不到这种错误

我不信想使用 recive 这种消耗配合字节逐个解析的方法 可能还得配合超时来获取字节总是很浪费性能 难道就没有一个方法可以从缓冲区获取一次 tcp 交流的所有数据的方法?

wjsw1781 avatar Feb 27 '25 02:02 wjsw1781

local peek_num=1
  while true do
      local chunk, err =sock:peek(peek_num)
      ngx.log(ngx.ERR,"peek ..." ,chunk, ' == ',peek_num ,err )
      -- ngx.log(ngx.ERR,"peek ..." ,#chunk, ' == ',peek_num ,err,bytes_to_hex(chunk) )
      peek_num=peek_num+1
  end
 ngx.log(ngx.ERR,"退出循环 ..."  )

这样会卡死在最后一个缓冲区的下一个

但是当我添加了 preread_timeout 1s;


stream {
    preread_timeout 1s;

    server {
        listen 0.0.0.0:3889;  #监听本机地址和端口,当使用keeplived的情况下使用keeplived VIP
        preread_by_lua_file /root/socks_ss_gfw_ss_socks/nginx_redis_lua/test_socks.lua;
        proxy_pass backend; #
    }
    upstream backend{  
        server 127.0.0.2:1101;  # 爱写啥写啥  反正下面的代码也给你改了
        balancer_by_lua_file /root/socks_ss_gfw_ss_socks/nginx_redis_lua/balancer_by_lua_file.lua;
    } 

}
此时

        local chunk, err =pcall(function() return sock:peek(peek_num) end) 

这里的 pcall 还是捕获不到这种错误

我不信想使用 recive 这种消耗配合字节逐个解析的方法 可能还得配合超时来获取字节总是很浪费性能 难道就没有一个方法可以从缓冲区获取一次 tcp 交流的所有数据的方法?

"所有"这个概念不是很清晰,read函数不知道你缓冲区有多少数据,如果你想实现的是读多少处理多少最好的办法就是在write_filter_module的前面加一个c模块

aifeiasdf avatar Mar 24 '25 05:03 aifeiasdf

I've encountered the same issue as you. After looking through online resources, I found that the njs module can be used to detecte HTTP request headers on stream module. And it also solved my issue.

NJS-example

ZigHuang avatar Mar 26 '25 06:03 ZigHuang