Перейти к содержанию

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

Чтобы использовать эту библиотеку Lua с NGINX, убедитесь, что установлен nginx-module-lua.

Этот документ описывает lua-resty-socket v1.0.0, выпущенный 18 января 2019 года.


Модуль автоматической совместимости cosocket/LuaSocket для lua-resty модулей, которые хотят быть совместимыми с обычным Lua или контекстом init OpenResty.

Сценарий использования этой библиотеки: вы разрабатываете модуль lua-resty, который зависит от cosockets, но хотите, чтобы его также можно было использовать в контексте init OpenResty или даже в обычном Lua. Этот модуль нацелен на то, чтобы всегда предоставлять вашей библиотеке сокеты, которые будут совместимы в текущем контексте, экономя ваше время и усилия, и расширяя API LuaSocket, чтобы соответствовать API cosockets, позволяя вам всегда писать ваш код так, как будто вы находитесь в контексте OpenResty, совместимом с cosocket.

Особенности

  • Позволяет вашим lua-resty модулям автоматически использовать cosockets/LuaSocket
  • Предоставляет прокси sslhandshake при использовании LuaSocket, с зависимостью от LuaSec
  • Не блокирует использование LuaSocket в других контекстах, если загружен в ngx_lua init (легкая ошибка)
  • Кэширует методы сокетов для повышения производительности
  • Выводит предупреждение в журнал для ваших пользователей при создании сокета с использованием LuaSocket в OpenResty

Мотивация

Цель этого модуля - предоставить автоматическое резервное решение для LuaSocket, когда cosockets [ngx_lua] недоступны. То есть: - Когда не используется в ngx_lua - В контекстах ngx_lua, где cosockets не поддерживаются (init, init_worker и т.д.)

При переходе на LuaSocket он предоставляет вам шимы для функций, доступных только для cosocket, таких как getreusedtimes, setkeepalive и т.д.

Это удобно, когда вы разрабатываете модуль/библиотеку, которая должна быть совместима как с ngx_lua так и с обычным Lua, или в контекстах ngx_lua, таких как init.

Библиотеки, использующие его

Вот несколько конкретных примеров использования этого модуля. Вы можете увидеть, как мы пишем код так, как будто мы постоянно находимся в контексте OpenResty, совместимом с cosocket, что значительно упрощает нашу работу и предоставляет совместимость с обычным Lua из коробки.

  • lua-cassandra: посмотрите, как модуль cassandra совместим как с OpenResty, так и с обычным Lua без усилий или специальных кодовых путей, различающих cosockets и LuaSocket.

Важное примечание

Использование LuaSocket внутри ngx_lua категорически не рекомендуется из-за его блокирующей природы. Однако его можно использовать в контексте init, где блокировка не считается вредной.

В будущем только фаза init будет позволять переход на LuaSocket.

В настоящее время поддерживаются только TCP сокеты.

Использование

Все доступные функции следуют тому же прототипу, что и API cosocket, что позволяет этому примеру работать в любом контексте ngx_lua или вообще вне ngx_lua:

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

getmetatable(sock) == socket.luasocket_mt ---> true/false в зависимости от базового сокета

sock:settimeout(1000) ---> 1000ms переводится в 1s, если LuaSocket

sock:getreusedtimes(...) ---> 0, если LuaSocket

sock:setkeepalive(...) ---> вызывает close(), если LuaSocket

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() -- API cosocket
  if not times then
    return nil, err
  elseif times == 0 then
    -- обработка соединения
  end
end

return _M

Пользователь такого модуля может использовать его в контекстах с поддержкой cosocket или в фазе init ngx_lua, с минимальными усилиями со стороны разработчика.

GitHub

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-socket.