Skip to content

Commit

Permalink
Merge pull request #43 from rdeits/refactor-servers
Browse files Browse the repository at this point in the history
refactor out servers components to keep working around JuliaLang/julia#21653
  • Loading branch information
rdeits authored Jun 11, 2018
2 parents 49e385e + b1c6b40 commit 27c5a76
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 58 deletions.
60 changes: 2 additions & 58 deletions src/MeshCat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ using GeometryTypes: raw
using Parameters: @with_kw
using Base.Random: UUID, uuid1
using DocStringExtensions
using Requires: @require
using Mux: page
using JSExpr
using JSExpr: @js, @new, @var
using Base.Filesystem: rm
using BinDeps: download_cmd, unpack_cmd

Expand Down Expand Up @@ -57,9 +55,6 @@ export PointsMaterial,
export Animation,
atframe




include("trees.jl")
using .SceneTrees
include("geometry.jl")
Expand All @@ -71,61 +66,10 @@ include("lowering.jl")
include("msgpack.jl")
include("visualizer.jl")
include("animation_visualizer.jl")
include("servers.jl")

const VIEWER_ROOT = joinpath(@__DIR__, "..", "assets", "meshcat", "dist")

Base.open(vis::Visualizer, args...; kw...) = open(vis.core, args...; kw...)

function Base.open(core::CoreVisualizer, port::Integer)
WebIO.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

@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

function develop_meshcat_assets(skip_confirmation=false)
meshcat_dir = abspath(joinpath(@__DIR__, "..", "assets", "meshcat"))
Expand Down
114 changes: 114 additions & 0 deletions src/servers.jl
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

0 comments on commit 27c5a76

Please sign in to comment.