### Install async-cable Gem Source: https://github.com/socketry/async-cable/blob/main/guides/getting-started/readme.md Installs the async-cable gem into your project. This is a prerequisite for using the library. ```bash $ bundle add async-cable ``` -------------------------------- ### Run Falcon Server Benchmark Source: https://github.com/socketry/async-cable/blob/main/benchmark/readme.md Starts a Falcon server for benchmarking purposes. Ensure all dependencies are installed before running. This script is typically executed from the benchmark/servers directory. ```shell cd benchmark/servers bundle exec ./falcon.rb ``` -------------------------------- ### Configure async-cable in Rails Application Source: https://github.com/socketry/async-cable/blob/main/guides/getting-started/readme.md Adds the Async::Cable::Middleware to your Rails application's middleware stack. This enables automatic handling of WebSocket connections and integration with Action Cable. ```ruby require 'async/cable' ``` -------------------------------- ### Manage WebSocket Client Connection with Async::Cable::Socket Source: https://context7.com/socketry/async-cable/llms.txt This snippet illustrates the internal usage of `Async::Cable::Socket` for wrapping async-websocket connections. It covers initializing the socket, establishing an ActionCable connection, transmitting data to clients, and gracefully closing the socket. The `socket.run` method starts a background fiber for asynchronous message flushing. ```ruby # Internal usage (handled by middleware) socket = Async::Cable::Socket.new(env, websocket, server, coder: ActiveSupport::JSON) connection = server.config.connection_class.call.new(server, socket) # Transmit data to client socket.transmit({type: "welcome", sid: "session-123"}) # Close socket gracefully socket.close # The socket runs an async task for outbound messages: socket.run # Starts background fiber that flushes queued messages ``` -------------------------------- ### Define ActionCable Channel for Real-time Communication Source: https://context7.com/socketry/async-cable/llms.txt This example shows how to define a custom ActionCable channel for real-time communication. It includes methods for subscribing to streams, echoing messages back to the client, and broadcasting messages to subscribed clients. Client-side JavaScript usage is also illustrated. ```ruby # app/channels/benchmark_channel.rb class BenchmarkChannel < ApplicationCable::Channel def subscribed stream_from "all#{stream_id}" end def echo(data) transmit data end def broadcast(data) ActionCable.server.broadcast "all#{stream_id}", data end private def stream_id params[:id] || "" end end # Client-side JavaScript usage: # const cable = ActionCable.createConsumer('ws://localhost:8080/cable') # const subscription = cable.subscriptions.create( # { channel: 'BenchmarkChannel', id: '123' }, # { # received(data) { console.log('Received:', data) }, # connected() { console.log('Connected') }, # disconnected() { console.log('Disconnected') } # } # ) # subscription.perform('echo', { message: 'Hello World' }) ``` -------------------------------- ### Broadcast Messages to All Subscribed Clients Source: https://context7.com/socketry/async-cable/llms.txt This example demonstrates how to broadcast messages from the server-side to all clients subscribed to a specific stream. The messages are queued and asynchronously flushed to all connected clients, enabling real-time updates across the application. ```ruby # Broadcast from anywhere in your Rails app ActionCable.server.broadcast("notifications:user:#{user.id}", { type: "notification", title: "New Message", body: "You have a new message", timestamp: Time.now.iso8601 }) ``` -------------------------------- ### Configure ActionCable Server Settings Source: https://context7.com/socketry/async-cable/llms.txt This code shows how to configure ActionCable server settings, including the adapter type (e.g., 'async', 'redis'), connection class, and security policies like allowed request origins. It also demonstrates setting up connection identification based on user authentication. ```ruby # config/initializers/action_cable.rb ActionCable.server.config.cable = { "adapter" => "async", # or "redis", "postgresql" "url" => ENV["REDIS_URL"] } ActionCable.server.config.connection_class = -> { ApplicationCable::Connection } ActionCable.server.config.disable_request_forgery_protection = false ActionCable.server.config.allowed_request_origins = [ "http://example.com", /https:\/\/.*\.example\.com/ ] ActionCable.server.config.allow_same_origin_as_host = true ActionCable.server.config.logger = Rails.logger # Connection with identified_by module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :uid def connect self.uid = find_verified_user end private def find_verified_user cookies.signed[:user_id] || reject_unauthorized_connection end end end ``` -------------------------------- ### Programmatic WebSocket Client Connection (Ruby) Source: https://context7.com/socketry/async-cable/llms.txt This Ruby code demonstrates how to establish a programmatic WebSocket client connection using async-websocket. It includes subscribing to a channel, sending a message, and reading the response, suitable for testing or building Ruby-based ActionCable clients. ```ruby require "async" require "async/http/endpoint" require "async/websocket" IDENTIFIER = {channel: "BenchmarkChannel", id: "test"}.to_json SUBSCRIBE_MESSAGE = Protocol::WebSocket::TextMessage.generate( command: "subscribe", identifier: IDENTIFIER ) Async do endpoint = Async::HTTP::Endpoint.parse("http://localhost:8080/cable") connection = Async::WebSocket::Client.connect(endpoint) # Subscribe to channel SUBSCRIBE_MESSAGE.send(connection) connection.flush # Wait for confirmation while message = connection.read parsed = message.parse break if parsed[:type] == "confirm_subscription" end # Send message to channel message = Protocol::WebSocket::TextMessage.generate( command: "message", identifier: IDENTIFIER, data: {action: "echo", payload: "Hello World"}.to_json ) message.send(connection) connection.flush # Read response response = connection.read puts response.parse # => {identifier: ..., message: {...}} connection.shutdown ensure connection.close end ``` -------------------------------- ### Benchmark Testing for ActionCable (Ruby) Source: https://context7.com/socketry/async-cable/llms.txt This Ruby script measures ActionCable performance by creating a specified number of concurrent WebSocket connections and broadcasting messages. It uses async-websocket and Async::Clock for benchmarking connection and broadcast rates, useful for capacity planning. ```ruby # benchmark/broadcast.rb require "async" require "async/http/endpoint" require "async/websocket" CONNECTION_COUNT = 1000 BROADCAST_COUNT = 20 IDENTIFIER = {channel: "BenchmarkChannel"}.to_json def connect(endpoint, count: 100, parent: Async::Task.current) count.times.map do parent.async do connection = Async::WebSocket::Client.connect(endpoint) subscribe = Protocol::WebSocket::TextMessage.generate( command: "subscribe", identifier: IDENTIFIER ) subscribe.send(connection) connection.flush while message = connection.read break if message.parse[:type] == "confirm_subscription" end connection end end.map(&:wait) end def broadcast(connections, data, count: 10, parent: Async::Task.current) message = Protocol::WebSocket::TextMessage.generate( command: "message", identifier: IDENTIFIER, data: data.to_json ) parent.async do count.times do message.send(connections.first) connections.first.flush end end connections.map do |conn| parent.async do count.times do while msg = conn.read break if msg.parse[:identifier] == IDENTIFIER end end end end.map(&:wait) end Async do endpoint = Async::HTTP::Endpoint.parse("http://localhost:8080/cable") duration = Async::Clock.measure do connections = connect(endpoint, count: CONNECTION_COUNT) end puts "Connected #{CONNECTION_COUNT} clients in #{duration}s" puts "Rate: #{(CONNECTION_COUNT / duration).round(2)} clients/s" duration = Async::Clock.measure do broadcast(connections, {action: "broadcast", payload: "Hello"}, count: BROADCAST_COUNT) end puts "Broadcast #{BROADCAST_COUNT}x to #{CONNECTION_COUNT} clients in #{duration}s" puts "Rate: #{(CONNECTION_COUNT * BROADCAST_COUNT / duration).round(2)} broadcasts/s" end ``` -------------------------------- ### Configure Async::Cable Middleware in Rails Source: https://context7.com/socketry/async-cable/llms.txt This code demonstrates how to automatically integrate Async::Cable middleware into a Rails application. It ensures WebSocket requests on the '/cable' path are handled asynchronously. The middleware manages request origin validation, connection lifecycle, and message processing. ```ruby # config/application.rb - Automatic integration via Railtie require "async/cable" class Application < Rails::Application # Middleware is automatically added by Async::Cable::Railtie # Manual configuration (optional): config.middleware.use Async::Cable::Middleware, path: "/cable", server: ActionCable.server end # The middleware automatically handles: # - WebSocket upgrade on the /cable path # - Request origin validation # - Connection lifecycle (open, message processing, close) # - Error handling and abnormal disconnections ``` -------------------------------- ### Run Broadcast Benchmark Script Source: https://github.com/socketry/async-cable/blob/main/benchmark/readme.md Executes the broadcast benchmark script to measure connection and broadcast times. This script requires the server to be running and measures performance metrics like connection speed and broadcast efficiency. ```shell bundle exec ./broadcast.rb ``` -------------------------------- ### Broadcast from a Channel Action (Ruby) Source: https://context7.com/socketry/async-cable/llms.txt This Ruby code defines a ChatChannel that subscribes to a specific chat room and handles sending and broadcasting messages within that room. It uses ActionCable for server-side WebSocket communication. ```ruby class ChatChannel < ApplicationCable::Channel def subscribed stream_from "chat:room:#{params[:room_id]}" end def send_message(data) message = Message.create!( room_id: params[:room_id], user_id: current_user.id, content: data["message"] ) ActionCable.server.broadcast("chat:room:#{params[:room_id]}", { id: message.id, user: current_user.name, content: message.content, created_at: message.created_at.iso8601 }) end end ``` -------------------------------- ### Configure WebSocket Endpoint Path (Ruby) Source: https://context7.com/socketry/async-cable/llms.txt This Ruby code configures the Async::Cable middleware to use a custom path for WebSocket endpoints, preventing it from intercepting all connections. This allows for multiple WebSocket endpoints within the same application. ```ruby # config/application.rb class Application < Rails::Application # Custom cable path config.middleware.use Async::Cable::Middleware, path: "/websocket" end # The middleware validates paths before upgrading connections: # GET /cable -> Handled by Async::Cable if path matches # GET /other-ws -> Passed through to next middleware # GET /api/data -> Passed through to Rails routes # Client connects to custom path: # const cable = ActionCable.createConsumer('ws://localhost:3000/websocket') ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.