Saltar a contenido

socket: Módulo de compatibilidad automática de LuaSocket/cosockets

Instalación

Si no has configurado la suscripción al repositorio RPM, regístrate. Luego puedes proceder con los siguientes pasos.

CentOS/RHEL 7 o 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 de Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.

Este documento describe lua-resty-socket v1.0.0 lanzado el 18 de enero de 2019.


Módulo de compatibilidad automática de cosocket/LuaSocket para módulos lua-resty que desean ser compatibles con Lua puro o el contexto init de OpenResty.

El caso de uso para esta biblioteca es: estás desarrollando un módulo lua-resty que depende de cosockets, pero deseas que también sea utilizable en el contexto init de OpenResty o incluso en Lua puro. Este módulo tiene como objetivo proporcionar siempre a tu biblioteca sockets que sean compatibles en el contexto actual, ahorrándote tiempo y esfuerzo, y extendiendo la API de LuaSocket para que coincida con la de cosockets, permitiéndote siempre escribir tu código como si estuvieras en un contexto de OpenResty compatible con cosockets.

Características

  • Permite que tus módulos lua-resty utilicen automáticamente cosockets/LuaSocket
  • Proporciona un proxy sslhandshake al usar LuaSocket, con una dependencia en LuaSec
  • No se bloquea al usar LuaSocket en contextos posteriores si se carga en el init de ngx_lua (un error fácil de cometer)
  • Memoriza los métodos de socket subyacentes para mejorar el rendimiento
  • Genera un registro de advertencia para tus usuarios al crear un socket usando LuaSocket mientras está en OpenResty

Motivación

El objetivo de este módulo es proporcionar una alternativa automática a LuaSocket cuando los cosockets de [ngx_lua] no están disponibles. Es decir: - Cuando no se utiliza en ngx_lua - En contextos de ngx_lua donde los cosockets no son compatibles (init, init_worker, etc...)

Al recurrir a LuaSocket, te proporciona adaptadores para funciones exclusivas de cosocket como getreusedtimes, setkeepalive, etc...

Es útil cuando se desarrolla un módulo/biblioteca que busca ser compatible tanto con ngx_lua como con Lua puro, o en contextos de ngx_lua como init.

Bibliotecas que lo utilizan

Aquí hay algunos ejemplos concretos del uso de este módulo. Puedes ver cómo solo escribimos código como si estuviéramos constantemente en un contexto de OpenResty compatible con cosockets, lo que simplifica enormemente nuestro trabajo y proporciona compatibilidad con Lua puro de inmediato.

  • lua-cassandra: observa cómo el módulo cassandra es compatible tanto en OpenResty como en Lua puro sin esfuerzos ni rutas de código especiales que distingan entre cosockets y LuaSocket.

Nota importante

El uso de LuaSocket dentro de ngx_lua es muy desaconsejado debido a su naturaleza bloqueante. Sin embargo, está bien usarlo en el contexto init donde el bloqueo no se considera perjudicial.

En el futuro, solo la fase init permitirá recurrir a LuaSocket.

Actualmente solo soporta sockets TCP.

Uso

Todas las funciones disponibles siguen el mismo prototipo que la API de cosocket, lo que permite que este ejemplo se ejecute en cualquier contexto de ngx_lua o fuera de ngx_lua por completo:

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

getmetatable(sock) == socket.luasocket_mt ---> true/false dependiendo del socket subyacente

sock:settimeout(1000) ---> 1000ms traducido a 1s si es LuaSocket

sock:getreusedtimes(...) ---> 0 si es LuaSocket

sock:setkeepalive(...) ---> llama a close() si es LuaSocket

sock:sslhandshake(...) ---> dependencia de LuaSec si es LuaSocket

Así, uno puede escribir un módulo que dependa de sockets TCP como:

local socket = require 'resty.socket'

local _M = {}

function _M.new()
  local sock = socket.tcp() -- similar 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
    -- manejar conexión
  end
end

return _M

El usuario de tal módulo podría usarlo en contextos con soporte de cosocket, o en la fase init de ngx_lua, con poco esfuerzo por parte del desarrollador.

GitHub

Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-socket.