Skip to content

Instantly share code, notes, and snippets.

@Earu
Last active September 27, 2020 11:13
Show Gist options
  • Save Earu/f9920693e3bd080b5e318349678c2b55 to your computer and use it in GitHub Desktop.
Save Earu/f9920693e3bd080b5e318349678c2b55 to your computer and use it in GitHub Desktop.
Garry's Mod client-side websockets.
local function init_listener_type(obj, browser, name)
local listeners_key = ("%sListeners"):format(name)
local callback_key = ("On%s"):format(name)
local add_listener_key = ("Add%sListener"):format(name)
obj[listeners_key] = {}
obj[callback_key] = function(...)
for _, listener in ipairs(obj[listeners_key]) do
listener(...)
end
end
obj[add_listener_key] = function(self,f)
table.insert(obj[listeners_key], f)
end
browser:AddFunction("LuaWS", callback_key, obj[callback_key])
browser:QueueJavascript(("WEBSOCKET.on%s = LuaWS.%s;"):format(name:lower(), callback_key))
end
-- AddMessageListener etc... :V
local console_overrides = {
log = print,
info = print,
error = error,
warn = ErrorNoHalt,
}
return function (adr)
local obj = {}
obj.Address = adr
local browser = vgui.Create("DHTML")
browser.IsChatBackup = true
-- for the sake of having something opened to allow us to use js
browser:SetHTML("<html><body></body></html>")
browser:SetAllowLua(true)
-- bring back muh errors on the lua stack
browser:AddFunction("LuaWS", "Error", function(err)
error(err.message)
end)
browser:QueueJavascript(([[
try {
var WEBSOCKET = new WebSocket(%q);
} catch (err) {
LuaWS.Error(err);
}
]]):format(adr:JavascriptSafe()))
for func_name, override in pairs(console_overrides) do
browser:AddFunction("console", func_name, override)
end
init_listener_type(obj, browser, "Open")
init_listener_type(obj, browser, "Close")
init_listener_type(obj, browser, "Message")
init_listener_type(obj, browser, "Error")
function obj:Send(data)
local t = type(data)
if t == "table" then
data = util.TableToJSON(data)
else
data = tostring(data)
end
browser:QueueJavascript(([[
try {
WEBSOCKET.send(%q);
} catch (err) {
LuaWS.Error(err);
}
]]):format(data))
end
function obj:Close()
browser:QueueJavascript([[
try {
WEBSOCKET.close();
} catch (err) {
LuaWS.Error(err);
}
]])
end
function obj:IsValid()
return browser:IsValid()
end
obj.Browser = browser
return obj
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment