### Start AnyCable-Go with Memory Broker Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/reliable_streams.md Manually configure AnyCable-Go to use the 'memory' broker adapter. This is a basic setup for reliable streams. ```sh $ anycable-go --broker=memory INFO 2023-04-14T00:31:55.548Z context=main Starting AnyCable 1.4.0-d8939df (with mruby 1.2.0 (2015-11-17)) (pid: 87410, open file limit: 122880, gomaxprocs: 8) INFO 2023-04-14T00:31:55.548Z context=main Using in-memory broker (epoch: vRXl, history limit: 100, history ttl: 300s, sessions ttl: 300s) ... ``` -------------------------------- ### Install Dependencies and Start Dev Server Source: https://github.com/anycable/docs.anycable.io/blob/master/README.md Install project dependencies and start the VitePress development server with hot reload. Ensure Node.js is installed and navigate to the 'docs/' directory. ```sh cd docs # Install dependencies npm install # Start the dev server with hot reload npm run dev ``` -------------------------------- ### Install AnyCable-Go with Homebrew Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/getting_started.md Use Homebrew to install the AnyCable-Go binary on macOS. ```sh brew install anycable-go ``` -------------------------------- ### Start AnyCable-Go with Redis Broker Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/reliable_streams.md Configure AnyCable-Go to use Redis as the broker adapter for multi-node installations. This requires Redis to be running and accessible. ```sh $ anycable-go --broker=redis INFO 2023-07-08T00:46:55.491Z context=main Starting AnyCable 1.6.0-pro-eed05bc (with mruby 1.2.0 (2015-11-17)) (pid: 78585, open file limit: 122880, gomaxprocs: 8, netpoll: true) INFO 2023-07-08T00:46:55.492Z context=main Using Redis broker at localhost:6379 (history limit: 100, history ttl: 300s, sessions ttl: 300s, presence ttl: 15s) ... ``` -------------------------------- ### Install AnyCable JS SDK Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/guides/client-side.md Install the AnyCable JS SDK using npm, yarn, or pnpm. Use `@anycable/web` for browser environments and `@anycable/core` for non-web environments like Node.js. ```bash npm install @anycable/web yarn add @anycable/web pnpm install @anycable/web ``` -------------------------------- ### Run AnyCable-Go Locally Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/guides/serverless.md After installation, execute the AnyCable-Go binary using npx. The binary is downloaded automatically on the first run. ```sh npx anycable-go ``` -------------------------------- ### Run AnyCable Setup Wizard Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/getting_started.md Execute the Rails generator to initiate the interactive configuration wizard for AnyCable. ```sh bin/rails g anycable:setup ``` -------------------------------- ### Metrics Log Example Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/instrumentation.md This is an example of the log output when metrics logging is enabled. ```sh INFO 2018-03-06T14:16:27.872Z broadcast_msg_total=0 broadcast_streams_num=0 client_msg_total=0 clients_num=0 clients_uniq_num=0 context=metrics disconnect_queue_size=0 failed_auths_total=0 failed_broadcast_msg_total=0 failed_client_msg_total=0 goroutines_num=35 rpc_call_total=0 rpc_error_total=0 ``` -------------------------------- ### Install AnyCable-Go with NPM, PNPM, or Yarn Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/guides/serverless.md Use these commands to install the AnyCable-Go NPM package as a development dependency. The package version matches the AnyCable-Go binary version. ```sh npm install --save-dev @anycable/anycable-go ``` ```sh pnpm install --save-dev @anycable/anycable-go ``` ```sh yarn add --dev @anycable/anycable-go ``` -------------------------------- ### Action Cable over SSE Message Format Example Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/sse.md Illustrates the structure of messages exchanged between the server and client over SSE. Differentiates between GET and POST connection payloads and includes event types like welcome, confirm_subscription, ping, disconnect, and data messages with IDs. ```txt event: welcome data: {"type":"welcome"} event: confirm_subscription data: {"type":"confirm_subscription","identifier":"{\"channel\":\"ChatChannel\"}"} event: ping data: {"type":"ping","message":1694041735} data: {"message":"hello"} id: 1/chat_42/y2023 data: {"message":"good-bye"} id: 2/chat_42/y2023 data: {"identifier":"{\"channel\":\"ChatChannel\"}","message":{"message":"hello"}} id: 1/chat_42/y2023 data: {"identifier":"{\"channel\":\"ChatChannel\"}","message":{"message":"good-bye"}} id: 2/chat_42/y2023 event: ping data: {"type":"ping","message":1694044435} event: disconnect data: {"type":"disconnect","reason":"remote","reconnect":false} retry: 31536000000 ``` -------------------------------- ### Install AnyCable-Go via NPM Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/getting_started.md Install AnyCable-Go as a development dependency for JavaScript projects using npm, pnpm, or yarn. The NPM package version matches the server binary version. ```sh npm install --save-dev @anycable/anycable-go ``` ```sh pnpm install --save-dev @anycable/anycable-go ``` ```sh yarn add --dev @anycable/anycable-go ``` ```sh npx anycable-go ``` -------------------------------- ### Librato-Compatible Log Output Example Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/instrumentation.md This is an example of the log output when using the Librato-compatible mruby metrics formatter. ```sh INFO 2018-04-27T14:11:59.701Z sample#clients_num=0 sample#clients_uniq_num=0 sample#goroutines_num=0 ``` -------------------------------- ### Add AnyCable Server to Procfile.dev Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/getting_started.md Include commands to start the AnyCable server in your Procfile.dev for development, specifying the RPC mode. ```sh web: bin/rails s # ... ws: anycable-go # When using gRPC rpc: bundle exec anycable ``` -------------------------------- ### Install anycable-laravel Broadcaster Package Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/guides/laravel.md Install the AnyCable Laravel broadcaster package using Composer to enable AnyCable as a broadcasting backend. ```sh composer require anycable/laravel-broadcaster ``` -------------------------------- ### Ephemeral Channel State Example (Action Cable) Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/channels_state.md This example demonstrates a common pattern in Action Cable where instance variables are expected to persist. In AnyCable, this pattern fails because channel instances are recreated for each request. ```ruby class RoomChannel < ApplicationCable::Channel def subscribed @room = Room.find(params["room_id"]) stream_for @room end def speak(data) broadcast_to @room, message: data["text"] end end ``` -------------------------------- ### Log Preset Detection Example Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/configuration.md This log message indicates that AnyCable-Go has automatically loaded configuration presets for a specific deployment environment. ```sh INFO ... context=config Loaded presets: fly ``` -------------------------------- ### Example AnyCable-Go Logs Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/tracing.md These log entries show session IDs (sid) and context for incoming messages and pub/sub events. ```sh D 2019-04-25T18:41:07.172Z context=node sid=FQQS_IltswlTJK60ncf9Cm Incoming message: &{subscribe {"channel":"PresenceChannel"} } D 2019-04-25T18:41:08.074Z context=pubsub Incoming pubsub message from Redis: {"stream":"presence:Z2lkOi8vbWFuYWdlYmFjL1NjaG9vbC8xMDAwMjI3Mw","data":"{\"type\":\"presence\",\"event\":\"user-presence-changed\",\"user_id\":1,\"status\":\"online\"}"} ``` -------------------------------- ### Run AnyCable-Go in Standalone Public Mode Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/getting_started.md Start AnyCable-Go in an insecure standalone mode for pub/sub functionality. This enables `--noauth` and `--public_streams`. Use with caution. ```sh $ anycable-go --public 2024-03-06 14:00:12.549 INF Starting AnyCable 1.6.0-4f16b99 (pid: 17817, open file limit: 122880, gomaxprocs: 8) nodeid=wAhWDB 2024-03-06 14:00:12.549 WRN Server is running in the public mode nodeid=wAhWDB ... ``` -------------------------------- ### Start AnyCable gRPC Server Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/ruby/cli.md Use the `anycable` CLI to start the gRPC server. Specify your application code using the `--require` option. For Rails applications, this is often not needed as AnyCable checks for standard configuration files. ```sh $ bundle exec anycable --require "./path/to/app.rb" #> Starting AnyCable gRPC server (pid: 85746, workers_num: 30) #> AnyCable version: 1.5.0 #> gRPC version: 1.57.0 #> Serving Rails application from ./path/to/app.rb ... #> ... ``` -------------------------------- ### Prometheus Metrics Output Example Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/instrumentation.md Example output of the Prometheus metrics endpoint, showing various AnyCable-Go metrics like active clients, message counts, and RPC statistics. ```prometheus # HELP anycable_go_clients_num The number of active clients # TYPE anycable_go_clients_num gauge anycable_go_clients_num 0 # HELP anycable_go_clients_uniq_num The number of unique clients (with respect to connection identifiers) # TYPE anycable_go_clients_uniq_num gauge anycable_go_clients_uniq_num 0 # HELP anycable_go_client_msg_total The total number of received messages from clients # TYPE anycable_go_client_msg_total counter anycable_go_client_msg_total 5906 # HELP anycable_go_failed_client_msg_total The total number of unrecognized messages received from clients # TYPE anycable_go_failed_client_msg_total counter anycable_go_failed_client_msg_total 0 # HELP anycable_go_broadcast_msg_total The total number of messages received through PubSub (for broadcast) # TYPE anycable_go_broadcast_msg_total counter anycable_go_broadcast_msg_total 956 # HELP anycable_go_failed_broadcast_msg_total The total number of unrecognized messages received through PubSub # TYPE anycable_go_failed_broadcast_msg_total counter anycable_go_failed_broadcast_msg_total 0 # HELP anycable_go_broadcast_streams_num The number of active broadcasting streams # TYPE anycable_go_broadcast_streams_num gauge anycable_go_broadcast_streams_num 0 # HELP anycable_go_rpc_call_total The total number of RPC calls # TYPE anycable_go_rpc_call_total counter anycable_go_rpc_call_total 15808 # HELP anycable_go_rpc_error_total The total number of failed RPC calls # TYPE anycable_go_rpc_error_total counter anycable_go_rpc_error_total 0 # HELP anycable_go_rpc_retries_total The total number of RPC call retries # TYPE anycable_go_rpc_retries_total counter anycable_go_rpc_retries_total 0 # HELP anycable_go_rpc_pending_num The number of pending RPC calls # TYPE anycable_go_rpc_pending_num gauge anycable_go_rpc_pending_num 0 # HELP anycable_go_failed_auths_total The total number of failed authentication attempts # TYPE anycable_go_failed_auths_total counter anycable_go_failed_auths_total 0 # HELP anycable_go_goroutines_num The number of Go routines # TYPE anycable_go_goroutines_num gauge anycable_go_goroutines_num 5222 # HELP anycable_go_disconnect_queue_size The size of delayed disconnect # TYPE anycable_go_disconnect_queue_size gauge anycable_go_disconnect_queue_size 0 # HELP anycable_go_server_msg_total The total number of messages sent to clients # TYPE anycable_go_server_msg_total counter anycable_go_server_msg_total 453 # HELP anycable_go_failed_server_msg_total The total number of messages failed to send to clients # TYPE anycable_go_failed_server_msg_total counter anycable_go_failed_server_msg_total 0 # HELP anycable_go_data_sent_total The total amount of bytes sent to clients # TYPE anycable_go_data_sent_total counter anycable_go_data_sent_total 1232434334 # HELP anycable_go_data_rcvd_total The total amount of bytes received from clients ``` -------------------------------- ### Start AnyCable-Go with Broker Preset Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/reliable_streams.md Use the 'broker' preset for AnyCable-Go to enable reliable streams and resumable sessions. This preset configures an in-memory broker with default history and session TTLs. ```sh $ anycable-go --presets=broker INFO 2023-04-14T00:31:55.548Z context=main Starting AnyCable 1.4.0-d8939df (with mruby 1.2.0 (2015-11-17)) (pid: 87410, open file limit: 122880, gomaxprocs: 8) INFO 2023-04-14T00:31:55.548Z context=main Using in-memory broker (epoch: vRXl, history limit: 100, history ttl: 300s, sessions ttl: 300s) INFO 2023-04-18T20:46:00.693Z context=pubsub Starting Redis pub/sub: localhost:6379 INFO 2023-04-19T16:22:55.776Z context=pubsub provider=http Accept broadcast requests at http://localhost:8090/_broadcast ... ``` -------------------------------- ### Detailed Memory Metrics Example Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/instrumentation.md Enable detailed memory usage metrics by setting the ANYCABLE_MEMORY_METRICS environment variable to 1. This provides granular insights into heap and system memory allocation. ```text heap_alloc_total=2226352 heap_idle_bytes=4104192 heap_released_bytes=4104192 heap_sys_bytes=7569408 mem_sys_bytes=13912328stack_sys_bytes=819200 ``` -------------------------------- ### Add Ruby Buildpack Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/heroku.md Ensures the Ruby buildpack is installed on the AnyCable application to support the RPC server. ```bash # Add ruby buildpack heroku buildpacks:add heroku/ruby -a example-app-anycable ``` -------------------------------- ### Specify Configuration File Path Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/configuration.md Use the `--config-path` option to specify a custom TOML configuration file for AnyCable-Go. The output shows the starting log with the specified configuration file. ```shell $ anycable-go --config-path=/path/to/anycable.toml 2024-10-07 17:52:37.139 INF Starting AnyCable 1.6.0-87217bb (pid: 80235, open file limit: 122880, gomaxprocs: 8) nodeid=BzeSHV 2024-10-07 17:52:37.139 INF Using configuration from file: ./path/to/anycable.toml nodeid=BzeSHV ``` -------------------------------- ### Parameterized Redis Configuration with Password Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/kamal.md Use environment variables for Redis host and password to parameterize the configuration. This example shows how to set up Redis with a password and configure AnyCable to use it. ```yaml accessories: # ... redis: host: <%= ENV.fetch('REDIS_HOST') %> image: redis:8.0-alpine port: "6379:6379" cmd: redis-server --requirepass <%= ENV.fetch("REDIS_PASSWORD") %> volumes: - redisdata:/data anycable-go: image: anycable/anycable-go:1.6 host: <%= ENV.fetch("ANYCABLE_HOST") %> proxy: # .. env: clear: ANYCABLE_HOST: "0.0.0.0" ANYCABLE_PORT: 8080 ANYCABLE_REDIS_URL: "redis://:<%= ENV.fetch("REDIS_PASSWORD") %>@<%= ENV.fetch("REDIS_HOST") %>:6379/0" ``` -------------------------------- ### MRuby Enabled Server Startup Message Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/instrumentation.md This message indicates that the AnyCable Go server has started with mruby support enabled. ```sh $ anycable-go INFO 2019-08-07T16:37:46.387Z context=main Starting AnyCable v0.6.2-13-gd421927 (with mruby 1.2.0 (2015-11-17)) (pid: 1362) ``` -------------------------------- ### Configure Memory Broker and RedisX Broadcaster Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/reliable_streams.md Combine the 'memory' broker with the 'redisx' broadcasting adapter for AnyCable-Go. This setup is suitable for clustered environments using Redis for broadcasting. ```sh $ anycable-go --broker=memory --broadcast_adapter=redisx ... INFO 2023-07-04T02:00:24.386Z consumer=s2IbkM context=broadcast id=s2IbkM provider=redisx stream=__anycable__ Starting Redis broadcaster at localhost:6379 ... ``` -------------------------------- ### Generate Sample Configuration File Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/configuration.md Use the `--print-config` option to output the current AnyCable-Go configuration to standard output. This can be redirected to a file to create a sample configuration. ```shell anycable-go --print-config > anycable.toml ``` -------------------------------- ### Heroku Release Command for Dual Deployment Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/heroku.md This example shows how to conditionally skip the release command for AnyCable deployments, allowing the main application to manage database migrations. It uses the ANYCABLE_DEPLOYMENT environment variable. ```ruby release: [[ "$ANYCABLE_DEPLOYMENT" == "true" ]] && echo "Skip release script" || bundle exec rails db:migrate ``` -------------------------------- ### Get Channel Users with Pusher Ruby SDK Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/pusher.md Example of using the Pusher Ruby SDK to request users for a presence channel. The SDK handles authentication and response parsing. ```ruby require "pusher" client = Pusher::Client.new( app_id: "my-app-id", key: "my-app-key", secret: "my-secret" ) # Request the users for a presence channel: response = pusher.channel_users("presence-my-channel") response["users"].each do |user| puts "User ID: #{user['id']}" end ``` -------------------------------- ### Start AnyCable-Go with Embedded NATS Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/reliable_streams.md Use the `--embed_nats` flag to automatically enable JetStream when using the NATS broker. This is suitable for single-node setups where NATS is managed by AnyCable-Go. ```sh $ anycable-go --embed_nats --broker=nats INFO 2023-10-28T00:59:01.177Z context=main Starting AnyCable 1.4.6-c31c153 (with mruby 1.2.0 (2015-11-17)) (pid: 30693, open file limit: 122880, gomaxprocs: 8) INFO 2023-10-28T00:59:01.177Z context=main Starting NATS broker: nats://127.0.0.1:4222 (history limit: 100, history ttl: 300s, sessions ttl: 300s) INFO 2023-10-28T00:59:01.205Z context=main Embedded NATS server started: nats://127.0.0.1:4222 ... ``` -------------------------------- ### Embed AnyCable into an Existing Go HTTP Server Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/library.md This example demonstrates how to embed AnyCable into an existing Go web application. It configures AnyCable with default options and serves WebSocket connections on the /cable endpoint. ```go package main import ( "net/http" "github.com/anycable/anycable-go/cli" ) func main() { opts := []cli.Option{ cli.WithName("AnyCable"), cli.WithDefaultRPCController(), cli.WithDefaultBroker(), cli.WithDefaultSubscriber(), cli.WithDefaultBroadcaster(), } c := cli.NewConfig() runner, _ := cli.NewRunner(c, opts) anycable, _ := runner.Embed() wsHandler, _ := anycable.WebSocketHandler() http.Handle("/cable", wsHandler) http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Broadcast Remote Commands via Action Cable Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/ocpp.md Demonstrates how to send remote commands to stations using Action Cable broadcasts. This example shows broadcasting a 'TriggerMessage' command to request a 'BootNotification'. ```ruby OCCPChannel.broadcast_to( "ev/#{serial_number}", { command: "TriggerMessage", id: "", payload: { requestedMessage: "BootNotification" } } ) ``` -------------------------------- ### Launch AnyCable-Go Fly Application Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/fly.md Initialize the AnyCable-Go Fly application using the official Docker image, without immediate deployment. ```sh fly launch --image anycable/anycable-go:1 --no-deploy --name my-cable ``` -------------------------------- ### Configure AnyCable for Pusher Compatibility Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/pusher.md Start AnyCable with Pusher application ID, key, and secret to enable compatibility mode. The logs will show the Pusher WebSocket and HTTP API endpoints. ```sh $ anycable-go --pusher_app_id=my-app-id --pusher_app_key=my-app-key --pusher_secret=my-secret ... INFO 2025-01-20 12:00:00.000 INF Handle Pusher WebSocket connections at http://localhost:8080/app/my-app-key INFO 2025-01-20 12:00:00.000 INF Handle Pusher API requests at http://localhost:8080/apps/my-app-id/ ``` -------------------------------- ### Create AnyCable-Go Application Directory Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/fly.md Prepare the working directory for deploying the AnyCable-Go Fly application. ```sh mkdir -p .fly/applications/anycable-go cd .fly/applications/anycable-go ``` -------------------------------- ### Basic CLI Configuration Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/configuration.md Configure AnyCable-Go server using command-line options for RPC host, headers, Redis connection, and server host/port. ```sh $ anycable-go --rpc_host=localhost:50051 --headers=cookie \ --redis_url=redis://localhost:6379/5 --redis_channel=__anycable__ \ --host=localhost --port=8080 ``` -------------------------------- ### StatsD Example Payload Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/instrumentation.md This is an example of the metrics payload that AnyCable Go can send to a StatsD server. ```sh anycable_go.mem_sys_bytes:15516936|g anycable_go.clients_num:0|g anycable_go.clients_uniq_num:0|g anycable_go.broadcast_streams_num:0|g anycable_go.disconnect_queue_size:0|g anycable_go.rpc_pending_num:0|g anycable_go.failed_server_msg_total:1|c anycable_go.rpc_call_total:1|c anycable_go.rpc_retries_total:1|c anycable_go.rpc_error_total:1|c ``` -------------------------------- ### Download AnyCable Pro Binary using fetch Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/pro/install.md Download AnyCable Pro binaries from GitHub Releases using the `fetch` command-line tool. Replace `` with your GitHub personal access token. ```sh fetch --repo=https://github.com/anycable/anycable-go-pro-releases --tag="v1.4.0" --release-asset="anycable-go-linux-amd64" --github-oauth-token="" /tmp ``` -------------------------------- ### Custom MRuby Metrics Formatter Example (Librato) Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/instrumentation.md An example of an mruby script that formats metrics in a Librato-compatible string format. ```ruby module MetricsFormatter def self.call(data) parts = [] data.each do |key, value| parts << "sample##{key}=#{value}" end parts.join(" ") end end ``` -------------------------------- ### Run AnyCable Go Server with Turbo Streams Enabled Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/guides/hotwire.md Start the AnyCable Go server with the necessary environment variables or command-line arguments to enable Turbo Streams support. This ensures AnyCable can handle Turbo Stream connections. ```sh ANYCABLE_SECRET=your-secret \ ANYCABLE_TURBO_STREAMS=true \ anycable-go ``` ```sh anycable-go --secret=your-secret --turbo_streams ``` -------------------------------- ### Example API Response for Presence Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/api.md This is an example of a successful response when retrieving presence information, showing the total number of users and their details. ```json { "type": "info", "total": 2, "records": [ { "id": "user-123", "info": { "name": "Alice", "status": "online" } }, { "id": "user-456", "info": { "name": "Bob", "status": "away" } } ] } ``` -------------------------------- ### Download AnyCable Thruster Pro Binary using fetch Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/pro/install.md Download AnyCable Thruster Pro binaries from GitHub Releases using the `fetch` command-line tool. Replace `` with your GitHub personal access token. ```sh fetch --repo=https://github.com/anycable/anycable-go-pro-releases --tag="v1.6.5" --release-asset="anycable-thruster-linux-amd64" --github-oauth-token="" /tmp ``` -------------------------------- ### Install AnyCable Rails RuboCop as a Separate Gem Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/compatibility.md You can install the AnyCable Rails RuboCop extension as a separate gem, which is useful if you manage your RuboCop configuration via a dedicated gem. ```ruby gem "rubocop-anycable-rails" ``` -------------------------------- ### Configure Action Cable Adapter for Production Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/getting_started.md Set the Action Cable adapter to 'any_cable' in your `cable.yml` for production environments. ```yaml production: adapter: any_cable # ... ``` -------------------------------- ### Client-side Chat Channel with AnyCable Web SDK Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/guides/serverless.md Demonstrates how to set up a client-side chat channel using the AnyCable Web SDK. Includes creating a cable connection, defining a channel class, subscribing, and performing remote commands. ```javascript import { createCable, Channel } from "@anycable/web"; //Set up a connection export const cable = createCable(); //Define a client-side class for the channel export class ChatChannel extends Channel { static identifier = "chat"; sendMessage(message: SentMessage) { this.perform("sendMessage", message); } } // create a channel instance const channel = new ChatChannel({ roomId }); // subscribe to the server-side channel cable.subscribe(channel); channel.on("message", (message) => { console.log("New message", message); }); // perform remote commands channel.sendMessage({ body: "Hello, world!" }); ``` -------------------------------- ### Start HTTP Health Check Server via Environment Variable Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/ruby/health_checking.md Configure the AnyCable RPC server to start with an HTTP health check server using an environment variable for the port. ```sh ANYCABLE_HTTP_HEALTH_PORT=54321 bundle exec anycable ``` -------------------------------- ### Configure AnyCable Server Settings Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/getting_started.md Set up basic AnyCable configuration, including the broadcast adapter and WebSocket URL, in the anycable.yml file. ```yaml # config/anycable.yml development: broadcast_adapter: http websocket_url: ws://localhost:8080/cable ``` -------------------------------- ### Configure Memory Broker, RedisX Broadcaster, and Redis Pub/Sub Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/reliable_streams.md Set up AnyCable-Go with 'memory' broker, 'redisx' broadcaster, and 'redis' pub/sub adapter. This configuration enables reliable message re-transmission within a cluster. ```sh $ anycable-go --broker=memory --broadcast_adapter=redisx --pubsub=redis INFO 2023-07-04T02:02:10.548Z context=main Starting AnyCable 1.4.0-d8939df (with mruby 1.2.0 (2015-11-17)) (pid: 87410, open file limit: 122880, gomaxprocs: 8) INFO 2023-07-04T02:02:10.548Z context=main Using in-memory broker (epoch: vRXl, history limit: 100, history ttl: 300s, sessions ttl: 300s) INFO 2023-07-04T02:02:10.586Z consumer=s2IbkM context=broadcast id=s2IbkM provider=redisx stream=__anycable__ Starting Redis broadcaster at localhost:6379 INFO 2023-07-04T02:02:10.710Z context=pubsub Starting Redis pub/sub: localhost:6379 ... ``` -------------------------------- ### Get Users of a Presence Channel via Pusher HTTP API Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/pusher.md Retrieve the list of users subscribed to a presence channel using the GET /apps/{app_id}/channels/{channel_name}/users endpoint. This endpoint only works with presence channels and requires authentication. ```sh curl "http://localhost:8080/apps/my-app-id/channels/presence-my-channel/users?auth_key=my-app-key&auth_timestamp=$(date +%s)&auth_version=1.0&auth_signature=" ``` -------------------------------- ### Example Action Cable Channel for OCPP Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/ocpp.md This Ruby class demonstrates how to manage EV charging station connections and handle OCPP commands like BootNotification, StatusNotification, Authorize, StartTransaction, and StopTransaction using Action Cable. ```ruby class OCPPChannel < ApplicationCable::Channel def subscribed # You can subscribe the station to its personal stream to # send remote comamnds to it # params["sn"] contains the station's serial number # (meterSerialNumber from the BootNotification request) stream_for "ev/#{params["sn"]}" end def boot_notification(data) # Data contains the following fields: # - id - a unique message ID # - command - an original command name # - payload - a hash with the original request data id, payload = data.values_at("id", "payload") logger.info "BootNotification: #{payload}" # By default, if not ack sent, AnyCable sends the following: # [3, , {"status": "Accepted"}] # # For boot notification response, the "interval" is also added. end def status_notification(data) id, payload = data.values_at("id", "payload") logger.info "Status Notification: #{payload}" end def authorize(data) id, payload = data.values_at("id", "payload") logger.info "Authorize: idTag — #{payload["idTag"]}" # For some actions, you may want to send a custom response. transmit_ack(id:, idTagInfo: {status: "Accepted"}) end def start_transaction(data) id, payload = data.values_at("id", "payload") id_tag, connector_id = payload.values_at("idTag", "connectorId") logger.info "StartTransaction: idTag — #{id_tag}, connectorId — #{connector_id}" transmit_ack(id:, transactionId: rand(1000), idTagInfo: {status: "Accepted"}) end def stop_transaction(data) id, payload = data.values_at("id", "payload") id_tag, connector_id, transaction_id = payload.values_at("idTag", "connectorId", "transactionId") logger.info "StopTransaction: transcationId - #{transaction_id}, idTag — #{id_tag}" transmit_ack(id:, idTagInfo: {status: "Accepted"}) end # These are special methods to handle OCPP errors and acks def error(data) id, code, message, details = data.values_at("id", "code", "message", "payload") logger.error "Error from EV: #{code} — #{message} (#{details})" end def ack(data) logger.info "ACK from EV: #{data["id"]} — #{data.dig("payload", "status")}" end private def transmit_ack(id:, **payload) # IMPORTANT: You must use "Ack" as the command for acks, # so AnyCable can correctly translate them into OCPP acks. transmit({command: :Ack, id:, payload:}) end end ``` -------------------------------- ### Empty Stream Response Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/api.md An example of an API response for a stream that currently has no users present. ```json { "total": 0 } ``` -------------------------------- ### Basic AnyCable-Go Accessory Configuration Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/kamal.md Configure the anycable-go accessory with Redis for pub/sub. Ensure Redis is accessible and AnyCable is configured with the correct Redis URL. ```yaml accessories: # ... redis: image: redis:7.0 host: 192.168.0.1 directories: - data:/data anycable-go: image: anycable/anycable-go:1.6 host: 192.168.0.1 proxy: host: ws.demo.anycable.io ssl: true app_port: 8080 healthcheck: path: /health env: clear: ANYCABLE_HOST: "0.0.0.0" ANYCABLE_PORT: 8080 ANYCABLE_REDIS_URL: "redis://anycable_rails_demo-redis:6379/0" ``` -------------------------------- ### Add PostgreSQL and Redis Add-ons Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/heroku.md Installs necessary add-ons for your Heroku application. Ensure Redis is available. ```bash heroku addons:create heroku-postgresql heroku addons:create heroku-redis ``` -------------------------------- ### Get Presence Channel Users API Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/pusher.md Retrieves a list of users currently subscribed to a presence channel. ```APIDOC ## GET /channels/{channel}/users ### Description Fetches the list of users currently subscribed to a presence channel. ### Method GET ### Endpoint /channels/{channel}/users ### Parameters #### Path Parameters - **channel** (string) - Required - The name of the presence channel. ### Response #### Success Response (200) - **users** (array) - A list of user identifiers subscribed to the channel. #### Response Example ```json { "users": [ "user1", "user2" ] } ``` ``` -------------------------------- ### Run AnyCable-Go Server Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/getting_started.md Execute the AnyCable-Go server binary. By default, it attempts to connect to a gRPC server at localhost:50051. ```sh $ anycable-go 2024-03-06 13:38:07.545 INF Starting AnyCable 1.6.0-4f16b99 (pid: 8289, open file limit: 122880, gomaxprocs: 8) nodeid=hj2mXN ... 2024-03-06 13:38:56.490 INF RPC controller initialized: localhost:50051 (concurrency: 28, impl: grpc, enable_tls: false, proto_versions: v1) nodeid=FlCtwf context=rpc ``` -------------------------------- ### Pusher HTTP API - Get Channel Users Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/pusher.md Retrieve the list of users subscribed to a presence channel. ```APIDOC ## GET /apps/{app_id}/channels/{channel_name}/users ### Description Retrieve the list of users subscribed to a presence channel. ### Method GET ### Endpoint /apps/{app_id}/channels/{channel_name}/users ### Parameters #### Path Parameters - **app_id** (string) - Required - The application ID. - **channel_name** (string) - Required - The name of the presence channel. #### Query Parameters - **auth_key** (string) - Required - Pusher authentication key. - **auth_timestamp** (integer) - Required - Unix timestamp of the request. - **auth_version** (string) - Required - Authentication version, typically "1.0". - **auth_signature** (string) - Required - Signature generated using Pusher's secret. ### Response #### Success Response (200) - **users** (array) - A list of user objects, each with an `id` field. #### Response Example ```json { "users": [ {"id": "user-1"}, {"id": "user-2"} ] } ``` ### Notes - This endpoint only works with presence channels (channels prefixed with `presence-`). - Returns `400 Bad Request` for non-presence channels. - Returns an empty list for unknown channels. ``` -------------------------------- ### Deploy AnyCable-Go Button Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/heroku.md Click this button to deploy AnyCable-Go to Heroku using a pre-configured template. Ensure you fill in the required environment variables like ANYCABLE_RPC_HOST and ANYCABLE_SECRET. ```link https://www.heroku.com/deploy?template=https://github.com/anycable/anycable-go ``` -------------------------------- ### Kamal Configuration for AnyCable-Go Accessory Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/kamal.md This configuration sets up the anycable-go accessory, including its host, image, environment variables, and proxy settings. It demonstrates how to use a fixed list of RPC addresses. ```yaml accessories: # ... anycable-go: host: <%= ENV.fetch("WS_HOSTS") %> image: anycable/anycable-go:1.6.2-alpine env: clear: <<: *default_env ANYCABLE_HOST: "0.0.0.0" ANYCABLE_PORT: "8080" # Using a fixed list of RPC addresses https://docs.anycable.io/deployment/load_balancing?id=using-a-fixed-list-of-rpc-addresses ANYCABLE_RPC_HOST: "grpc-list://<%= ENV.fetch("RPC_HOSTS").split(",").map { "#{_1}:50051" }.join(",") %>" proxy: # ... ``` -------------------------------- ### GET /presence/:stream/users Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/api.md Retrieve presence information for a specific stream. This endpoint requires presence support to be enabled. ```APIDOC ## GET /presence/:stream/users ### Description Retrieve presence information for a specific stream. This endpoint requires presence support to be enabled. ### Method GET ### Endpoint /api/presence/:stream/users ### Parameters #### Path Parameters - **stream** (string) - Required - The name of the stream to get presence information for ### Response #### Success Response (200 OK) Presence information retrieved successfully #### Response Body ```json { "type": "info", "total": 2, "records": [ { "id": "user-1", "info": { "name": "Alice" } }, { "id": "user-2", "info": { "name": "Bob" } } ] } ``` - **type** (string) - Always "info" - **total** (integer) - Total number of unique presence records in the stream - **records** (array) - List of presence records (omitted if empty) - **id** (string) - Unique presence identifier for the user - **info** (object) - User-defined presence information #### Error Responses - **401 Unauthorized**: Missing or invalid authentication - **404 Not Found**: Invalid path format - **422 Unprocessable Entity**: Invalid request method (non-GET) - **501 Not Implemented**: Presence is not supported by the current broker ``` -------------------------------- ### Configure AnyCable-Go with RedisX and Redis Adapters Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/upgrade-notes/1_3_0_to_1_4_0.md Configure AnyCable-Go to use both `redisx` and `redis` broadcast adapters along with `redis` pubsub. This is necessary when migrating to the new broadcasting architecture and running multiple AnyCable-Go instances. ```sh ANYCABLE_BROADCAST_ADAPTER=redisx,redis \ ANYCABLE_PUBSUB=redis anycable-go ``` ```sh anycable-go --broadcast_adapter=redisx,redis --pubsub=redis ``` -------------------------------- ### AnyCable/PeriodicalTimers Cop: Incompatible Usage Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/compatibility.md This example shows the 'bad' usage of periodical timers, which is flagged by the AnyCable/PeriodicalTimers RuboCop cop. ```ruby # bad class MyChannel < ApplicationCable::Channel periodically(:do_something, every: 2.seconds) end ``` -------------------------------- ### Publication Meta Field: exclude_socket Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/broadcasting.md Example of using the 'exclude_socket' meta field to prevent a specific client from receiving a publication. ```json { "stream": "...", "data": "...", "meta": { "exclude_socket": "unique_client_identifier" } } ``` -------------------------------- ### Start AnyCable-Go with Embedded NATS Cluster (First Instance) Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/anycable-go/embedded_nats.md Initialize the first AnyCable-Go instance for a NATS cluster. This involves enabling embedded NATS, specifying its address, and defining the cluster address for peer discovery. ```sh # first instance $ anycable-go --broadcast_adapter=nats --embed_nats --enats_addr=nats://0.0.0.0:4242 --enats_cluster=nats://0.0.0.0:4243 INFO 2023-02-28T00:06:45.618Z context=main Starting AnyCable 1.3.0 INFO 2023-02-28T00:06:45.649Z context=main Embedded NATS server started: nats://127.0.0.1:4242 (cluster: nats://0.0.0.0:4243, cluster_name: anycable-cluster) ``` -------------------------------- ### Dockerfile for AnyCable-Go Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/deployment/render.md Use this Dockerfile to build the AnyCable-Go service. Ensure it's pushed to a git repository for Render to access. ```dockerfile FROM anycable/anycable-go:1.2 ``` -------------------------------- ### Create Cable Instance Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/guides/client-side.md Create a cable instance using `createCable` from `@anycable/web`. Configure options like `logLevel` for debugging and `protocol` for specifying the communication protocol. ```javascript import { createCable } from '@anycable/web' export default createCable({ // There are various options available. For example: // - Enable verbose logging logLevel: 'debug', // - Use the extended Action Cable protocol protocol: 'actioncable-v1-ext-json', }) ``` -------------------------------- ### Activate a Custom Middleware Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/ruby/middlewares.md Add your custom middleware to the AnyCable middleware chain using `AnyCable.middleware.use`. This can be done before the AnyCable server starts. ```ruby AnyCable.middleware.use(PrintMiddleware) ``` ```ruby AnyCable.middleware.use(ParameterizedMiddleware.new(params)) ``` -------------------------------- ### AnyCable/InstanceVars Cop: Incompatible Code Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/compatibility.md This example shows the 'bad' usage of instance variables within a channel, which is flagged by the AnyCable/InstanceVars RuboCop cop. ```ruby # bad class MyChannel < ApplicationCable::Channel def subscribed @post = Post.find(params[:id]) stream_from @post end end ``` -------------------------------- ### Configure Action Cable Adapter for AnyCable Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/getting_started.md Specify 'any_cable' as the adapter for Action Cable in your cable.yml file for development environments. ```yaml # config/cable.yml development: adapter: any_cable # ... ``` -------------------------------- ### Hub Broadcast Implementation Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/misc/how_to_anycable_server.md Provides an example implementation for the broadcast function within the Hub interface, iterating through channels and sockets to transmit messages. ```js func broadcast(stream, msg) { # Assume that we have a nested structure to store subscriptions: # sockets2streams # | # stream1 # | | # | channel1 - (socket1, ..., socketN) # | | # | channel2 – ( ... ) # | # stream2 ... # for (channel in channels_for_stream(stream)) { channel_msg = msg_for_channel(msg, channel.id()) for (socket in channel.sockets()) { socket.transmit(channel_msg) } } } # msg – JSON encoded string # We should transform into another JSON "{"identifier":,"message": }" func msg_for_channel(msg, identifier) { return json_encode(['identifier', 'message'], [identifier, json_decode(msg)]); } ``` -------------------------------- ### AnyCable/StreamFrom Cop: Incompatible Stream Calls Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/rails/compatibility.md These examples demonstrate 'bad' usage of `stream_from` with custom callbacks or coders, which are flagged by the AnyCable/StreamFrom RuboCop cop. ```ruby # bad class MyChannel < ApplicationCable::Channel def follow stream_from("all") {} end end class MyChannel < ApplicationCable::Channel def follow stream_from("all", -> {}) end end class MyChannel < ApplicationCable::Channel def follow stream_from("all", coder: SomeCoder) end end ``` -------------------------------- ### Integrate AnyCable with Hotwire (Turbo Streams) Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/guides/client-side.md Switch Turbo to use the AnyCable client for improved real-time experience. Ensure you import `@hotwired/turbo` directly and not `turbo-rails`. The `start` function from `@anycable/turbo-stream` is used to initialize the integration. ```javascript // IMPORTANT: Do not import turbo-rails, just turbo // import "@hotwired/turbo-rails"; import "@hotwired/turbo"; import { start } from "@anycable/turbo-stream"; import cable from "cable" start(cable, { delayedUnsubscribe: true }) ``` -------------------------------- ### Configure Honeybadger Exception Handler Source: https://github.com/anycable/docs.anycable.io/blob/master/docs/ruby/exceptions.md Attach a custom handler to report exceptions to Honeybadger. This example shows how to send the exception, component, action, and message. ```ruby # with Honeybadger AnyCable.capture_exception do |ex, method, message| Honeybadger.notify(ex, component: "any_cable", action: method, params: message) end ```