Class: Crimson::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/crimson/server.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeServer

Returns a new instance of Server.



12
13
14
# File 'lib/crimson/server.rb', line 12

def initialize
  @clients = {}
end

Instance Attribute Details

#clientsObject (readonly)

Returns the value of attribute clients.



10
11
12
# File 'lib/crimson/server.rb', line 10

def clients
  @clients
end

Class Method Details

.staticObject



28
29
30
# File 'lib/crimson/server.rb', line 28

def self.static
  { :urls => [File.expand_path("#{__dir__}/.."), File.expand_path("#{__dir__}/../javascript")] }
end

.template_html_pathObject



24
25
26
# File 'lib/crimson/server.rb', line 24

def self.template_html_path
  File.expand_path("#{__dir__}/../html/template.html")
end

Instance Method Details

#call(env) ⇒ Object



39
40
41
# File 'lib/crimson/server.rb', line 39

def call(env)
  call_async(env) or call_faye(env) or serve_template(env)
end

#call_async(env) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/crimson/server.rb', line 43

def call_async(env)
  Async::WebSocket::Adapters::Rack.open(env, protocols: ['ws']) do |connection|
    id = :"client_#{Utilities.generate_id}"
    client = Client.new(id, connection)
    clients[connection] = client
    
    @on_connect&.call(client)

    begin
      while message = connection.read
        client.on_message(message)
      end
    rescue Protocol::WebSocket::ClosedError
      
    end
  ensure
    @on_disconnect&.call(client)
    clients.delete(connection)
    connection.close
  end
end

#call_faye(env) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/crimson/server.rb', line 65

def call_faye(env)
  if Faye::WebSocket.websocket?(env)
    connection = Crimson::Adapters::Faye.new(Faye::WebSocket.new(env))
    id = :"client_#{Utilities.generate_id}"
    client = Client.new(id, connection)
    clients[id] = client

    @on_connect&.call(client)

    connection.on :message do |event|
      client.on_message(JSON.parse(event.data))
    end

    connection.on :close do |event|
      @on_disconnect&.call(client)
      clients.delete(id)
      connection = nil
    end

    return connection.rack_response
  end
end

#content(port, path = Server.template_html_path) ⇒ Object



32
33
34
35
36
37
# File 'lib/crimson/server.rb', line 32

def content(port, path = Server.template_html_path)
  template = File.read(path)
  template.sub!("{PORT}", port)

  [template]
end

#on_connect(&block) ⇒ Object



16
17
18
# File 'lib/crimson/server.rb', line 16

def on_connect(&block)
  @on_connect = block if block_given?
end

#on_disconnect(&block) ⇒ Object



20
21
22
# File 'lib/crimson/server.rb', line 20

def on_disconnect(&block)
  @on_disconnect = block if block_given?
end

#serve_template(env) ⇒ Object



88
89
90
91
92
93
94
# File 'lib/crimson/server.rb', line 88

def serve_template(env)
  if env['REQUEST_PATH'] != '/'
    return Rack::Directory.new(File.expand_path("#{__dir__}/..")).call(env)
  else
    return [200, {"Content-Type" => "text/html"}, content(env['SERVER_PORT'])]
  end
end