Class: DuoRuby::Socket
- Includes:
- Transport
- Defined in:
- lib/duoruby/socket.rb,
lib/duoruby/socket/transport.rb,
lib/duoruby/socket/test_promise.rb
Overview
Browser-side event hub. Manages the WebSocket connection and message dispatch.
Socket inherits the full Channel event system. Declare handlers at the class level (inherited by subclasses) or add them at runtime on an instance.
Unlike server handlers, Socket event handlers receive only the message params as keyword arguments — there is no client positional argument because there is exactly one connection per browser socket instance.
A transport callable (proc or block) is responsible for delivering outbound messages. Under Opal it is set automatically by Transport#connect; in tests you can supply any callable at construction time.
Defined Under Namespace
Modules: Transport Classes: TestPromise
Instance Attribute Summary collapse
-
#sent ⇒ Array<Hash>
readonly
Every message sent through this socket, for inspection.
-
#socket ⇒ Browser::Socket?
readonly
The active WebSocket, or nil before Transport#connect.
Attributes inherited from Channel
Class Method Summary collapse
Instance Method Summary collapse
- #cancel_pending_calls(code: :disconnect, message: "connection closed", details: nil) ⇒ Object
- #deliver(message) ⇒ Object
-
#initialize(transport: nil) {|message| ... } ⇒ Socket
constructor
A new instance of Socket.
-
#receive(message) ⇒ self
Opens the WebSocket connection and wires socket lifecycle events.
-
#send(event, **params) ⇒ Hash, PromiseV2
Sends
eventwithparamsto the server. - #transport=(transport) ⇒ Object
Methods included from Transport
#connect, included, #open_socket, #reconnect
Methods inherited from Channel
#channel, #dispatch, #handler_for, inherited, #off, #on, #one
Methods included from Channel::HandlerMethods
#channel, #handlers, included, #included, #off, #on, #one
Constructor Details
#initialize(transport: nil) {|message| ... } ⇒ Socket
Returns a new instance of Socket.
48 49 50 51 52 53 54 |
# File 'lib/duoruby/socket.rb', line 48 def initialize(transport: nil, &transport_block) super() @transport = transport || transport_block @sent = [] @pending_calls = {} @next_call_id = 0 end |
Instance Attribute Details
#sent ⇒ Array<Hash> (readonly)
Returns every message sent through this socket, for inspection.
39 40 41 |
# File 'lib/duoruby/socket.rb', line 39 def sent @sent end |
#socket ⇒ Browser::Socket? (readonly)
Returns the active WebSocket, or nil before DuoRuby::Socket::Transport#connect.
42 43 44 |
# File 'lib/duoruby/socket.rb', line 42 def socket @socket end |
Class Method Details
.promise_class ⇒ Object
121 122 123 |
# File 'lib/duoruby/socket.rb', line 121 def self.promise_class defined?(::PromiseV2) ? ::PromiseV2 : TestPromise end |
Instance Method Details
#cancel_pending_calls(code: :disconnect, message: "connection closed", details: nil) ⇒ Object
114 115 116 117 118 119 |
# File 'lib/duoruby/socket.rb', line 114 def cancel_pending_calls(code: :disconnect, message: "connection closed", details: nil) error = ReplyError.new(code: code, message: , details: details) @pending_calls.each_value { |promise| promise.reject(error) } @pending_calls.clear self end |
#deliver(message) ⇒ Object
108 109 110 111 112 |
# File 'lib/duoruby/socket.rb', line 108 def deliver() sent << @transport.call() if @transport end |
#receive(message) ⇒ self
Opens the WebSocket connection and wires socket lifecycle events.
Only available under Opal (requires Browser::Socket). Raises immediately on CRuby. Raises if already connected.
Sets up a JSON-serialising transport and forwards:
-
socket
:open→ triggers :$connect -
socket
:message→ calls #receive with the parsed JSON payload -
socket
:close→ triggers :$disconnect
Coerces message and dispatches it to the appropriate event handlers. Params are forwarded as keyword arguments only (no positional client arg).
94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/duoruby/socket.rb', line 94 def receive() = Message.coerce() return resolve_call() if .event == Message::REPLY_EVENT return reject_call() if .event == Message::ERROR_EVENT && .reply_to results = dispatch(.event, **.params) deliver(Message.reply(.id, results.last).to_h) if .id results rescue StandardError => error raise unless &.id deliver(Message.error(code: error.class.name, message: error., reply_to: .id).to_h) end |
#send(event, **params) ⇒ Hash, PromiseV2
Sends event with params to the server.
Events ending with ? are questions: they include a request id and return a promise that resolves when the server replies. Other events are fire-and-forget and return the serialized message hash.
65 66 67 68 69 |
# File 'lib/duoruby/socket.rb', line 65 def send(event, **params) return send_question(event, **params) if question_event?(event) deliver(Message.new(event, **params).to_h) end |
#transport=(transport) ⇒ Object
71 72 73 |
# File 'lib/duoruby/socket.rb', line 71 def transport=(transport) @transport = transport end |