Aller au contenu

socket: Module de compatibilité automatique LuaSocket/cosockets

Installation

Si vous n'avez pas configuré l'abonnement au dépôt RPM, inscrivez-vous. Ensuite, vous pouvez procéder avec les étapes suivantes.

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

Pour utiliser cette bibliothèque Lua avec NGINX, assurez-vous que nginx-module-lua est installé.

Ce document décrit lua-resty-socket v1.0.0 publiée le 18 janvier 2019.


Module de compatibilité automatique cosocket/LuaSocket pour les modules lua-resty souhaitant être compatibles avec Lua standard ou le contexte init d'OpenResty.

Le cas d'utilisation de cette bibliothèque est le suivant : vous développez un module lua-resty s'appuyant sur des cosockets, mais vous souhaitez qu'il soit également utilisable dans le contexte init d'OpenResty ou même dans Lua standard. Ce module vise à toujours fournir à votre bibliothèque des sockets qui seront compatibles dans le contexte actuel, vous faisant gagner du temps et des efforts, et étendant l'API de LuaSocket pour correspondre à celle des cosockets, vous permettant d'écrire toujours votre code comme si vous étiez dans un contexte OpenResty compatible avec les cosockets.

Caractéristiques

  • Permet à vos modules lua-resty d'utiliser automatiquement des cosockets/LuaSocket
  • Fournit un proxy sslhandshake lors de l'utilisation de LuaSocket, avec une dépendance à LuaSec
  • Ne bloque pas l'utilisation de LuaSocket dans d'autres contextes s'il est chargé dans le init de ngx_lua (erreur facile à commettre)
  • Mémorise les méthodes de socket sous-jacentes pour des performances accrues
  • Émet un journal d'avertissement pour vos utilisateurs lors de la création d'un socket utilisant LuaSocket tout en étant dans OpenResty

Motivation

L'objectif de ce module est de fournir un retour automatique à LuaSocket lorsque les cosockets de [ngx_lua] ne sont pas disponibles. C'est-à-dire : - Lorsqu'il n'est pas utilisé dans ngx_lua - Dans les contextes ngx_lua où les cosockets ne sont pas pris en charge (init, init_worker, etc...)

Lorsqu'il revient à LuaSocket, il vous fournit des adaptateurs pour des fonctions réservées aux cosockets telles que getreusedtimes, setkeepalive, etc...

Il est pratique lorsque l'on développe un module/bibliothèque qui vise à être compatible à la fois avec ngx_lua et Lua standard, ou dans des contextes ngx_lua tels que init.

Bibliothèques l'utilisant

Voici quelques exemples concrets d'utilisation de ce module. Vous pouvez voir comment nous n'écrivons que du code comme si nous étions constamment dans un contexte OpenResty compatible avec les cosockets, ce qui simplifie grandement notre travail et fournit une compatibilité avec Lua standard dès le départ.

  • lua-cassandra : voyez comment le module cassandra est compatible à la fois dans OpenResty et Lua standard sans efforts ni chemins de code spéciaux distinguant les cosockets et LuaSocket.

Note importante

L'utilisation de LuaSocket à l'intérieur de ngx_lua est très fortement déconseillée en raison de sa nature bloquante. Cependant, il est acceptable de l'utiliser dans le contexte init où le blocage n'est pas considéré comme nuisible.

À l'avenir, seule la phase init permettra de revenir à LuaSocket.

Il prend actuellement uniquement en charge les sockets TCP.

Utilisation

Toutes les fonctions disponibles suivent le même prototype que l'API des cosockets, permettant à cet exemple de s'exécuter dans n'importe quel contexte ngx_lua ou en dehors de ngx_lua dans son ensemble :

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

getmetatable(sock) == socket.luasocket_mt ---> true/false selon le socket sous-jacent

sock:settimeout(1000) ---> 1000ms traduit en 1s si LuaSocket

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

sock:setkeepalive(...) ---> appelle close() si LuaSocket

sock:sslhandshake(...) ---> dépendance LuaSec si LuaSocket

Ainsi, on peut écrire un module s'appuyant sur des sockets TCP tel que :

local socket = require 'resty.socket'

local _M = {}

function _M.new()
  local sock = socket.tcp() -- similaire à 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 cosocket
  if not times then
    return nil, err
  elseif times == 0 then
    -- gérer la connexion
  end
end

return _M

L'utilisateur d'un tel module pourrait l'utiliser dans des contextes avec support des cosockets, ou dans la phase init de ngx_lua, avec peu d'efforts de la part du développeur.

GitHub

Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-socket.