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.