跳转至

socket: 自动 LuaSocket/cosockets 兼容模块

安装

如果您尚未设置 RPM 仓库订阅,请 注册。然后您可以继续以下步骤。

CentOS/RHEL 7 或 Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-socket

CentOS/RHEL 8+、Fedora Linux、Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-socket

要在 NGINX 中使用此 Lua 库,请确保已安装 nginx-module-lua

本文档描述了 lua-resty-socket v1.0.0,于 2019 年 1 月 18 日发布。


这是一个用于 lua-resty 模块的 cosocket/LuaSocket 自动兼容模块,旨在与普通 Lua 或 OpenResty 的 init 上下文兼容。

此库的使用场景是:您正在开发一个依赖于 cosockets 的 lua-resty 模块,但您希望它也能在 OpenResty 的 init 上下文中使用,甚至在普通 Lua 中使用。该模块旨在始终为您的库提供与当前上下文兼容的套接字,节省您的时间和精力,并扩展 LuaSocket 的 API 以匹配 cosockets,从而允许您始终像在 cosocket 兼容的 OpenResty 上下文中一样编写代码。

特性

  • 允许您的 lua-resty 模块自动使用 cosockets/LuaSocket
  • 在使用 LuaSocket 时提供 sslhandshake 代理,依赖于 LuaSec
  • 如果在 ngx_lua init 中加载,则不会阻止在进一步上下文中使用 LuaSocket(这是一个容易犯的错误)
  • 为性能缓存底层套接字方法
  • 当在 OpenResty 中使用 LuaSocket 生成套接字时,为您的用户输出警告日志

动机

该模块的目的是在 [ngx_lua] 的 cosockets 不可用时提供自动回退到 LuaSocket。即: - 当不在 ngx_lua 中使用时 - 在 ngx_lua 上下文中不支持 cosockets 的情况下(initinit_worker 等)

当回退到 LuaSocket 时,它为仅 cosocket 函数提供了适配器,例如 getreusedtimessetkeepalive 等。

当开发旨在与 ngx_lua 普通 Lua 兼容的模块/库, 在 ngx_lua 上下文中(如 init)时,这非常方便。

使用它的库

以下是此模块的一些具体使用示例。您可以看到我们只需编写代码,就像我们始终处于一个 cosocket 兼容的 OpenResty 上下文中,这大大简化了我们的工作,并提供了开箱即用的普通 Lua 兼容性。

  • lua-cassandra:查看 cassandra 模块如何在 OpenResty 和普通 Lua 中兼容,而无需努力或特殊代码路径来区分 cosockets 和 LuaSocket。

重要说明

由于 LuaSocket 的阻塞特性,非常强烈不建议在 ngx_lua 中使用它。然而,在 init 上下文中使用它是可以的,因为阻塞不会被认为是有害的。

未来,只有 init 阶段将允许回退到 LuaSocket。

它目前仅支持 TCP 套接字。

使用

所有可用的函数都遵循与 cosocket API 相同的原型,允许此示例在任何 ngx_lua 上下文中或完全在 ngx_lua 外部运行:

local socket = require 'resty.socket'
local sock = socket.tcp()

getmetatable(sock) == socket.luasocket_mt ---> true/false 取决于底层套接字

sock:settimeout(1000) ---> 1000ms 如果是 LuaSocket 则转换为 1s

sock:getreusedtimes(...) ---> 如果是 LuaSocket 则为 0

sock:setkeepalive(...) ---> 如果是 LuaSocket 则调用 close()

sock:sslhandshake(...) ---> LuaSec 依赖如果是 LuaSocket

因此,可以编写一个依赖于 TCP 套接字的模块,例如:

local socket = require 'resty.socket'

local _M = {}

function _M.new()
  local sock = socket.tcp() -- 类似于 ngx.socket.tcp()

  return setmetatable({
    sock = sock
  }, {__index = _M})
end

function _M:connect(host, port)
  local ok, err = self.sock:connect(host, port)
  if not ok then
    return nil, err
  end

  local times, err = self.sock:getreusedtimes() -- cosocket API
  if not times then
    return nil, err
  elseif times == 0 then
    -- 处理连接
  end
end

return _M

这样的模块用户可以在支持 cosocket 的上下文中使用它,或在 ngx_lua 的 init 阶段中使用,开发者几乎不需要付出额外的努力。

GitHub

您可以在 nginx-module-socket 的 GitHub 仓库 中找到此模块的其他配置提示和文档。