Class: Ruflet::Server
- Inherits:
-
Object
- Object
- Ruflet::Server
- Includes:
- ConnectionProtocol
- Defined in:
- lib/ruflet/server.rb
Overview
Standalone TCP transport for the Ruflet protocol. The protocol itself lives in Ruflet::ConnectionProtocol and is shared with host-server adapters (e.g. ruflet_rails runs it on the Rails server’s own socket).
Constant Summary collapse
- WEBSOCKET_GUID =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
Instance Attribute Summary collapse
-
#port ⇒ Object
readonly
Returns the value of attribute port.
Instance Method Summary collapse
- #bind_server_socket!(max_attempts: 100) ⇒ Object
-
#initialize(host: "0.0.0.0", port: 8550, &app_block) ⇒ Server
constructor
A new instance of Server.
- #reload_app! ⇒ Object
- #start ⇒ Object
- #stop ⇒ Object
Methods included from ConnectionProtocol
#attach_sender, #before_dispatch_event, #close_connection, #decode_incoming, #disconnect_error?, #fetch_page, #handle_message, #handle_upgraded_socket, #log_connection_error, #normalize_event_data, #normalize_incoming, #on_control_event, #on_invoke_control_method, #on_register_client, #on_update_control, #pseudo_uuid, #remove_session, #reset_mount_state, #resume_session, #run_connection, #send_message, #sender_for, #session_removed, #session_stored
Constructor Details
#initialize(host: "0.0.0.0", port: 8550, &app_block) ⇒ Server
Returns a new instance of Server.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ruflet/server.rb', line 23 def initialize(host: "0.0.0.0", port: 8550, &app_block) @host = host @port = port @app_block = app_block @sessions = {} @sessions_mutex = Mutex.new @connections = {} @connections_mutex = Mutex.new @running = false @server_socket = nil at_exit do begin stop rescue StandardError nil end end end |
Instance Attribute Details
#port ⇒ Object (readonly)
Returns the value of attribute port.
19 20 21 |
# File 'lib/ruflet/server.rb', line 19 def port @port end |
Instance Method Details
#bind_server_socket!(max_attempts: 100) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/ruflet/server.rb', line 56 def bind_server_socket!(max_attempts: 100) requested = @port.to_i candidate = requested attempts = ENV["RUFLET_STRICT_PORT"] == "1" ? 1 : max_attempts attempts.times do begin @server_socket = TCPServer.new(@host, candidate) @port = candidate if @port != requested && ENV["RUFLET_SUPPRESS_SERVER_BANNER"] != "1" warn "Requested port #{requested} is busy; bound to #{@port}" end publish_bound_port! return rescue Errno::EADDRINUSE candidate += 1 end end raise Errno::EADDRINUSE, "Unable to bind port #{requested}" if attempts == 1 raise Errno::EADDRINUSE, "Unable to bind starting at #{requested} after #{max_attempts} attempts" end |
#reload_app! ⇒ Object
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 |
# File 'lib/ruflet/server.rb', line 104 def reload_app! snapshots = @sessions_mutex.synchronize { @sessions.to_a } snapshots.each do |session_key, current_page| ws = @connections_mutex.synchronize { @connections[session_key] } next unless ws refreshed_page = Page.new( session_id: current_page.session_id, client_details: current_page.client_details, sender: lambda do |action, payload| (ws, action, payload) end ) refreshed_page.title = "Ruflet App" @sessions_mutex.synchronize do @sessions[session_key] = refreshed_page end @app_block.call(refreshed_page) refreshed_page.update rescue StandardError => e warn "reload error: #{e.class}: #{e.}" end end |
#start ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/ruflet/server.rb', line 43 def start previous_signals = trap_stop_signals bind_server_socket! @running = true accept_loop rescue Interrupt nil ensure stop restore_stop_signals(previous_signals) end |
#stop ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/ruflet/server.rb', line 80 def stop return unless @running || @server_socket @running = false remove_port_file! server = @server_socket @server_socket = nil begin server&.close rescue IOError nil end live_connections = @connections_mutex.synchronize { @connections.values.dup } live_connections.each do |conn| begin conn.close rescue StandardError nil end end end |