centrifuge

0.21.0

Dart client to communicate with Centrifuge and Centrifugo from Flutter and VM over WebSockets

Download archive

Readme

Websocket client for Centrifugo server and Centrifuge library.

Since there is no v1 release yet, patch version updates only contain backwards compatible changes, minor version updates can have backwards incompatible API changes.

Check out client SDK API specification to learn how this SDK behaves. It's recommended to read that before starting to work with this SDK as the spec covers common SDK behavior - describes client and subscription state transitions, main options and methods. Also check out examples folder.

The features implemented by this SDK can be found in SDK feature matrix.

Note that custom WebSocket connection Upgrade headers are sent natively on platforms that support dart:io and in web context headers are sent using Centrifugo v6 Headers Emulation feature.

The latest centrifuge-dart is compatible with Centrifugo server v6, v5 and v4 and Centrifuge >= 0.25.0. For Centrifugo v2, Centrifugo v3 and Centrifuge < 0.25.0 you should use centrifuge-dart v0.8.0.

Examples

  • example\flutter_app simple chat application
  • example\console simple console application

Usage in background

When a mobile application goes to the background there are OS-specific limitations for established persistent connections - which can be silently closed shortly. Thus in most cases you need to disconnect from a server when app moves to the background and connect again when app goes to the foreground.

Errors in event listeners

Event listeners should not throw: catch errors in your listeners. The SDK can't know what a throwing listener left undone, so it fails loudly instead of going on as if nothing happened:

  • the error is reported to the zone the listener was registered in, as an uncaught error;
  • the client disconnects with code 2 (bad protocol) and the reason exception in event handler: <error>, and doesn't reconnect – call connect() to start again;
  • the listeners after the failing one don't get that event; the SDK's own work completes as if the listener had returned;
  • a publication whose listener threw is not counted as delivered: after connect(), a recoverable subscription receives it again.

Alternative SDK

See also PlugFox/spinify for an alternative Dart (Flutter) real-time client SDK implementation.

Run tests locally

Start test Centrifugo server:

docker compose up

Then run tests:

dart run test --reporter expanded

Instructions for maintainers/contributors

How to update protobuf definitions

  1. Install protoc compiler
  2. Install protoc_plugin https://pub.dev/packages/protoc_plugin (dart pub global activate protoc_plugin)
  3. cd lib/src/proto and run protoc --dart_out=. -I . client.proto
  4. cd to root and run dartfmt -w lib/ test/ (install dartfmt with dart pub global activate dart_style)

How to release

  1. Update CHANGELOG.md, bump version in pubspec.yaml, push, create new tag
  2. [ONLY IF THERE ARE ISSUES WITH CI PUBLISH] dart pub publish

Author

German Saprykin, saprykin.h@gmail.com

Changelog

[0.21.0]

A stability release. Connection, subscription and token handling were reviewed against a validation harness and against centrifuge-js. The harness covers seeded chaos against a fake server, a real Centrifugo behind fault-injecting proxies, and browsers under dart2js and dart2wasm. Most fixes cover races between reconnects, event listeners calling back into the client, teardown, token refresh, and browser behaviour. Every fix comes with a regression test.

Centrifugo v6.9.6 or later is recommended; see "Server versions" below.

Behaviour changes to check when upgrading

  • connect() validates the endpoint. It throws the new ConfigurationError, without changing the client state, when the endpoint can't be opened as a websocket on the platform. Such endpoints used to be retried forever as transport errors, calling getToken and getData on every attempt.
    • VM: the endpoint must be a ws:// or wss:// URL with a host and a valid port.
    • Browsers: it's checked with the browser's own URL parser, as new WebSocket() does. ws:, wss:, http:, https: and page-relative URLs are accepted; a fragment is not.
    • PRs: #159, #161, #166.
  • An expired connection token with no getToken stops the client. The client emits a ConfigurationError error event and disconnects as unauthorized, as centrifuge-js does, instead of reconnecting with the expired token forever. Call setToken() with a new token, then connect(). With getToken configured, the next attempt still calls getToken, even after setToken(). PRs: #129, #154.
  • An exception while handling a message from the server stops the client. An example is a fossil delta publication without base data. The client disconnects with badProtocol and reason "exception during message handling: ...", without reconnecting, as centrifuge-js does. The exception is still reported as uncaught. Before, the rest of that websocket message was lost, including replies to pending calls, and the client went on. The same now applies to a publication recovered in a subscribe reply that fails to decode, e.g. a delta without base data: before, the error went unnoticed and the rest of the recovered publications were dropped. PRs: #131, #177.
  • An exception thrown by an event listener stops the client. The client disconnects with badProtocol and reason "exception in event handler: ...", without reconnecting, as centrifuge-js does; call connect() to start again. The exception is still reported as uncaught in the listener's zone. Listeners after the failing one don't get that event, and the SDK's own processing completes as if the listener had returned. A publication whose listener threw doesn't count as delivered, so after connect() a recoverable subscription receives it again. Before, the exception was reported and otherwise ignored, and the client went on. Catch errors in your listeners. PR: #177.
  • The websocket handshake is limited by ClientConfig.timeout (10s by default). It's aborted on timeout, and on disconnect() or close() while in progress. Before, a server that accepted the connection but never answered the upgrade left the client connecting forever, and every attempt against it leaked its socket: two file descriptors per attempt, measured at 824 open descriptors after 400 attempts, until the process hit its limit and could no longer connect at all.
    • With HttpOverrides in effect, the handshake uses the app's HttpClient, which is left open, so a timed-out handshake isn't aborted.
    • PRs: #126, #139, #151, #158, #162.
  • unsubscribed is emitted when unsubscribe() is called, before the server replies, instead of after the reply. The Unsubscribe command is sent before the event, so a subscribe() from its listener follows it. PRs: #128, #133.
  • removeSubscription() unregisters the subscription at once.
    • A new subscription to the same channel can be created right away.
    • subscribe() on the removed subscription throws ClientClosedError.
    • Its streams close once the unsubscribe completes, so every listener still gets the current event.
    • PRs: #147, #153.
  • subscriptions() returns an unmodifiable copy instead of the client's live registry. Code can remove subscriptions while iterating over it. PR: #150.
  • ready() returns a failed future instead of throwing synchronously when the client is disconnected or closed, or the subscription is unsubscribed. await ready() inside try catches the error as before; ready().catchError(...) now gets it too. PR: #163.
  • A repeated connect() or subscribe() doesn't fail. A second call while connecting or subscribing still waits for the attempt in progress. Like the first call, it now completes without an error if that attempt ends in a disconnect or unsubscribe, instead of leaving an uncaught error when not awaited. PR: #164.
  • A server unsubscribe push is ignored while a subscription is still subscribing, as centrifuge-js does. The server sends it also for a channel the connection isn't subscribed to yet. PR: #155.
  • Nested events are delivered immediately. An event emitted while a listener handles another one is delivered right away, still synchronously, instead of throwing StateError: Cannot fire new event. PR: #127.
  • Close reasons below 3000 are normalized. A websocket close with a code below 3000, other than 1009, is reported as code 1 with reason "transport closed", as centrifuge-js does. It used to carry the socket's reason, which is empty in browsers for a dropped connection. PR: #167.
  • A zero timeout means no timeout also for calls waiting for the client or a subscription to become ready; they used to fail at once. PR: #156.
  • A static token survives state invalidation. After a 3014 disconnect or a 2502 unsubscribe, a connection or subscription token without getToken is kept, and the client reconnects or resubscribes with it. The server rejects it if it's no longer valid. PRs: #129, #152.

Connection fixes

  • Superseded connect attempts:
    • disconnect(), setToken() and connect() during a pending attempt no longer connect with the old token.
    • connect() after disconnect() is no longer dropped while the old attempt runs.
    • disconnect() closes the pending attempt's transport.
    • A transport closing while getData is awaited no longer loses its reconnect.
    • PR: #126.
  • Listeners calling back into the client:
    • disconnect() or connect() from connecting, connected, disconnected, subscribing and error listeners leaves consistent state and one connection attempt, with no duplicate events, no ConcurrentModificationError and no leftover ping or refresh timers.
    • A listener's reaction to a failed connect or subscribe is no longer undone by the failure handling that followed.
    • PRs: #127, #137.
  • connect() from a disconnected listener after getToken threw UnauthorizedException no longer leaves the client connecting forever. PR: #124.
  • Closed connections:
    • A closed connection is processed before its pending calls fail, so a pending subscribe or refresh no longer emits an error event for a close the client recovers from on its own.
    • A listener sending a command while those calls fail no longer leaves the client connected to a closed connection.
    • PRs: #138, #140.
  • Calls and timeouts:
    • A call racing disconnect() fails with ClientDisconnectedError instead of a null-check TypeError.
    • When a suspended process resumes, replies and pings already received are processed before call timeouts and the ping timeout. That avoids failing a call the server handled, and "no ping" reconnects of healthy connections.
    • Calls that time out waiting for ready() no longer leave waiters behind.
    • PRs: #130, #145, #148.
  • Data that isn't the protocol while connecting closes the connection and reconnects at once, instead of waiting for the connect timeout. PR: #160.

Subscription and recovery fixes

  • No deliveries after a teardown. Publications, joins and leaves are no longer delivered, and the stored position no longer moves, after unsubscribe(), disconnect() or removeSubscription(). This covers:
    • the rest of a message
    • the rest of the recovered publications
    • publications of server-side subscriptions from the connect reply
    • PR: #128.
  • Ghost subscriptions:
    • A subscribe superseded by unsubscribe() can no longer mark the subscription subscribed, or leave a server-side subscription the client doesn't track.
    • A subscribe pending when the connection is lost, e.g. in a browser whose network dropped, no longer blocks the next connection's resubscribe.
    • When unsubscribe() during a subscribe in flight sends an Unsubscribe and it fails, the client reconnects, as after a failed Unsubscribe of a subscribed subscription and as in centrifuge-js. Before, the server could keep the subscription and push its publications until the connection ended. A failure arriving after that connection ended no longer reconnects the next one.
    • PRs: #128, #134, #177.
  • Recovery without an epoch: when a subscribe or connect reply had no epoch (a channel without a stream yet), subscriptions and server-side subscriptions recovered with an empty epoch, which skips the server's epoch check. The epoch sent with the channel's first publication is now used, as in centrifuge-js. The bundled protocol gains Publication.epoch. PR: #170.
  • unsubscribe() and subscribe() from a publication listener no longer recover that publication again. PR: #142.
  • A subscription getToken that throws TimeoutException is handled like other getToken errors instead of reconnecting the whole client. PR: #143.
  • State invalidation:
    • A getState subscription created before a 3014 still calls getState on its first subscribe.
    • Server-side subscriptions no longer request recovery from their pre-invalidation position.
    • PRs: #121, #146.
  • removeSubscription() and subscribe:
    • Removing a subscription that was already removed no longer closes a newer subscription to the same channel.
    • A subscription being removed can no longer subscribe again on the server.
    • PRs: #141, #147.
  • ready() no longer resolves after a subscribed listener tore the subscription down. PR: #148.
  • Channel compaction: a subscription moved back to subscribing by the server drops its channel compaction ID, so pushes for another channel reusing that ID aren't delivered to it. PR: #123.

Token fixes

  • Refresh chains: a token refresh whose getToken resolves after a reconnect or resubscribe no longer starts a second refresh chain for the life of the connection or subscription. PR: #129.
  • Empty refresh token: an empty token returned by getToken during a refresh means unauthorized, as documented and as in centrifuge-js. It disconnects the client, or unsubscribes the subscription, instead of sending a refresh without a token. PR: #122.
  • Static subscription token: a subscription with a token but without getToken no longer fails into an endless retry loop when the server reports an expiry. PR: #120.
  • Expired token and error listeners: an expired token is dropped before the error event, so connect() or subscribe() from its listener gets a new token. PR: #137.

Other fixes

  • toString(): UnauthorizedException.toString() includes its message, and MessageEvent.toString() is well-formed. PRs: #118, #119.

Server versions

Two Centrifugo bugs found during this validation are fixed in Centrifugo v6.9.6 (centrifugal/centrifuge#629 and #627):

  • Fossil delta after an empty recovery. On older servers, a subscription with fossil delta that recovers no publications, for example one subscribing with since at the top of the stream, gets the next publication as a delta without base data. With this release the client then disconnects with badProtocol; earlier versions dropped every publication on the channel.
  • Expired subscription token accepted on refresh. On older servers a subscription refresh with an expired token was accepted, and the subscription then never expired. v6.9.6 disconnects with 3006, and the client reconnects and gets a new token.

Tests and CI

  • Centrifugo version: CI runs against Centrifugo v6.9.6, with a real-server test for the fossil delta fix. PR: #168.
  • Browser tests: test/web_endpoint_test.dart runs in a browser: dart test -p chrome test/web_endpoint_test.dart, optionally with --compiler dart2wasm. CI runs it in Chrome under both compilers.
  • Tooling: the analyzer uses package:lints with strict casts and raw types, and covers the tests too. The code is formatted with dart format, and CI checks it. The unused mockito and build_runner dev dependencies and the old tool/test.sh are removed. example/chat_app is removed too: it depended on the discontinued dash_chat package and no longer built. The public API and the minimum Dart SDK (3.7) are unchanged.
  • Flaky tests and comments: a timing-sensitive ping test was made independent of CPU load, a call timeout race test was made deterministic, outdated comments were updated, and the fake test server now documents that it keeps every command it received. PRs: #165, #169, #171, #177.

Some PRs in this release fix issues introduced by earlier PRs of the same release: #135, #136, #144, #149, #157 and parts of the PRs above. They are not listed separately, since v0.20.1 was not affected.

[0.20.1]

  • Fix Transport resolving to the dart:io (IOWebSocketChannel) implementation instead of the browser one (HtmlWebSocketChannel) when compiled with dart2wasm. The conditional import in transport.dart used to check dart.library.html, which is not declared under the wasm compile target — Flutter Web's wasm target has no dart:html and relies on dart:js_interop instead — so the WebSocket transport silently fell back to the VM implementation and never connected in the browser. Switched the check to dart.library.js_interop, which is declared for both dart2js and dart2wasm web builds while remaining unavailable on native (VM) targets, so native platforms keep using dart:io as before.

[0.20.0]

  • Add SubscriptionConfig.getState callback support (requires Centrifugo >= 6.8.0), mirroring the same option in centrifuge-js. The callback lets the application load its state from its own source of truth and return the corresponding stream position — the SDK then subscribes with recovery from that position, so no publications are lost between the state read and the subscribe. The callback is invoked on initial subscribe (when there is no saved position) and again when the server reports an unrecoverable position (error 112 — the SDK requests this behavior via the reject_unrecovered subscribe flag). It is NOT called on reconnects where server-side recovery succeeds. Errors thrown from the callback emit a subscription error event with the new SubscriptionGetStateError type and are retried with backoff.
  • Support channel compaction, mirroring centrifuge-js: every subscribe request now offers the channel_compaction flag, and when the server supports and allows it (Centrifugo PRO allow_channel_compaction namespace option) publication/join/leave pushes carry a short numeric channel ID instead of the string channel name — the SDK routes such pushes via an internal ID registry. Servers without compaction support simply ignore the flag, so behavior is unchanged there.
  • Support publication filtering by tags, mirroring centrifuge-js: a subscription can carry a tags filter so the server delivers only publications whose tags match, saving bandwidth. Build the filter with the new Filter helpers and pass it via SubscriptionConfig.tagsFilter, or change it at runtime with Subscription.setTagsFilter(). A tags filter cannot be combined with delta compression. #112
  • Resubscribe from an unrecoverable position on state invalidation: on state invalidation the SDK now resets the recovery position to a sentinel epoch the server cannot match instead of clearing it, so a recoverable subscription resubscribes with wasRecovering=true, recovered=false — letting the app reload via its existing recovery-failure path rather than looking like a brand-new first subscribe. A non-recoverable subscription simply resubscribes. #113

[0.19.1]

  • More connection and subscription stability fixes #109:
    • Fix Client.send() to use SendRequest instead of the deprecated Message type so async messages reach the server again.
    • Server-initiated unsubscribes that move the subscription to subscribing (codes 2500/3007 and other temporary codes) now trigger an immediate resubscribe instead of waiting for a reconnect that may never come.
    • Subscription resubscribe is now guarded against re-entry, and bails out cleanly if unsubscribe() or disconnect() arrives while getToken is awaiting.
    • Client.close() and Subscription.close() no longer emit error/unsubscribed events after the resource is closed; pending ready() futures on a closed subscription are completed with SubscriptionUnsubscribedError and any timers are cancelled.
    • ClientDisconnectedError thrown by an in-flight ConnectRequest no longer cancels the reconnect timer that the transport's onDone already scheduled (previously left the client stuck in connecting).
    • Reply decoding errors are now routed through the transport's onError callback instead of crashing the socket listener.
    • Errors thrown from the getData callback are caught: an error event is emitted and the transport is closed (instead of an unhandled async exception).
    • _refreshToken no longer issues a RefreshRequest if the client is not connected anymore by the time the token callback resolves.
    • getToken is no longer invoked when the user did not configure one (previous check could call a null callback in edge cases).
    • backoffDelay returns minDelay when the computed range collapses to zero, avoiding RangeError from Random.nextInt(0).

[0.19.0]

  • Add Client.close() — disconnects and releases all client resources (closes every event stream and removes every subscription). The client is unusable after close(); subsequent public method calls throw ClientClosedError. Use Client.disconnect() for a temporary disconnect that keeps the client usable. #106
  • Multiple connection stability fixes, see #106 for the full list. Highlights:
    • await client.disconnect() now actually waits for transport teardown before resolving.
    • Disconnect code 3014 (connection state invalidated) and unsubscribe code 2502 (subscription state invalidated) now correctly clear the relevant token and recovery state, forcing a fresh getToken on reconnect.
    • WebSocket close code 1009 (message size limit) is now terminal (no auto-reconnect), matching the behavior in centrifuge-js.
    • Cancelling a subscription while its SubscribeRequest is in flight now sends a cleanup Unsubscribe to the server, preventing a "ghost" server-side subscription that keeps pushing publications to the local sub.
    • Concurrent unsubscribe()/disconnect during a subscribe round-trip can no longer flip the subscription state back to Subscribed.
    • Several smaller correctness fixes around connect-mutex resets, async error handling, ping-reply decoding, and the ClientDisconnectedError thrown type.
  • Wire ClientConfig.tlsSkipVerify through to the WebSocket transport on VM/Flutter (dart:io) platforms — was a silent no-op before. Useful for wss:// development against a self-signed cert. Web platforms ignore the flag, since the browser owns TLS validation. #107
  • Substantially expand the integration test suite: server-initiated reconnection scenarios, extended stream recovery edge cases, client/subscription lifecycle ordering, getToken retries, and several race-condition tests, all running against the docker-compose Centrifugo.

[0.18.0]

  • Min SDK version is 3.7
  • Allow usage of protobuf v6 as dependency
  • Drop support for Protobuf v3, v4.

[0.17.0]

  • Allow usage of protobuf v5 as dependency

[0.16.0]

  • Allow usage of protobuf v4 as dependency, drop protobuf v2

[0.15.1]

  • Support Fossil delta compression, #97

[0.15.0]

  • Update web_socket_channel, min SDK is now 3.3 #91
  • Support headers emulation. Also added setHeaders method to update headers #92.

This release changes headers in ClientConfig from Map<String, dynamic> to Map<String, String>. This is a breaking change, but it must not cause huge troubles beyond a simple refactoring.

Usages of dart.html were removed in this release. Also some internal optimizations were done to allocate less when constructing Protobuf command data.

[0.14.1]

  • Add callback to update connection data #88

[0.14.0]

  • connInfo and chanInfo for join/leave events by @hetao29 #84

[0.13.0]

  • Relax Protobuf dependency requirements to be >=2.0.0 <4.0.0 instead of ^3.0.0

[0.12.0]

  • Fix websocket usage in web env (fixes The method 'sendByteBuffer' isn't defined for the type 'WebSocket' error), add simple web example #85

[0.11.0]

  • Update protobuf dependency from ^2.0.0 to ^3.0.0. Requires Dart 2.19

[0.10.0]

Breaking change! This release changes the semantics of working with connection tokens described in Centrifugo v5 release post.

Previously, returning an empty token string from getToken callback resulted in client disconnection with unauthorized reason.

Now returning an empty string from getToken is a valid scenario which won't result into disconnect on the client side. It's still possible to disconnect client by throwing a special UnauthorizedException from getToken function.

And we are putting back setToken method to the SDK – so it's now possible to reset the token to be empty upon user logout.

[0.9.4]

  • Improving reconnect behaviour upon bad network conditions (like connect timeout), #79
  • #79 also handles ClientDisconnectedError in _onPing method, addresses #76

[0.9.3]

  • Add support for web platform – #73

[0.9.2]

  • Fix null check for close reason, fixes #66
  • Close subscription streams on remove #67

[0.9.1]

  • Fix setting initial connection token
  • Fix setting connection data
  • Fix LateInitializationError if transport is not initialized yet
  • Better string representation of UnsubscribedEvent

[0.9.0]

Breaking changes

This release adopts a new iteration of Centrifugal protocol and a new iteration of API. Client now behaves according to the client SDK API specification. The work has been done according to Centrifugo v4 roadmap.

Check out Centrifugo v4 release post that covers the reasoning behind changes.

All the current core features of Centrifugal client protocol are now supported here.

New release only works with Centrifugo >= v4.0.0 and Centrifuge >= 0.25.0. See Centrifugo v4 migration guide for details about the changes in the ecosystem.

Note, that Centrifugo v4 supports clients working over the previous protocol iteration, so you can update Centrifugo to v4 without any changes on the client side (but you need to turn on use_client_protocol_v1_by_default option in the configuration of Centrifugo, see Centrifugo v4 migration guide for details).

[0.8.0]

Version 0.8.0 is the next iteration of centrifuge-dart development. It pushes client closer to other clients in the ecosystem. It also contains several backwards incompatible changes.

  • Return Futures from Client.connect, Client.disconnect, Subscription.subscribe, Subscription.unsubscribe methods - addresses #31.
  • On initial connect fire DisconnectEvent on connection error - this makes behavior of centrifuge-dart similar to all other our clients - addresses #56.
  • Add client error stream to consume ErrorEvent - each transport failure will emit error to this stream - addresses #56.
  • Refactor subscription statuses - add subscribing and error statuses. This change is mostly internal should not affect working with Subscriptions.
  • Do not call UnsubscribeEvent if subscription is not successfully subscribed (i.e. in subscribed state). This makes behavior of centrifuge-dart similar to all other our clients.
  • Update disconnect reasons due to failed connection and calling Client.Disconnect method - make it more similar to all other connector libraries in ecosystem.
  • Add default transport timeout (10 sec) – on connect and subscribe timeouts client will auto reconnect, calls like publish, history, rpc can now throw TimeoutException. Also - properly pass timeout to the transport (was not before!). Again – this makes client behave similarly to all other connectors.
  • Add presence and presenceStats methods for Subscription and on client top level (for server-side subscriptions).
  • Support streamPosition in SubscribeSuccessEvent.
  • Support streamPosition in ServerSubscribeEvent.
  • Support data in ServerSubscribeEvent.
  • Implement send method to send async messages to a server.
  • Fix deletion during iteration over map when working with server-side subscriptions.
  • Better event String representations.
  • Improvements and fixes in examples.

[0.7.1]

  • Add support for data in SubscribeSuccessEvent. This is a custom data which can be sent by a server towards client connection in subscribe result. Note that due to the bug in Centrifugo server this feature only works in Centrifugo >= v3.0.3.

[0.7.0]

Update to work with Centrifuge >= v0.18.0 and Centrifugo v3.

Breaking change in server behavior. Client History API behavior changed in Centrifuge >= v0.18.0 and Centrifugo >= v3.0.0. When using history call it won't return all publications in a stream by default. See Centrifuge v0.18.0 release notes or Centrifugo v3 migration guide for more information and workaround on server-side.

  • Protocol definitions updated to the latest version
  • History method now accepts optional limit, since and reverse arguments and returns HistoryResult
  • RPC call now requires method name as first argument (you can pass empty string to mimic previous behavior)
  • Publish now returns PublishResult
  • When working with Centrifugo v3 or Centrifuge >= v0.18.0 it's now possible to avoid using ?format=protobuf in connection URL. Client will negotiate Protobuf protocol with a server using WebSocket subprotocol mechanism (in request headers).

[0.6.0]

Null safety migration

  • library dependencies updated to null safe versions
  • library code updated to support null safety in places where required

See issue #47 and pull request #48 for details.

[0.5.1]

  • Skip handling for events from server-side subscriptions resulted in null pointer dereference

[0.5.0]

  • Update protobuf dependency to ^1.0.1, thanks @Holofox

[0.4.1]

  • Implement removeSubscription method, thanks @tiamo

[0.4.0]

  • Breaking changes connected property removed

[0.3.0]

  • Breaking changes Changed API to avoid returning futures where they do not make sense – in connect and subscribe methods.
  • Client now uses Websocket Ping/Pong frames to find broken connection
  • Support for private channel subscription using onPrivateSub configuration callback function
  • Fix several null pointer dereferences in edge cases, throw ClientDisconnectedError when there is an attempt to send protocol request over non-connected client.
  • Fix examples where subscribe could happen before stream handlers set

[0.2.0]

  • Breaking changes Replaced subscribe method with getSubscription in Client.
  • Added reconnection.
  • Added history method to Subscription. Thanks vanelizarov.
  • Added rpc method.

[0.1.0]

  • Added authorization with JWT
  • Added subscription to private channel with JWT

[0.0.1]

  • Initial release

Installing

export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add centrifuge
pubspec.yaml
name: centrifuge
version: 0.21.0

description: >
  Dart client to communicate with Centrifuge and Centrifugo from Flutter and VM
  over WebSockets

homepage: https://github.com/centrifugal/centrifuge-dart

environment:
  sdk: '>=3.7.0 <4.0.0'

dependencies:
  fixnum: ^1.0.0
  meta: ^1.3.0
  protobuf: ">=5.0.0 <7.0.0"
  web_socket_channel: ">=3.0.0 <4.0.0"

dev_dependencies:
  http: ^1.1.0
  lints: ">=5.1.1 <7.0.0"
  stream_channel: ^2.1.4
  test: ^1.17.4

Version history

VersionPublishedArchiveSHA-256
0.0.1Cached · Upstream SHA-256 matchedDownloaddb3faacd…bd6395
0.1.0Cached · Upstream SHA-256 matchedDownload09f7e4de…6b0b62
0.2.0Cached · Upstream SHA-256 matchedDownload23bb4439…ea7ae6
0.3.0Cached · Upstream SHA-256 matchedDownload3b377680…8aab61
0.4.0Cached · Upstream SHA-256 matchedDownload08e6f397…213fbc
0.4.1Cached · Upstream SHA-256 matchedDownload6bb61dec…98094b
0.5.0Cached · Upstream SHA-256 matchedDownloadfd063805…d18ae1
0.5.1Cached · Upstream SHA-256 matchedDownload60d5f869…941458
0.6.0Cached · Upstream SHA-256 matchedDownloadd219ec9a…037c10
0.7.0Cached · Upstream SHA-256 matchedDownload6548eff6…235e80
0.7.1Cached · Upstream SHA-256 matchedDownload56407e60…13ad2c
0.8.0Cached · Upstream SHA-256 matchedDownload5ac2b57e…b7620a
0.9.0Cached · Upstream SHA-256 matchedDownload1f281a39…016252
0.9.1Cached · Upstream SHA-256 matchedDownload0b9abe02…7ab142
0.9.2Cached · Upstream SHA-256 matchedDownloadc261d991…360df3
0.9.3Cached · Upstream SHA-256 matchedDownload4cd31b8b…bd7d34
0.9.4Cached · Upstream SHA-256 matchedDownloadfda87da9…272ec3
0.10.0Cached · Upstream SHA-256 matchedDownloada278ecc0…d447b3
0.11.0Cached · Upstream SHA-256 matchedDownload26bc8e36…65c5ec
0.12.0Cached · Upstream SHA-256 matchedDownload8a836da8…ea9aef
0.13.0Cached · Upstream SHA-256 matchedDownload8cea9670…6c71c8
0.14.0Cached · Upstream SHA-256 matchedDownloadc35b75c7…4e4d47
0.14.1Cached · Upstream SHA-256 matchedDownload15b9aabc…7e2516
0.15.0Cached · Upstream SHA-256 matchedDownloadbc4e20bc…a8eb01
0.15.1Cached · Upstream SHA-256 matchedDownloadbcd1e205…ccdf09
0.16.0Cached · Upstream SHA-256 matchedDownloadb8b3d3c6…522a6d
0.17.0Cached · Upstream SHA-256 matchedDownload96050368…f97c73
0.18.0Cached · Upstream SHA-256 matchedDownloadfa943928…f530ba
0.19.0Cached · Upstream SHA-256 matchedDownload672d21fa…77253d
0.19.1Cached · Upstream SHA-256 matchedDownload27808466…6446ea
0.20.0Cached · Upstream SHA-256 matchedDownloadfae4f687…b2bc6a
0.20.1Cached · Upstream SHA-256 matchedDownload5f172511…1e177d
0.21.0Cached · Upstream SHA-256 matchedDownload7449dc56…2b7969

Dependencies

fixnum "^1.0.0"

meta "^1.3.0"

protobuf "\u003e=5.0.0 \u003c7.0.0"

web_socket_channel "\u003e=3.0.0 \u003c4.0.0"