fix(reload): bind SSE server to port 0 for OS-assigned port

Problem: the SSE reload server hardcoded port 5554, causing silent
failure when that port was already in use. bind() would fail but its
return value was never checked; listen() would also error and silently
drop via the if err then return end guard. inject() still wrote the
dead EventSource URL into the HTML, so the browser would connect to
whatever was on 5554 — or nothing — and live reload would silently
stop working.

Solution: bind to port or 0 so the OS assigns a free port, then call
getsockname() after bind to capture the actual port into actual_port.
inject() reads actual_port in preference to the hardcoded constant,
and stop() resets it. PORT = 5554 is kept only as a last-resort
fallback in inject() if actual_port is unset.
This commit is contained in:
Barrett Ruth 2026-03-03 17:41:53 -05:00
parent 62961c8541
commit 2888c5bb09
Signed by: barrett
GPG key ID: A6C96C9349D2FC81

View file

@ -2,6 +2,7 @@ local M = {}
local PORT = 5554
local server_handle = nil
local actual_port = nil
local clients = {}
local function make_script(port)
@ -14,12 +15,15 @@ local function make_script(port)
end
function M.start(port)
port = port or PORT
if server_handle then
return
end
local server = vim.uv.new_tcp()
server:bind('127.0.0.1', port)
server:bind('127.0.0.1', port or 0)
local sockname = server:getsockname()
if sockname then
actual_port = sockname.port
end
server:listen(128, function(err)
if err then
return
@ -66,6 +70,7 @@ function M.stop()
server_handle:close()
server_handle = nil
end
actual_port = nil
end
function M.broadcast()
@ -85,7 +90,7 @@ function M.broadcast()
end
function M.inject(path, port)
port = port or PORT
port = actual_port or port or PORT
local f = io.open(path, 'r')
if not f then
return