class Flammarion::Server

@api private

Attributes

port[R]
server_thread[R]
webrick_port[R]

Public Class Methods

new() click to toggle source
# File lib/flammarion/server.rb, line 6
def initialize
  @windows = {}
  @socket_paths = {}
  @started = false
  @launch_thread = Thread.current
  @server_thread = Thread.new do
    begin
      start_http_server
      start_server_internal
    rescue StandardError
      handle_exception($!)
    end
  end
  sleep 0.01 while not @started
end

Public Instance Methods

handle_exception(e) click to toggle source
# File lib/flammarion/server.rb, line 98
def handle_exception(e)
  @launch_thread.raise(e)
end
log(str) click to toggle source
# File lib/flammarion/server.rb, line 94
def log(str)
  # Kernel.puts str
end
register_window(window) click to toggle source
# File lib/flammarion/server.rb, line 102
def register_window(window)
  @new_path ||= 0
  @new_path += 1
  @windows["/w#{@new_path}"] = window
  return "w#{@new_path}"
end
start_http_server() click to toggle source
# File lib/flammarion/server.rb, line 27
def start_http_server
  source_dir = File.absolute_path(File.join(File.dirname(File.absolute_path(__FILE__)), "/../html/source/"))
  begin
    @webrick_port = rand(65000 - 1024) + 1024
    @webrick = WEBrick::HTTPServer.new(Host: '127.0.0.1', Port: @webrick_port, DocumentRoot: source_dir, AccessLog: [], Logger: WEBrick::Log.new(File.open(File::NULL, 'w')))
  rescue RuntimeError, Errno::EADDRINUSE, Errno::EACCES
    if $!.message == "no acceptor (port is in use or requires root privileges)" or $!.is_a? Errno::EADDRINUSE or $!.is_a? Errno::EACCES
      @webrick_port = rand(65000 - 1024) + 1024
      retry
    else
      raise
    end
  end
  Thread.new { @webrick.start }
end
start_server_internal() click to toggle source
# File lib/flammarion/server.rb, line 43
def start_server_internal
  @port = 7870
  @port = rand(65000 - 1024) + 1024 if Gem.win_platform? || wsl_platform

  begin
    @server = Rubame::Server.new("127.0.0.1", @port)
    log "WebServer started on port #{@port}"
    while true do
      @started = true
      @server.run do |ws|
        ws.onopen {
          log "WebSocket connection open"
          if @windows.include?(ws.handshake.path)
            @windows[ws.handshake.path].sockets << ws
            @windows[ws.handshake.path].on_connect.call() if @windows[ws.handshake.path].on_connect
            @socket_paths[ws] = ws.handshake.path
          else
            log "No such window: #{handshake.path}"
          end
        }

        ws.onclose do
          log "Connection closed";
          @windows[@socket_paths[ws]].disconnect(ws) if @windows[@socket_paths[ws]]
        end

        ws.onmessage { |msg|
          Thread.new do
            begin
              @windows[@socket_paths[ws]].process_message(msg)
            rescue Exception
              handle_exception($!)
            end
          end
        }
      end
    end
  rescue RuntimeError, Errno::EADDRINUSE, Errno::EACCES
    if $!.message == "no acceptor (port is in use or requires root privileges)" or $!.is_a? Errno::EADDRINUSE or $!.is_a? Errno::EACCES
      @port = rand(65000 - 1024) + 1024
      retry
    else
      raise
    end
  end
  @started = true
end
stop() click to toggle source
# File lib/flammarion/server.rb, line 91
def stop
end
wsl_platform() click to toggle source
# File lib/flammarion/server.rb, line 22
def wsl_platform
  return File.file?('/proc/version') &&
    File.open('/proc/version', &:gets).downcase.include?("microsoft")
end