-
Notifications
You must be signed in to change notification settings - Fork 64
/
mux.jl
89 lines (75 loc) · 1.97 KB
/
mux.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using JSON
using AssetRegistry
using Sockets
using Base64: stringmime
export webio_serve
"""
webio_serve(app, port=8000)
Serve a Mux app which might return a WebIO node.
"""
function webio_serve(app, args...)
http = Mux.App(Mux.mux(
Mux.defaults,
app,
Mux.notfound()
))
webio_serve(http, args...)
end
function webio_serve(app::Mux.App, args...)
websock = Mux.App(Mux.mux(
Mux.wdefaults,
Mux.route("/webio-socket", create_socket),
Mux.wclose,
Mux.notfound(),
))
Mux.serve(app, websock, args...)
end
struct WebSockConnection <: WebIO.AbstractConnection
sock
end
function create_socket(req)
sock = req[:socket]
conn = WebSockConnection(sock)
t = @async while isopen(sock)
data = read(sock)
msg = JSON.parse(String(data))
WebIO.dispatch(conn, msg)
end
wait(t)
end
function Sockets.send(p::WebSockConnection, data)
write(p.sock, sprint(io->JSON.print(io,data)))
end
Base.isopen(p::WebSockConnection) = isopen(p.sock)
Mux.Response(o::AbstractWidget) = Mux.Response(Widgets.render(o))
function Mux.Response(content::Union{Node, Scope})
script_url = try
AssetRegistry.register(MUX_BUNDLE_PATH)
catch exc
@error(
"Unable to register Mux bundle path: $MUX_BUNDLE_PATH.\n"
* "Try rebuilding WebIO.",
exception=exc,
)
rethrow()
end
Mux.Response(
"""
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<script src="$(WebIO.baseurl[])$(script_url)"></script>
</head>
<body>
$(stringmime(MIME("text/html"), content))
</body>
</html>
"""
)
end
function WebIO.register_renderable(::Type{T}, ::Val{:mux}) where {T}
eval(:(Mux.Response(x::$T) = Mux.Response(WebIO.render(x))))
end
WebIO.setup_provider(::Val{:mux}) = nothing # Mux setup has no side-effects
WebIO.setup(:mux)