openresty / lua-resty-websocket

WebSocket support for the ngx_lua module (and OpenResty)
506 stars 106 forks source link

[idea] support HTTP connection reuse #73

Closed StarlightIbuki closed 1 year ago

StarlightIbuki commented 2 years ago

Maybe we can reuse an HTTP connection to establish a WebSocket client?

A direct implementation may be to allow users to pass sock(ngx.socket.tcp) as an argument:

function _M.new(self, opts, sock_reuse)
    local sock, err
    if sock_reuse == nil then
        sock, err= tcp()
    else
        sock = sock_reuse
    end
    if not sock then
        return nil, err
    end

    local max_payload_len, send_unmasked, timeout
    if opts then
        max_payload_len = opts.max_payload_len
        send_unmasked = opts.send_unmasked
        timeout = opts.timeout

        if timeout then
            sock:settimeout(timeout)
        end
    end

    return setmetatable({
        sock = sock,
        max_payload_len = max_payload_len or 65535,
        send_unmasked = send_unmasked,
    }, mt)
end

and then we may do this:

local httpc = require("resty.http").new()
-- some requests
-- ...
local wsock = require("resty.websock.client"):new(nil, httpc.sock)
-- and we shall not use httpc after here

(The code is for demonstration. It should be organized in a better way)

StarlightIbuki commented 2 years ago

It looks like a hack and relies on an undocumented implementation detail of resty.http. Anyone could suggest a better idea?

StarlightIbuki commented 2 years ago

Also, I am not sure if this is permitted by the RFC.

dndx commented 2 years ago

I do not believe this is a good idea. As WebSocket is bi-directional and it is expected to receive message from the other end at any moment, this won't work well with typical keepalive behavior (Nginx will close the keepalive connection immediately if any data is received on a keepalived connection). Plus, using keep-alive is like using WebSocket like a regular HTTP request, why not just use HTTP instead?

javierguerragiraldez commented 2 years ago

Plus, using keep-alive is like using WebSocket like a regular HTTP request, why not just use HTTP instead?

The goal is to open an HTTP connection, do some requests and then upgrade to WebSocket. Right now this module conflates the client connection and upgrade in a single step.