Skip to content

Releases: webpatser/resonate

v0.4.0

Choose a tag to compare

@webpatser webpatser released this 22 May 07:03

Completes the plugin connection lifecycle. v0.3.0 shipped onSubscribe but no onUnsubscribe, and PluginContext::connectionsOn() (read) with no write-side counterpart. A plugin could see a connection join a channel but not leave one short of a full disconnect, and could not evict a connection from a single channel without terminating the whole socket. Both gaps are now closed.

Added

  • ConnectionLifecycle::onUnsubscribe(Connection, Channel) - fires when a connection leaves a channel via the explicit pusher:unsubscribe event.
  • PluginManager::notifyUnsubscribe() - exception-isolated fan-out for the new hook.
  • PluginContext::unsubscribe(Connection, string $channel) - removes a connection from one channel, leaving the socket and its other subscriptions intact. A direct action; it does not itself emit onUnsubscribe.

Changed

  • ConnectionLifecycle gains a fourth method, onUnsubscribe. Breaking for existing implementers of the interface; the plugin system is one release old, so the contract is completed before it settles.
  • EventHandler::unsubscribe() fires the onUnsubscribe lifecycle hook after removing the connection from the channel. A closing connection is still reported once through onClose, not as one unsubscribe per channel.

Suite grows to 317 tests.

v0.3.0

Choose a tag to compare

@webpatser webpatser released this 21 May 18:50

Server-side plugin API. Resonate stays a product-agnostic Pusher relay, but a host application can now load ServerPlugin classes into the server process to intercept messages, observe the connection lifecycle, and run periodic ticks on the event loop. Ordinary Pusher traffic is unaffected: when every plugin returns Relay, routing is byte-identical to before.

Added

  • Webpatser\Resonate\Plugins namespace: ServerPlugin marker contract plus the MessageInterceptor, ConnectionLifecycle, and TickScheduler capability interfaces.
  • MessageDisposition enum (Handled / Rejected / Relay) returned by interceptors.
  • PluginManager - capability-indexed registry; every fan-out call is exception-isolated so a plugin error cannot break the core.
  • PluginContext - the API handed to plugins at boot: sendTo(), broadcast() (scaling-aware), terminate(), connectionsOn(), plus application() / applications().
  • Per-connection plugin state bag on the Connection contract: setState(), state(), hasState(), forgetState().
  • New config key reverb.servers.reverb.plugins, an array of ServerPlugin class names resolved through the container.
  • Scheduler (Webpatser\Resonate\Scheduling\Scheduler) - a thin layer over the Revolt event loop. Every task runs inside a fiber and is exception-isolated, named for logging, and cancellable.

Changed

  • Server::message() runs the interceptor chain after validation and before the pusher: / client-* split; Server::open() / close() and EventHandler::afterSubscribe() fire the lifecycle hooks.
  • A message a plugin marks Handled or Rejected no longer fires the MessageReceived event or logs Message Handled; both are now scoped to traffic the core actually routed (Relay).
  • StartServer registers all periodic work through the Scheduler instead of bare EventLoop::repeat calls, so every task is fiber-wrapped and exception-isolated. Periodic tasks are cancelled when the server begins to drain or stop.

Docs

  • New docs/plugins.md - a full setup walkthrough with a worked plugin implementing all three capabilities.

Suite grows to 313 tests.

v0.1.1: rename artisan commands to resonate:*

Choose a tag to compare

@webpatser webpatser released this 16 May 10:19

Changed (breaking)

  • Artisan commands renamed from reverb:start / reverb:restart / reverb:install to resonate:start / resonate:restart / resonate:install. Update supervisor / systemd / Docker entrypoints accordingly. The laravel:reverb:restart cache key is unchanged, so running Resonate servers still pick up restart signals from any existing tooling.

v0.1.0: initial release

Choose a tag to compare

@webpatser webpatser released this 16 May 09:58

Changelog

All notable changes to webpatser/resonate are documented here.

v0.1.0 - 2026-05-16

Initial public release. Fiber-based drop-in replacement for Laravel Reverb on webpatser/fledge-fiber.

  • Pusher wire protocol with byte-exact JSON framing (public, private, presence, cache, private-cache, presence-cache channels; client events; rate limiting; connection limits; origin verification).
  • Full Pusher-compatible HTTP REST API (events, batch events, channels, channel, channel users, connections, user termination, health check) with the original HMAC signature canonicalization.
  • Horizontal scaling via Redis pub/sub on fledge-fiber's async Redis. Pure JSON envelopes, no serialize(). Cross-node message / terminate / metrics propagation.
  • reverb:start, reverb:restart, reverb:install artisan commands; PID file; signal handling; restart-cache poll; periodic prune / ping; Pulse and Telescope ingest timers.
  • Pulse recorders + Livewire dashboard components (reverb.connections, reverb.messages).