-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from rdeits/refactor-servers
refactor out servers components to keep working around JuliaLang/julia#21653
- Loading branch information
Showing
2 changed files
with
116 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
module Servers | ||
module MuxProvider | ||
using Mux | ||
using WebIO | ||
using JSON | ||
|
||
# This module was copied over from | ||
# https://github.com/JuliaGizmos/WebIO.jl/blob/8e25ed2f9cf3158652907735bd44420205a105d9/src/providers/mux.jl | ||
# to attempt to avoid inference issues described in: | ||
# https://github.com/JuliaLang/julia/issues/21653 | ||
function webio_serve(app, port=8000) | ||
http = Mux.App(Mux.mux( | ||
Mux.defaults, | ||
app, | ||
Mux.notfound() | ||
)) | ||
|
||
websock = Mux.App(Mux.mux( | ||
Mux.wdefaults, | ||
route("/webio-socket", create_socket), | ||
Mux.wclose, | ||
Mux.notfound(), | ||
)) | ||
|
||
serve(http, websock, port) | ||
end | ||
|
||
struct WebSockConnection <: 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 Base.send(p::WebSockConnection, data) | ||
write(p.sock, sprint(io->JSON.print(io,data))) | ||
end | ||
|
||
Base.isopen(p::WebSockConnection) = isopen(p.sock) | ||
end | ||
|
||
using .MuxProvider: webio_serve | ||
using MeshCat: CoreVisualizer, Visualizer | ||
using Mux: page | ||
|
||
Base.open(vis::Visualizer, args...; kw...) = open(vis.core, args...; kw...) | ||
|
||
function Base.open(core::CoreVisualizer, port::Integer) | ||
webio_serve(page("/", req -> core.scope), port) | ||
url = "http://127.0.0.1:$port" | ||
info("Serving MeshCat visualizer at $url") | ||
open_url(url) | ||
end | ||
|
||
function open_url(url) | ||
try | ||
if is_windows() | ||
run(`start $url`) | ||
elseif is_apple() | ||
run(`open $url`) | ||
elseif is_linux() | ||
run(`xdg-open $url`) | ||
end | ||
catch e | ||
println("Could not open browser automatically: $e") | ||
println("Please open the following URL in your browser:") | ||
println(url) | ||
end | ||
end | ||
|
||
function Base.open(core::CoreVisualizer; default_port=8700, max_retries=500) | ||
for port in default_port + (0:max_retries) | ||
server = try | ||
listen(port) | ||
catch e | ||
if e isa Base.UVError | ||
continue | ||
end | ||
end | ||
close(server) | ||
# It is *possible* that a race condition could occur here, in which | ||
# some other process grabs the given port in between the close() above | ||
# and the open() below. But it's unlikely and would not be terribly | ||
# damaging (the user would just have to call open() again). | ||
return open(core, port) | ||
end | ||
end | ||
end | ||
|
||
module BlinkInterface | ||
using Requires | ||
using MeshCat: CoreVisualizer | ||
|
||
@require Blink begin | ||
function Base.open(core::CoreVisualizer, w::Blink.AtomShell.Window) | ||
# Ensure the window is ready | ||
Blink.js(w, "ok") | ||
# Set its contents | ||
Blink.body!(w, core.scope) | ||
w | ||
end | ||
end | ||
end |