async-websocket

repository·main·Indexed 41 days ago

https://github.com/socketry/async-websocket

An asynchronous WebSocket client and server implementation for Ruby supporting HTTP/1 and HTTP/2. It provides adapters for seamless integration with the Rails web framework and Rack, and is designed for high-performance communication using a fiber-per-request architecture, particularly when paired with the Falcon web server.

Tokens
7.7K
Snippets
35
Records
42
Agent score
46%

What's inside async-websocket

  1. Overview of Async::WebSocket

    main
    Async::WebSocket is an asynchronous WebSocket client and server implementation designed to work with both HTTP/1 and HTTP/2 protocols. It is built to leverage asynchronous I/O for high-performance WebSocket communication.
  2. Getting Started with Async::WebSocket

    main
    To implement a basic WebSocket client and server, refer to the official Getting Started guide. This guide provides the foundational steps for setting up both sides of a WebSocket connection using the async-websocket library.
  3. Integrate Async::WebSocket with Rails

    main
    Async::WebSocket can be integrated into Rails applications. Detailed instructions for Rails integration, including handling specific requirements like CSRF token considerations for WebSocket clients, are available in the official Rails Integration guide.
  4. Optimize Fiber performance

    main

    To improve fiber performance when scaling to a high number of connections, you can tune the Ruby VM environment variables. Note that RUBY_SHARED_FIBER_POOL_FREE_STACKS is an experimental feature available on ruby-head.

    Set the following environment variables:

    export RUBY_FIBER_VM_STACK_SIZE=0
    export RUBY_FIBER_MACHINE_STACK_SIZE=0
    export RUBY_SHARED_FIBER_POOL_FREE_STACKS=0
  5. Implement a WebSocket controller in Rails

    main

    To handle WebSocket connections in a Rails controller, use Async::WebSocket::Adapters::Rails.open(request).

    Important: Because WebSocket clients may not send CSRF tokens, you must disable the authenticity token verification for the specific action handling the WebSocket connection using skip_before_action :verify_authenticity_token.

    require 'async/websocket/adapters/rails'
    
    class HomeController < ApplicationController
      # WebSocket clients may not send CSRF tokens, so we need to disable this check.
      skip_before_action :verify_authenticity_token, only: [:index]
      
      def index
        self.response = Async::WebSocket::Adapters::Rails.open(request) do |connection|
          message = Protocol::WebSocket::TextMessage.generate({message: "Hello World"})
          connection.write(message)
        end
      end
    end
  6. Use Falcon as the Rails server for WebSockets

    main

    The default Puma server is limited by its thread pool, which can be exhausted by many concurrent WebSocket connections. For high-concurrency WebSocket handling, use Falcon, which utilizes a fiber-per-request architecture.

    To switch, remove Puma and add Falcon:

    bundle remove puma
    bundle add falcon
    $ bundle remove puma
    $ bundle add falcon
  7. Force an HTTP/1.1 Connection for WebSockets

    main

    If a server advertises HTTP/2 but does not support WebSocket connections over HTTP/2, you can force the client to use HTTP/1.1 by passing alpn_protocols: Async::HTTP::Protocol::HTTP11.names to the Async::HTTP::Endpoint.parse method.

    endpoint = Async::HTTP::Endpoint.parse("https://remote-server.com", alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
    
    Async::WebSocket::Client.connect(endpoint) do |connection|
      # ...
    end