socket: Módulo de compatibilidade automática LuaSocket/cosockets
Instalação
Se você ainda não configurou a assinatura do repositório RPM, inscreva-se. Em seguida, você pode prosseguir com os seguintes passos.
CentOS/RHEL 7 ou 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
Para usar esta biblioteca Lua com NGINX, certifique-se de que o nginx-module-lua está instalado.
Este documento descreve lua-resty-socket v1.0.0 lançado em 18 de janeiro de 2019.
Módulo de compatibilidade automática cosocket/LuaSocket para módulos lua-resty que desejam ser compatíveis com Lua simples ou com o contexto init do OpenResty.
O caso de uso para esta biblioteca é: você está desenvolvendo um módulo lua-resty que depende de cosockets, mas deseja que ele também possa ser usado no contexto init do OpenResty ou até mesmo em Lua simples. Este módulo visa sempre fornecer à sua biblioteca sockets que serão compatíveis no contexto atual, economizando tempo e esforço, e estendendo a API do LuaSocket para corresponder à dos cosockets, permitindo que você sempre escreva seu código como se estivesse em um contexto OpenResty compatível com cosockets.
Recursos
- Permite que seus módulos lua-resty usem automaticamente cosockets/LuaSocket
- Fornece proxy
sslhandshakeao usar LuaSocket, com uma dependência do LuaSec - Não fica bloqueado ao usar LuaSocket em outros contextos se carregado no
initdo ngx_lua (um erro fácil de cometer) - Memoiza métodos de socket subjacentes para desempenho
- Emite um log de aviso para seus usuários ao criar um socket usando LuaSocket enquanto está no OpenResty
Motivação
O objetivo deste módulo é fornecer uma alternativa automática ao LuaSocket quando os cosockets do [ngx_lua] não estão disponíveis. Ou seja:
- Quando não utilizado no ngx_lua
- Em contextos do ngx_lua onde os cosockets não são suportados (init, init_worker, etc...)
Ao recorrer ao LuaSocket, ele fornece shims para funções exclusivas de cosocket, como getreusedtimes, setkeepalive, etc...
É útil quando alguém está desenvolvendo um módulo/biblioteca que visa ser compatível tanto com ngx_lua quanto com Lua simples, ou em contextos do ngx_lua, como init.
Bibliotecas que o utilizam
Aqui estão alguns exemplos concretos do uso deste módulo. Você pode ver como escrevemos código como se estivéssemos constantemente em um contexto OpenResty compatível com cosocket, o que simplifica muito nosso trabalho e fornece compatibilidade com Lua simples fora da caixa.
- lua-cassandra: veja como o módulo cassandra é compatível tanto no OpenResty quanto no Lua simples, sem esforços ou caminhos de código especiais que distinguem cosockets e LuaSocket.
Nota importante
O uso do LuaSocket dentro do ngx_lua é fortemente desencorajado devido à sua natureza bloqueante. No entanto, é aceitável usá-lo no contexto init, onde o bloqueio não é considerado prejudicial.
No futuro, apenas a fase init permitirá recorrer ao LuaSocket.
Atualmente, ele suporta apenas sockets TCP.
Uso
Todas as funções disponíveis seguem o mesmo protótipo da API de cosocket, permitindo que este exemplo seja executado em qualquer contexto ngx_lua ou fora do ngx_lua completamente:
local socket = require 'resty.socket'
local sock = socket.tcp()
getmetatable(sock) == socket.luasocket_mt ---> true/false dependendo do socket subjacente
sock:settimeout(1000) ---> 1000ms traduzido para 1s se LuaSocket
sock:getreusedtimes(...) ---> 0 se LuaSocket
sock:setkeepalive(...) ---> chama close() se LuaSocket
sock:sslhandshake(...) ---> dependência do LuaSec se LuaSocket
Assim, pode-se escrever um módulo que depende de sockets TCP, como:
local socket = require 'resty.socket'
local _M = {}
function _M.new()
local sock = socket.tcp() -- semelhante a 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() -- API de cosocket
if not times then
return nil, err
elseif times == 0 then
-- tratar conexão
end
end
return _M
O usuário de tal módulo poderia usá-lo em contextos com suporte a cosocket ou na fase init do ngx_lua, com pouco esforço do desenvolvedor.
GitHub
Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório do GitHub para nginx-module-socket.