async-websocket
repository·main·Indexed 41 days ago
https://github.com/socketry/async-websocketAn 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.
What's inside async-websocket
- 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.
Getting Started with Async::WebSocket
mainTo 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 theasync-websocketlibrary.Integrate Async::WebSocket with Rails
mainAsync::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.Use Falcon for high-concurrency WebSockets in Rails
mainThe default Rails server (Puma) uses a thread-per-request model which is unsuitable for large numbers of WebSocket connections. For better scalability, replace Puma with Falcon, which uses a fiber-per-request architecture.
To switch, remove Puma and add Falcon:
$ bundle remove puma $ bundle add falconRun the test suite
mainTo execute the project's test suite, use the
suscommand viabundle exec.bundle exec susInstall async-websocket via Bundler
mainAdd the
async-websocketgem to your project using Bundler to begin using the library for WebSocket client and server implementations.$ bundle add async-websocketOptimize Fiber performance
mainTo 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_STACKSis an experimental feature available onruby-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=0Implement a WebSocket controller in Rails
mainTo 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 endUse Falcon as the Rails server for WebSockets
mainThe 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 falconSetup Async::WebSocket in a new Rails project
mainTo set up a new project with
async-websocketsupport, create a new Rails application and add the gem via Bundler:rails new websockets cd websockets bundle add async-websocket$ rails new websockets $ bundle add async-websocketForce an HTTP/1.1 Connection for WebSockets
mainIf a server advertises
HTTP/2but does not support WebSocket connections overHTTP/2, you can force the client to useHTTP/1.1by passingalpn_protocols: Async::HTTP::Protocol::HTTP11.namesto theAsync::HTTP::Endpoint.parsemethod.endpoint = Async::HTTP::Endpoint.parse("https://remote-server.com", alpn_protocols: Async::HTTP::Protocol::HTTP11.names) Async::WebSocket::Client.connect(endpoint) do |connection| # ... endSet up async-websocket in a Rails project
mainTo integrate
async-websocketinto a Rails application, add the gem to your bundle usingbundle add async-websocket.$ bundle add async-websocket