Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/async/cable/socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ def transmit(data)
@output.push(@coder.encode(data))
end

# Enqueue an already-encoded message for asynchronous delivery to the client, bypassing the coder. Useful for "fastlane" broadcasts where the payload is encoded once and shared across many connections.
# @parameter data [String] The pre-encoded message to transmit.
def raw_transmit(data)
@output.push(data)
end

# Close the outbound queue, causing the drain task to terminate once all pending messages have been sent.
def close
# Console.info(self, "Closing socket.", task: Async::Task.current?)
Expand Down
4 changes: 4 additions & 0 deletions releases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Releases

## Unreleased

- Add {ruby Async::Cable::Socket#raw_transmit} for pushing pre-encoded payloads to the client without re-encoding. Enables "fastlane" broadcasts that encode the message once and share it across many connections.

## v0.3.0

- Filter requests based on path - don't eat all inbound WebSocket connections.
Expand Down
23 changes: 23 additions & 0 deletions test/async/cable/socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,29 @@ def fake_application.env_config; {"rails.test" => true}; end
end
end

with "#transmit" do
it "encodes data using the coder before enqueueing it" do
socket.transmit({type: "ping"})
expect(socket.instance_variable_get(:@output).pop).to be == ActiveSupport::JSON.encode({type: "ping"})
end
end

with "#raw_transmit" do
it "enqueues the data verbatim without encoding it" do
payload = ActiveSupport::JSON.encode({type: "ping"})
socket.raw_transmit(payload)
expect(socket.instance_variable_get(:@output).pop).to be_equal(payload)
end

it "cannot raw_transmit after close" do
socket.close

expect do
socket.raw_transmit("already encoded")
end.to raise_exception(ClosedQueueError)
end
end

with "#run" do
include Sus::Fixtures::Async::ReactorContext

Expand Down
Loading