Class: CelluloidPubsub::WebServer

Inherits:
Reel::Server::HTTP
  • Object
show all
Includes:
Celluloid::Logger
Defined in:
lib/celluloid_pubsub/web_server.rb

Overview

webserver to which socket connects should connect to . the server will dispatch each request into a new Reactor which will handle the action based on the message

Constant Summary

HOST =

The hostname on which the webserver runs on by default

'0.0.0.0'
PORT =

The port on which the webserver runs on by default

1234
PATH =

The request path that the webserver accepts by default

'/ws'

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (void) initialize(options = {})

receives a list of options that are used to configure the webserver

Parameters:

  • options (Hash) (defaults to: {})

    the options that can be used to connect to webser and send additional data

Options Hash (options):

  • :hostname (String)

    The hostname on which the webserver runs on

  • :port (Integer)

    The port on which the webserver runs on

  • :path (String)

    The request path that the webserver accepts

  • :spy (Boolean)

    Enable this only if you want to enable debugging for the webserver



54
55
56
57
58
59
# File 'lib/celluloid_pubsub/web_server.rb', line 54

def initialize(options = {})
  parse_options(options)
  @subscribers = {}
  info "CelluloidPubsub::WebServer example starting on #{@hostname}:#{@port}" if debug_enabled?
  super(@hostname, @port, { spy: @spy, backlog: @backlog }, &method(:on_connection))
end

Instance Attribute Details

- (Integer) backlog

Defaults to 1024

Returns:

  • (Integer)

    Determines how many connections can be used



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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/celluloid_pubsub/web_server.rb', line 31

class WebServer < Reel::Server::HTTP
  include Celluloid::Logger

  # The hostname on which the webserver runs on by default
  HOST = '0.0.0.0'
  # The port on which the webserver runs on by default
  PORT = 1234
  # The request path that the webserver accepts by default
  PATH = '/ws'

  attr_accessor :options, :subscribers, :backlog, :hostname, :port, :path, :spy

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  #
  # @return [void]
  #
  # @api public
  def initialize(options = {})
    parse_options(options)
    @subscribers = {}
    info "CelluloidPubsub::WebServer example starting on #{@hostname}:#{@port}" if debug_enabled?
    super(@hostname, @port, { spy: @spy, backlog: @backlog }, &method(:on_connection))
  end

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  # @option options [Integer]:backlog How many connections the server accepts
  #
  # @return [void]
  #
  # @api public
  def parse_options(options)
    raise 'Options is not a hash ' unless options.is_a?(Hash)
    @options = options.stringify_keys
    @backlog = @options.fetch(:backlog, 1024)
    @hostname = @options.fetch(:hostname, CelluloidPubsub::WebServer::HOST)
    @port = @options.fetch(:port, CelluloidPubsub::WebServer::PORT)
    @path = @options.fetch(:path, CelluloidPubsub::WebServer::PATH)
    @spy = @options.fetch(:spy, false)
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def debug_enabled?
    self.class.debug_enabled?
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def self.debug_enabled?
    ENV['DEBUG_CELLULOID'].present? && (ENV['DEBUG_CELLULOID'] == 'true' || ENV['DEBUG_CELLULOID'] == true)
  end

  #  checks if debug is enabled
  #
  # @param [String] current_topic The Channel to which the reactor instance {CelluloidPubsub::Rector} will publish the message to
  # @param [Object] message
  #
  # @return [void]
  #
  # @api public
  def publish_event(current_topic, message)
    return if current_topic.blank? || message.blank?
    @subscribers[current_topic].each do |hash|
      hash[:reactor].websocket << message
    end
  end

  #  callback that will execute when receiving new conections
  # If the connections is a websocket will call method {#route_websocket}
  # and if the connection is HTTP will call method {#route_request}
  # For websocket connections , the connection is detached from the server and dispatched to another actor
  #
  # @see #route_websocket
  # @see #route_request
  #
  # @param [Reel::WebSocket] connection The connection that was made to the webserver
  #
  # @return [void]
  #
  # @api public
  def on_connection(connection)
    while request = connection.request
      if request.websocket?
        info 'Received a WebSocket connection' if debug_enabled?

        # We're going to hand off this connection to another actor (Writer/Reader)
        # However, initially Reel::Connections are "attached" to the
        # Reel::Server::HTTP actor, meaning that the server manages the connection
        # lifecycle (e.g. error handling) for us.
        #
        # If we want to hand this connection off to another actor, we first
        # need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
        connection.detach
        route_websocket(request.websocket)
        return
      else
        route_request connection, request
      end
    end
  end

  #  HTTP connections are not accepted so this method will show 404 message "Not Found"
  #
  # @param [Reel::WebSocket] connection The HTTP connection that was received
  # @param [Reel::Request] request The request that was made to the webserver and contains the type , the url, and the parameters
  #
  # @return [void]
  #
  # @api public
  def route_request(connection, request)
    info "404 Not Found: #{request.path}" if debug_enabled?
    connection.respond :not_found, 'Not found'
  end

  #  If the socket url matches with the one accepted by the server, it will dispatch the socket connection to a new reactor {CelluloidPubsub::Reactor#work}
  # The new actor is linked to the webserver
  #
  # @see CelluloidPubsub::Reactor#work
  #
  #  @param [Reel::WebSocket] socket The  web socket connection that was received
  #
  # @return [void]
  #
  # @api public
  def route_websocket(socket)
    if socket.url == @path
      info 'Reactor handles new socket connection' if debug_enabled?
      reactor = CelluloidPubsub::Reactor.new
      Actor.current.link reactor
      reactor.async.work(socket, Actor.current)
    else
      info "Received invalid WebSocket request for: #{socket.url}" if debug_enabled?
      socket.close
    end
  end

  # If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format
  # otherwise will try send the message how it is and escaped into JSON format
  #
  # @param [CelluloidPubsub::Reactor] reactor The  reactor that received an unhandled message
  # @param [Object] data The message that the reactor could not handle
  #
  # @return [void]
  #
  # @api public
  def handle_dispatched_message(reactor, data)
    debug "Webserver trying to dispatch message  #{data.inspect}" if debug_enabled?
    message = reactor.parse_json_data(data)
    if message.present? && message.is_a?(Hash)
      reactor.websocket << message.to_json
    else
      reactor.websocket << data.to_json
    end
  end
end

- (String) hostname

Returns The hostname on which the webserver runs on

Returns:

  • (String)

    The hostname on which the webserver runs on



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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/celluloid_pubsub/web_server.rb', line 31

class WebServer < Reel::Server::HTTP
  include Celluloid::Logger

  # The hostname on which the webserver runs on by default
  HOST = '0.0.0.0'
  # The port on which the webserver runs on by default
  PORT = 1234
  # The request path that the webserver accepts by default
  PATH = '/ws'

  attr_accessor :options, :subscribers, :backlog, :hostname, :port, :path, :spy

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  #
  # @return [void]
  #
  # @api public
  def initialize(options = {})
    parse_options(options)
    @subscribers = {}
    info "CelluloidPubsub::WebServer example starting on #{@hostname}:#{@port}" if debug_enabled?
    super(@hostname, @port, { spy: @spy, backlog: @backlog }, &method(:on_connection))
  end

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  # @option options [Integer]:backlog How many connections the server accepts
  #
  # @return [void]
  #
  # @api public
  def parse_options(options)
    raise 'Options is not a hash ' unless options.is_a?(Hash)
    @options = options.stringify_keys
    @backlog = @options.fetch(:backlog, 1024)
    @hostname = @options.fetch(:hostname, CelluloidPubsub::WebServer::HOST)
    @port = @options.fetch(:port, CelluloidPubsub::WebServer::PORT)
    @path = @options.fetch(:path, CelluloidPubsub::WebServer::PATH)
    @spy = @options.fetch(:spy, false)
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def debug_enabled?
    self.class.debug_enabled?
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def self.debug_enabled?
    ENV['DEBUG_CELLULOID'].present? && (ENV['DEBUG_CELLULOID'] == 'true' || ENV['DEBUG_CELLULOID'] == true)
  end

  #  checks if debug is enabled
  #
  # @param [String] current_topic The Channel to which the reactor instance {CelluloidPubsub::Rector} will publish the message to
  # @param [Object] message
  #
  # @return [void]
  #
  # @api public
  def publish_event(current_topic, message)
    return if current_topic.blank? || message.blank?
    @subscribers[current_topic].each do |hash|
      hash[:reactor].websocket << message
    end
  end

  #  callback that will execute when receiving new conections
  # If the connections is a websocket will call method {#route_websocket}
  # and if the connection is HTTP will call method {#route_request}
  # For websocket connections , the connection is detached from the server and dispatched to another actor
  #
  # @see #route_websocket
  # @see #route_request
  #
  # @param [Reel::WebSocket] connection The connection that was made to the webserver
  #
  # @return [void]
  #
  # @api public
  def on_connection(connection)
    while request = connection.request
      if request.websocket?
        info 'Received a WebSocket connection' if debug_enabled?

        # We're going to hand off this connection to another actor (Writer/Reader)
        # However, initially Reel::Connections are "attached" to the
        # Reel::Server::HTTP actor, meaning that the server manages the connection
        # lifecycle (e.g. error handling) for us.
        #
        # If we want to hand this connection off to another actor, we first
        # need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
        connection.detach
        route_websocket(request.websocket)
        return
      else
        route_request connection, request
      end
    end
  end

  #  HTTP connections are not accepted so this method will show 404 message "Not Found"
  #
  # @param [Reel::WebSocket] connection The HTTP connection that was received
  # @param [Reel::Request] request The request that was made to the webserver and contains the type , the url, and the parameters
  #
  # @return [void]
  #
  # @api public
  def route_request(connection, request)
    info "404 Not Found: #{request.path}" if debug_enabled?
    connection.respond :not_found, 'Not found'
  end

  #  If the socket url matches with the one accepted by the server, it will dispatch the socket connection to a new reactor {CelluloidPubsub::Reactor#work}
  # The new actor is linked to the webserver
  #
  # @see CelluloidPubsub::Reactor#work
  #
  #  @param [Reel::WebSocket] socket The  web socket connection that was received
  #
  # @return [void]
  #
  # @api public
  def route_websocket(socket)
    if socket.url == @path
      info 'Reactor handles new socket connection' if debug_enabled?
      reactor = CelluloidPubsub::Reactor.new
      Actor.current.link reactor
      reactor.async.work(socket, Actor.current)
    else
      info "Received invalid WebSocket request for: #{socket.url}" if debug_enabled?
      socket.close
    end
  end

  # If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format
  # otherwise will try send the message how it is and escaped into JSON format
  #
  # @param [CelluloidPubsub::Reactor] reactor The  reactor that received an unhandled message
  # @param [Object] data The message that the reactor could not handle
  #
  # @return [void]
  #
  # @api public
  def handle_dispatched_message(reactor, data)
    debug "Webserver trying to dispatch message  #{data.inspect}" if debug_enabled?
    message = reactor.parse_json_data(data)
    if message.present? && message.is_a?(Hash)
      reactor.websocket << message.to_json
    else
      reactor.websocket << data.to_json
    end
  end
end

- (Hash) options

Returns options used to configure the webserver

Returns:

  • (Hash)

    options used to configure the webserver



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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/celluloid_pubsub/web_server.rb', line 31

class WebServer < Reel::Server::HTTP
  include Celluloid::Logger

  # The hostname on which the webserver runs on by default
  HOST = '0.0.0.0'
  # The port on which the webserver runs on by default
  PORT = 1234
  # The request path that the webserver accepts by default
  PATH = '/ws'

  attr_accessor :options, :subscribers, :backlog, :hostname, :port, :path, :spy

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  #
  # @return [void]
  #
  # @api public
  def initialize(options = {})
    parse_options(options)
    @subscribers = {}
    info "CelluloidPubsub::WebServer example starting on #{@hostname}:#{@port}" if debug_enabled?
    super(@hostname, @port, { spy: @spy, backlog: @backlog }, &method(:on_connection))
  end

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  # @option options [Integer]:backlog How many connections the server accepts
  #
  # @return [void]
  #
  # @api public
  def parse_options(options)
    raise 'Options is not a hash ' unless options.is_a?(Hash)
    @options = options.stringify_keys
    @backlog = @options.fetch(:backlog, 1024)
    @hostname = @options.fetch(:hostname, CelluloidPubsub::WebServer::HOST)
    @port = @options.fetch(:port, CelluloidPubsub::WebServer::PORT)
    @path = @options.fetch(:path, CelluloidPubsub::WebServer::PATH)
    @spy = @options.fetch(:spy, false)
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def debug_enabled?
    self.class.debug_enabled?
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def self.debug_enabled?
    ENV['DEBUG_CELLULOID'].present? && (ENV['DEBUG_CELLULOID'] == 'true' || ENV['DEBUG_CELLULOID'] == true)
  end

  #  checks if debug is enabled
  #
  # @param [String] current_topic The Channel to which the reactor instance {CelluloidPubsub::Rector} will publish the message to
  # @param [Object] message
  #
  # @return [void]
  #
  # @api public
  def publish_event(current_topic, message)
    return if current_topic.blank? || message.blank?
    @subscribers[current_topic].each do |hash|
      hash[:reactor].websocket << message
    end
  end

  #  callback that will execute when receiving new conections
  # If the connections is a websocket will call method {#route_websocket}
  # and if the connection is HTTP will call method {#route_request}
  # For websocket connections , the connection is detached from the server and dispatched to another actor
  #
  # @see #route_websocket
  # @see #route_request
  #
  # @param [Reel::WebSocket] connection The connection that was made to the webserver
  #
  # @return [void]
  #
  # @api public
  def on_connection(connection)
    while request = connection.request
      if request.websocket?
        info 'Received a WebSocket connection' if debug_enabled?

        # We're going to hand off this connection to another actor (Writer/Reader)
        # However, initially Reel::Connections are "attached" to the
        # Reel::Server::HTTP actor, meaning that the server manages the connection
        # lifecycle (e.g. error handling) for us.
        #
        # If we want to hand this connection off to another actor, we first
        # need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
        connection.detach
        route_websocket(request.websocket)
        return
      else
        route_request connection, request
      end
    end
  end

  #  HTTP connections are not accepted so this method will show 404 message "Not Found"
  #
  # @param [Reel::WebSocket] connection The HTTP connection that was received
  # @param [Reel::Request] request The request that was made to the webserver and contains the type , the url, and the parameters
  #
  # @return [void]
  #
  # @api public
  def route_request(connection, request)
    info "404 Not Found: #{request.path}" if debug_enabled?
    connection.respond :not_found, 'Not found'
  end

  #  If the socket url matches with the one accepted by the server, it will dispatch the socket connection to a new reactor {CelluloidPubsub::Reactor#work}
  # The new actor is linked to the webserver
  #
  # @see CelluloidPubsub::Reactor#work
  #
  #  @param [Reel::WebSocket] socket The  web socket connection that was received
  #
  # @return [void]
  #
  # @api public
  def route_websocket(socket)
    if socket.url == @path
      info 'Reactor handles new socket connection' if debug_enabled?
      reactor = CelluloidPubsub::Reactor.new
      Actor.current.link reactor
      reactor.async.work(socket, Actor.current)
    else
      info "Received invalid WebSocket request for: #{socket.url}" if debug_enabled?
      socket.close
    end
  end

  # If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format
  # otherwise will try send the message how it is and escaped into JSON format
  #
  # @param [CelluloidPubsub::Reactor] reactor The  reactor that received an unhandled message
  # @param [Object] data The message that the reactor could not handle
  #
  # @return [void]
  #
  # @api public
  def handle_dispatched_message(reactor, data)
    debug "Webserver trying to dispatch message  #{data.inspect}" if debug_enabled?
    message = reactor.parse_json_data(data)
    if message.present? && message.is_a?(Hash)
      reactor.websocket << message.to_json
    else
      reactor.websocket << data.to_json
    end
  end
end

- (String) path

Returns The hostname on which the webserver runs on

Returns:

  • (String)

    The hostname on which the webserver runs on



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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/celluloid_pubsub/web_server.rb', line 31

class WebServer < Reel::Server::HTTP
  include Celluloid::Logger

  # The hostname on which the webserver runs on by default
  HOST = '0.0.0.0'
  # The port on which the webserver runs on by default
  PORT = 1234
  # The request path that the webserver accepts by default
  PATH = '/ws'

  attr_accessor :options, :subscribers, :backlog, :hostname, :port, :path, :spy

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  #
  # @return [void]
  #
  # @api public
  def initialize(options = {})
    parse_options(options)
    @subscribers = {}
    info "CelluloidPubsub::WebServer example starting on #{@hostname}:#{@port}" if debug_enabled?
    super(@hostname, @port, { spy: @spy, backlog: @backlog }, &method(:on_connection))
  end

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  # @option options [Integer]:backlog How many connections the server accepts
  #
  # @return [void]
  #
  # @api public
  def parse_options(options)
    raise 'Options is not a hash ' unless options.is_a?(Hash)
    @options = options.stringify_keys
    @backlog = @options.fetch(:backlog, 1024)
    @hostname = @options.fetch(:hostname, CelluloidPubsub::WebServer::HOST)
    @port = @options.fetch(:port, CelluloidPubsub::WebServer::PORT)
    @path = @options.fetch(:path, CelluloidPubsub::WebServer::PATH)
    @spy = @options.fetch(:spy, false)
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def debug_enabled?
    self.class.debug_enabled?
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def self.debug_enabled?
    ENV['DEBUG_CELLULOID'].present? && (ENV['DEBUG_CELLULOID'] == 'true' || ENV['DEBUG_CELLULOID'] == true)
  end

  #  checks if debug is enabled
  #
  # @param [String] current_topic The Channel to which the reactor instance {CelluloidPubsub::Rector} will publish the message to
  # @param [Object] message
  #
  # @return [void]
  #
  # @api public
  def publish_event(current_topic, message)
    return if current_topic.blank? || message.blank?
    @subscribers[current_topic].each do |hash|
      hash[:reactor].websocket << message
    end
  end

  #  callback that will execute when receiving new conections
  # If the connections is a websocket will call method {#route_websocket}
  # and if the connection is HTTP will call method {#route_request}
  # For websocket connections , the connection is detached from the server and dispatched to another actor
  #
  # @see #route_websocket
  # @see #route_request
  #
  # @param [Reel::WebSocket] connection The connection that was made to the webserver
  #
  # @return [void]
  #
  # @api public
  def on_connection(connection)
    while request = connection.request
      if request.websocket?
        info 'Received a WebSocket connection' if debug_enabled?

        # We're going to hand off this connection to another actor (Writer/Reader)
        # However, initially Reel::Connections are "attached" to the
        # Reel::Server::HTTP actor, meaning that the server manages the connection
        # lifecycle (e.g. error handling) for us.
        #
        # If we want to hand this connection off to another actor, we first
        # need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
        connection.detach
        route_websocket(request.websocket)
        return
      else
        route_request connection, request
      end
    end
  end

  #  HTTP connections are not accepted so this method will show 404 message "Not Found"
  #
  # @param [Reel::WebSocket] connection The HTTP connection that was received
  # @param [Reel::Request] request The request that was made to the webserver and contains the type , the url, and the parameters
  #
  # @return [void]
  #
  # @api public
  def route_request(connection, request)
    info "404 Not Found: #{request.path}" if debug_enabled?
    connection.respond :not_found, 'Not found'
  end

  #  If the socket url matches with the one accepted by the server, it will dispatch the socket connection to a new reactor {CelluloidPubsub::Reactor#work}
  # The new actor is linked to the webserver
  #
  # @see CelluloidPubsub::Reactor#work
  #
  #  @param [Reel::WebSocket] socket The  web socket connection that was received
  #
  # @return [void]
  #
  # @api public
  def route_websocket(socket)
    if socket.url == @path
      info 'Reactor handles new socket connection' if debug_enabled?
      reactor = CelluloidPubsub::Reactor.new
      Actor.current.link reactor
      reactor.async.work(socket, Actor.current)
    else
      info "Received invalid WebSocket request for: #{socket.url}" if debug_enabled?
      socket.close
    end
  end

  # If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format
  # otherwise will try send the message how it is and escaped into JSON format
  #
  # @param [CelluloidPubsub::Reactor] reactor The  reactor that received an unhandled message
  # @param [Object] data The message that the reactor could not handle
  #
  # @return [void]
  #
  # @api public
  def handle_dispatched_message(reactor, data)
    debug "Webserver trying to dispatch message  #{data.inspect}" if debug_enabled?
    message = reactor.parse_json_data(data)
    if message.present? && message.is_a?(Hash)
      reactor.websocket << message.to_json
    else
      reactor.websocket << data.to_json
    end
  end
end

- (String) port

Returns The port on which the webserver runs on

Returns:

  • (String)

    The port on which the webserver runs on



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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/celluloid_pubsub/web_server.rb', line 31

class WebServer < Reel::Server::HTTP
  include Celluloid::Logger

  # The hostname on which the webserver runs on by default
  HOST = '0.0.0.0'
  # The port on which the webserver runs on by default
  PORT = 1234
  # The request path that the webserver accepts by default
  PATH = '/ws'

  attr_accessor :options, :subscribers, :backlog, :hostname, :port, :path, :spy

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  #
  # @return [void]
  #
  # @api public
  def initialize(options = {})
    parse_options(options)
    @subscribers = {}
    info "CelluloidPubsub::WebServer example starting on #{@hostname}:#{@port}" if debug_enabled?
    super(@hostname, @port, { spy: @spy, backlog: @backlog }, &method(:on_connection))
  end

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  # @option options [Integer]:backlog How many connections the server accepts
  #
  # @return [void]
  #
  # @api public
  def parse_options(options)
    raise 'Options is not a hash ' unless options.is_a?(Hash)
    @options = options.stringify_keys
    @backlog = @options.fetch(:backlog, 1024)
    @hostname = @options.fetch(:hostname, CelluloidPubsub::WebServer::HOST)
    @port = @options.fetch(:port, CelluloidPubsub::WebServer::PORT)
    @path = @options.fetch(:path, CelluloidPubsub::WebServer::PATH)
    @spy = @options.fetch(:spy, false)
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def debug_enabled?
    self.class.debug_enabled?
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def self.debug_enabled?
    ENV['DEBUG_CELLULOID'].present? && (ENV['DEBUG_CELLULOID'] == 'true' || ENV['DEBUG_CELLULOID'] == true)
  end

  #  checks if debug is enabled
  #
  # @param [String] current_topic The Channel to which the reactor instance {CelluloidPubsub::Rector} will publish the message to
  # @param [Object] message
  #
  # @return [void]
  #
  # @api public
  def publish_event(current_topic, message)
    return if current_topic.blank? || message.blank?
    @subscribers[current_topic].each do |hash|
      hash[:reactor].websocket << message
    end
  end

  #  callback that will execute when receiving new conections
  # If the connections is a websocket will call method {#route_websocket}
  # and if the connection is HTTP will call method {#route_request}
  # For websocket connections , the connection is detached from the server and dispatched to another actor
  #
  # @see #route_websocket
  # @see #route_request
  #
  # @param [Reel::WebSocket] connection The connection that was made to the webserver
  #
  # @return [void]
  #
  # @api public
  def on_connection(connection)
    while request = connection.request
      if request.websocket?
        info 'Received a WebSocket connection' if debug_enabled?

        # We're going to hand off this connection to another actor (Writer/Reader)
        # However, initially Reel::Connections are "attached" to the
        # Reel::Server::HTTP actor, meaning that the server manages the connection
        # lifecycle (e.g. error handling) for us.
        #
        # If we want to hand this connection off to another actor, we first
        # need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
        connection.detach
        route_websocket(request.websocket)
        return
      else
        route_request connection, request
      end
    end
  end

  #  HTTP connections are not accepted so this method will show 404 message "Not Found"
  #
  # @param [Reel::WebSocket] connection The HTTP connection that was received
  # @param [Reel::Request] request The request that was made to the webserver and contains the type , the url, and the parameters
  #
  # @return [void]
  #
  # @api public
  def route_request(connection, request)
    info "404 Not Found: #{request.path}" if debug_enabled?
    connection.respond :not_found, 'Not found'
  end

  #  If the socket url matches with the one accepted by the server, it will dispatch the socket connection to a new reactor {CelluloidPubsub::Reactor#work}
  # The new actor is linked to the webserver
  #
  # @see CelluloidPubsub::Reactor#work
  #
  #  @param [Reel::WebSocket] socket The  web socket connection that was received
  #
  # @return [void]
  #
  # @api public
  def route_websocket(socket)
    if socket.url == @path
      info 'Reactor handles new socket connection' if debug_enabled?
      reactor = CelluloidPubsub::Reactor.new
      Actor.current.link reactor
      reactor.async.work(socket, Actor.current)
    else
      info "Received invalid WebSocket request for: #{socket.url}" if debug_enabled?
      socket.close
    end
  end

  # If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format
  # otherwise will try send the message how it is and escaped into JSON format
  #
  # @param [CelluloidPubsub::Reactor] reactor The  reactor that received an unhandled message
  # @param [Object] data The message that the reactor could not handle
  #
  # @return [void]
  #
  # @api public
  def handle_dispatched_message(reactor, data)
    debug "Webserver trying to dispatch message  #{data.inspect}" if debug_enabled?
    message = reactor.parse_json_data(data)
    if message.present? && message.is_a?(Hash)
      reactor.websocket << message.to_json
    else
      reactor.websocket << data.to_json
    end
  end
end

- (Boolean) spy

Returns Enable this only if you want to enable debugging for the webserver

Returns:

  • (Boolean)

    Enable this only if you want to enable debugging for the webserver



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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/celluloid_pubsub/web_server.rb', line 31

class WebServer < Reel::Server::HTTP
  include Celluloid::Logger

  # The hostname on which the webserver runs on by default
  HOST = '0.0.0.0'
  # The port on which the webserver runs on by default
  PORT = 1234
  # The request path that the webserver accepts by default
  PATH = '/ws'

  attr_accessor :options, :subscribers, :backlog, :hostname, :port, :path, :spy

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  #
  # @return [void]
  #
  # @api public
  def initialize(options = {})
    parse_options(options)
    @subscribers = {}
    info "CelluloidPubsub::WebServer example starting on #{@hostname}:#{@port}" if debug_enabled?
    super(@hostname, @port, { spy: @spy, backlog: @backlog }, &method(:on_connection))
  end

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  # @option options [Integer]:backlog How many connections the server accepts
  #
  # @return [void]
  #
  # @api public
  def parse_options(options)
    raise 'Options is not a hash ' unless options.is_a?(Hash)
    @options = options.stringify_keys
    @backlog = @options.fetch(:backlog, 1024)
    @hostname = @options.fetch(:hostname, CelluloidPubsub::WebServer::HOST)
    @port = @options.fetch(:port, CelluloidPubsub::WebServer::PORT)
    @path = @options.fetch(:path, CelluloidPubsub::WebServer::PATH)
    @spy = @options.fetch(:spy, false)
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def debug_enabled?
    self.class.debug_enabled?
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def self.debug_enabled?
    ENV['DEBUG_CELLULOID'].present? && (ENV['DEBUG_CELLULOID'] == 'true' || ENV['DEBUG_CELLULOID'] == true)
  end

  #  checks if debug is enabled
  #
  # @param [String] current_topic The Channel to which the reactor instance {CelluloidPubsub::Rector} will publish the message to
  # @param [Object] message
  #
  # @return [void]
  #
  # @api public
  def publish_event(current_topic, message)
    return if current_topic.blank? || message.blank?
    @subscribers[current_topic].each do |hash|
      hash[:reactor].websocket << message
    end
  end

  #  callback that will execute when receiving new conections
  # If the connections is a websocket will call method {#route_websocket}
  # and if the connection is HTTP will call method {#route_request}
  # For websocket connections , the connection is detached from the server and dispatched to another actor
  #
  # @see #route_websocket
  # @see #route_request
  #
  # @param [Reel::WebSocket] connection The connection that was made to the webserver
  #
  # @return [void]
  #
  # @api public
  def on_connection(connection)
    while request = connection.request
      if request.websocket?
        info 'Received a WebSocket connection' if debug_enabled?

        # We're going to hand off this connection to another actor (Writer/Reader)
        # However, initially Reel::Connections are "attached" to the
        # Reel::Server::HTTP actor, meaning that the server manages the connection
        # lifecycle (e.g. error handling) for us.
        #
        # If we want to hand this connection off to another actor, we first
        # need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
        connection.detach
        route_websocket(request.websocket)
        return
      else
        route_request connection, request
      end
    end
  end

  #  HTTP connections are not accepted so this method will show 404 message "Not Found"
  #
  # @param [Reel::WebSocket] connection The HTTP connection that was received
  # @param [Reel::Request] request The request that was made to the webserver and contains the type , the url, and the parameters
  #
  # @return [void]
  #
  # @api public
  def route_request(connection, request)
    info "404 Not Found: #{request.path}" if debug_enabled?
    connection.respond :not_found, 'Not found'
  end

  #  If the socket url matches with the one accepted by the server, it will dispatch the socket connection to a new reactor {CelluloidPubsub::Reactor#work}
  # The new actor is linked to the webserver
  #
  # @see CelluloidPubsub::Reactor#work
  #
  #  @param [Reel::WebSocket] socket The  web socket connection that was received
  #
  # @return [void]
  #
  # @api public
  def route_websocket(socket)
    if socket.url == @path
      info 'Reactor handles new socket connection' if debug_enabled?
      reactor = CelluloidPubsub::Reactor.new
      Actor.current.link reactor
      reactor.async.work(socket, Actor.current)
    else
      info "Received invalid WebSocket request for: #{socket.url}" if debug_enabled?
      socket.close
    end
  end

  # If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format
  # otherwise will try send the message how it is and escaped into JSON format
  #
  # @param [CelluloidPubsub::Reactor] reactor The  reactor that received an unhandled message
  # @param [Object] data The message that the reactor could not handle
  #
  # @return [void]
  #
  # @api public
  def handle_dispatched_message(reactor, data)
    debug "Webserver trying to dispatch message  #{data.inspect}" if debug_enabled?
    message = reactor.parse_json_data(data)
    if message.present? && message.is_a?(Hash)
      reactor.websocket << message.to_json
    else
      reactor.websocket << data.to_json
    end
  end
end

- (Hash) subscribers

Returns The hostname on which the webserver runs on

Returns:

  • (Hash)

    The hostname on which the webserver runs on



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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/celluloid_pubsub/web_server.rb', line 31

class WebServer < Reel::Server::HTTP
  include Celluloid::Logger

  # The hostname on which the webserver runs on by default
  HOST = '0.0.0.0'
  # The port on which the webserver runs on by default
  PORT = 1234
  # The request path that the webserver accepts by default
  PATH = '/ws'

  attr_accessor :options, :subscribers, :backlog, :hostname, :port, :path, :spy

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  #
  # @return [void]
  #
  # @api public
  def initialize(options = {})
    parse_options(options)
    @subscribers = {}
    info "CelluloidPubsub::WebServer example starting on #{@hostname}:#{@port}" if debug_enabled?
    super(@hostname, @port, { spy: @spy, backlog: @backlog }, &method(:on_connection))
  end

  #  receives a list of options that are used to configure the webserver
  #
  # @param  [Hash]  options the options that can be used to connect to webser and send additional data
  # @option options [String]:hostname The hostname on which the webserver runs on
  # @option options [Integer] :port The port on which the webserver runs on
  # @option options [String] :path The request path that the webserver accepts
  # @option options [Boolean] :spy Enable this only if you want to enable debugging for the webserver
  # @option options [Integer]:backlog How many connections the server accepts
  #
  # @return [void]
  #
  # @api public
  def parse_options(options)
    raise 'Options is not a hash ' unless options.is_a?(Hash)
    @options = options.stringify_keys
    @backlog = @options.fetch(:backlog, 1024)
    @hostname = @options.fetch(:hostname, CelluloidPubsub::WebServer::HOST)
    @port = @options.fetch(:port, CelluloidPubsub::WebServer::PORT)
    @path = @options.fetch(:path, CelluloidPubsub::WebServer::PATH)
    @spy = @options.fetch(:spy, false)
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def debug_enabled?
    self.class.debug_enabled?
  end

  #  checks if debug is enabled
  #
  # @return [boolean]
  #
  # @api public
  def self.debug_enabled?
    ENV['DEBUG_CELLULOID'].present? && (ENV['DEBUG_CELLULOID'] == 'true' || ENV['DEBUG_CELLULOID'] == true)
  end

  #  checks if debug is enabled
  #
  # @param [String] current_topic The Channel to which the reactor instance {CelluloidPubsub::Rector} will publish the message to
  # @param [Object] message
  #
  # @return [void]
  #
  # @api public
  def publish_event(current_topic, message)
    return if current_topic.blank? || message.blank?
    @subscribers[current_topic].each do |hash|
      hash[:reactor].websocket << message
    end
  end

  #  callback that will execute when receiving new conections
  # If the connections is a websocket will call method {#route_websocket}
  # and if the connection is HTTP will call method {#route_request}
  # For websocket connections , the connection is detached from the server and dispatched to another actor
  #
  # @see #route_websocket
  # @see #route_request
  #
  # @param [Reel::WebSocket] connection The connection that was made to the webserver
  #
  # @return [void]
  #
  # @api public
  def on_connection(connection)
    while request = connection.request
      if request.websocket?
        info 'Received a WebSocket connection' if debug_enabled?

        # We're going to hand off this connection to another actor (Writer/Reader)
        # However, initially Reel::Connections are "attached" to the
        # Reel::Server::HTTP actor, meaning that the server manages the connection
        # lifecycle (e.g. error handling) for us.
        #
        # If we want to hand this connection off to another actor, we first
        # need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
        connection.detach
        route_websocket(request.websocket)
        return
      else
        route_request connection, request
      end
    end
  end

  #  HTTP connections are not accepted so this method will show 404 message "Not Found"
  #
  # @param [Reel::WebSocket] connection The HTTP connection that was received
  # @param [Reel::Request] request The request that was made to the webserver and contains the type , the url, and the parameters
  #
  # @return [void]
  #
  # @api public
  def route_request(connection, request)
    info "404 Not Found: #{request.path}" if debug_enabled?
    connection.respond :not_found, 'Not found'
  end

  #  If the socket url matches with the one accepted by the server, it will dispatch the socket connection to a new reactor {CelluloidPubsub::Reactor#work}
  # The new actor is linked to the webserver
  #
  # @see CelluloidPubsub::Reactor#work
  #
  #  @param [Reel::WebSocket] socket The  web socket connection that was received
  #
  # @return [void]
  #
  # @api public
  def route_websocket(socket)
    if socket.url == @path
      info 'Reactor handles new socket connection' if debug_enabled?
      reactor = CelluloidPubsub::Reactor.new
      Actor.current.link reactor
      reactor.async.work(socket, Actor.current)
    else
      info "Received invalid WebSocket request for: #{socket.url}" if debug_enabled?
      socket.close
    end
  end

  # If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format
  # otherwise will try send the message how it is and escaped into JSON format
  #
  # @param [CelluloidPubsub::Reactor] reactor The  reactor that received an unhandled message
  # @param [Object] data The message that the reactor could not handle
  #
  # @return [void]
  #
  # @api public
  def handle_dispatched_message(reactor, data)
    debug "Webserver trying to dispatch message  #{data.inspect}" if debug_enabled?
    message = reactor.parse_json_data(data)
    if message.present? && message.is_a?(Hash)
      reactor.websocket << message.to_json
    else
      reactor.websocket << data.to_json
    end
  end
end

Class Method Details

+ (boolean) debug_enabled?

checks if debug is enabled

Returns:

  • (boolean)


97
98
99
# File 'lib/celluloid_pubsub/web_server.rb', line 97

def self.debug_enabled?
  ENV['DEBUG_CELLULOID'].present? && (ENV['DEBUG_CELLULOID'] == 'true' || ENV['DEBUG_CELLULOID'] == true)
end

Instance Method Details

- (boolean) debug_enabled?

checks if debug is enabled

Returns:

  • (boolean)


88
89
90
# File 'lib/celluloid_pubsub/web_server.rb', line 88

def debug_enabled?
  self.class.debug_enabled?
end

- (void) handle_dispatched_message(reactor, data)

This method returns an undefined value.

If the message can be parsed into a Hash it will respond to the reactor's websocket connection with the same message in JSON format otherwise will try send the message how it is and escaped into JSON format

Parameters:

  • reactor (CelluloidPubsub::Reactor)

    The reactor that received an unhandled message

  • data (Object)

    The message that the reactor could not handle



194
195
196
197
198
199
200
201
202
# File 'lib/celluloid_pubsub/web_server.rb', line 194

def handle_dispatched_message(reactor, data)
  debug "Webserver trying to dispatch message  #{data.inspect}" if debug_enabled?
  message = reactor.parse_json_data(data)
  if message.present? && message.is_a?(Hash)
    reactor.websocket << message.to_json
  else
    reactor.websocket << data.to_json
  end
end

- (void) on_connection(connection)

This method returns an undefined value.

callback that will execute when receiving new conections If the connections is a websocket will call method #route_websocket and if the connection is HTTP will call method #route_request For websocket connections , the connection is detached from the server and dispatched to another actor

Parameters:

  • connection (Reel::WebSocket)

    The connection that was made to the webserver

See Also:



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/celluloid_pubsub/web_server.rb', line 129

def on_connection(connection)
  while request = connection.request
    if request.websocket?
      info 'Received a WebSocket connection' if debug_enabled?

      # We're going to hand off this connection to another actor (Writer/Reader)
      # However, initially Reel::Connections are "attached" to the
      # Reel::Server::HTTP actor, meaning that the server manages the connection
      # lifecycle (e.g. error handling) for us.
      #
      # If we want to hand this connection off to another actor, we first
      # need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
      connection.detach
      route_websocket(request.websocket)
      return
    else
      route_request connection, request
    end
  end
end

- (void) parse_options(options)

This method returns an undefined value.

receives a list of options that are used to configure the webserver

Parameters:

  • options (Hash)

    the options that can be used to connect to webser and send additional data

Options Hash (options):

  • :hostname (String)

    The hostname on which the webserver runs on

  • :port (Integer)

    The port on which the webserver runs on

  • :path (String)

    The request path that the webserver accepts

  • :spy (Boolean)

    Enable this only if you want to enable debugging for the webserver

  • :backlog (Integer)

    How many connections the server accepts



73
74
75
76
77
78
79
80
81
# File 'lib/celluloid_pubsub/web_server.rb', line 73

def parse_options(options)
  raise 'Options is not a hash ' unless options.is_a?(Hash)
  @options = options.stringify_keys
  @backlog = @options.fetch(:backlog, 1024)
  @hostname = @options.fetch(:hostname, CelluloidPubsub::WebServer::HOST)
  @port = @options.fetch(:port, CelluloidPubsub::WebServer::PORT)
  @path = @options.fetch(:path, CelluloidPubsub::WebServer::PATH)
  @spy = @options.fetch(:spy, false)
end

- (void) publish_event(current_topic, message)

This method returns an undefined value.

checks if debug is enabled

Parameters:

  • current_topic (String)

    The Channel to which the reactor instance Rector will publish the message to

  • message (Object)


109
110
111
112
113
114
# File 'lib/celluloid_pubsub/web_server.rb', line 109

def publish_event(current_topic, message)
  return if current_topic.blank? || message.blank?
  @subscribers[current_topic].each do |hash|
    hash[:reactor].websocket << message
  end
end

- (void) route_request(connection, request)

This method returns an undefined value.

HTTP connections are not accepted so this method will show 404 message “Not Found”

Parameters:

  • connection (Reel::WebSocket)

    The HTTP connection that was received

  • request (Reel::Request)

    The request that was made to the webserver and contains the type , the url, and the parameters



158
159
160
161
# File 'lib/celluloid_pubsub/web_server.rb', line 158

def route_request(connection, request)
  info "404 Not Found: #{request.path}" if debug_enabled?
  connection.respond :not_found, 'Not found'
end

- (void) route_websocket(socket)

This method returns an undefined value.

If the socket url matches with the one accepted by the server, it will dispatch the socket connection to a new reactor Reactor#work The new actor is linked to the webserver



173
174
175
176
177
178
179
180
181
182
183
# File 'lib/celluloid_pubsub/web_server.rb', line 173

def route_websocket(socket)
  if socket.url == @path
    info 'Reactor handles new socket connection' if debug_enabled?
    reactor = CelluloidPubsub::Reactor.new
    Actor.current.link reactor
    reactor.async.work(socket, Actor.current)
  else
    info "Received invalid WebSocket request for: #{socket.url}" if debug_enabled?
    socket.close
  end
end