diff --git a/.ably/capabilities.yaml b/.ably/capabilities.yaml index a38444fc1..4140330ec 100644 --- a/.ably/capabilities.yaml +++ b/.ably/capabilities.yaml @@ -43,6 +43,7 @@ compliance: Connection: Disconnected Retry Timeout: Get Identifier: + Incremental Backoff: Lifecycle Control: Ping: Recovery: diff --git a/README.md b/README.md index abd0d9f8f..1b2b2b7cf 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ _[Ably](https://ably.com) is the platform that powers synchronized digital experiences in realtime. Whether attending an event in a virtual venue, receiving realtime financial information, or monitoring live car performance data – consumers simply expect realtime digital experiences as standard. Ably provides a suite of APIs to build, extend, and deliver powerful digital experiences in realtime for more than 250 million devices across 80 countries each month. Organizations like Bloomberg, HubSpot, Verizon, and Hopin depend on Ably’s platform to offload the growing complexity of business-critical realtime data synchronization at global scale. For more information, see the [Ably documentation](https://ably.com/docs)._ -This is a .NET client library for Ably. The library currently targets the [Ably 1.1-beta client library specification](https://ably.com/docs/client-lib-development-guide/features). You can jump to the '[Known Limitations](#known-limitations)' section to see the features this client library does not yet support or or [view our client library SDKs feature support matrix](https://ably.com/download/sdk-feature-support-matrix) to see the list of all the available features. +This is a .NET client library for Ably which targets the 2.0 client library specification. You can see the features this client supports in our [feature support matrix](https://sdk.ably.com/builds/ably/ably-dotnet/main/features/). ## Supported platforms @@ -20,53 +20,24 @@ This is a .NET client library for Ably. The library currently targets the [Ably * [Xamarin.Android 8.0+](https://developer.xamarin.com/releases/android/xamarin.android_8/xamarin.android_8.0/) * [Xamarin.iOS 10.14+](https://developer.xamarin.com/releases/ios/xamarin.ios_10/xamarin.ios_10.14/) * Xamarin.Mac 3.8+ - -## Push notification - -The Ably.net library fully supports Ably's push notifications. The feature set consists of two distinct areas: [Push Admin](https://ably.com/docs/general/push/admin), [Device Push Notifications](https://ably.com/docs/realtime/push). - -The [Push Notifications Readme](PushNotifications.md) describes: - -* How to setup Push notifications for Xamarin mobile apps -* How to use the Push Admin api to send push notifications directly to a devices or a client -* How to subscribe to channels that support push notification -* How to send Ably messages that include a notification - -## Unity - -- Unity support is currently in beta. -- Supports both [Mono](https://docs.unity3d.com/Manual/Mono.html) and [IL2CPP](https://docs.unity3d.com/Manual/IL2CPP.html) builds. - -**Downloading Unity Package** -- Please download the latest Unity package from the [GitHub releases page](https://github.com/ably/ably-dotnet/releases/latest). All releases from 1.2.4 has `.unitypackage` included. -- Please take a look at [importing unity package](./unity/README.md#importing-unity-package) doc for initial config. and usage. - -**Supported Platforms** -- Ably Unity SDK supports **Windows, MacOS, Linux, Android and iOS**. -- It doesn't support **WebGL** due to incompatibility with WebSockets. Read the [Direct Socket Access](https://docs.unity3d.com/2019.3/Documentation/Manual/webgl-networking.html) section under WebGL Networking. -- To support **WebGL**, you should refer to [interation with browser javascript from WebGL](https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html). You can import [ably-js](https://github.com/ably/ably-js) as a browser javascript and call it from WebGL. For more information, refer to the project [Ably Tower Defence](https://github.com/ably-labs/ably-tower-defense/tree/js-branch/). - - -**Note** - Please take a look at [Unity README](./unity/README.md) and [Ably Unity Blog](https://ably.com/blog/multiplayer-game-in-unity-with-ably) for more information. - -## Known Limitations -* Browser push notifications in [Blazor](https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor) are not supported. +* Unity 2019.x +, [check README](./unity/README.md) +* Push Notification, [check support section](#push-notification). ## Documentation -Visit `https://ably.com/docs` for a complete API reference and more examples. +Visit [https://ably.com/docs](https://ably.com/docs) for a complete API reference and more examples. ## Installation The client library is available as a [nuget package](https://www.nuget.org/packages/ably.io/). -You can install it from the Package Manager Console using this command +You can install it from the Package Manager Console: ```shell PM> Install-Package ably.io ``` -or using the .NET CLI in your project directory using +or using the .NET CLI in your project directory: ```shell dotnet add package ably.io @@ -74,17 +45,21 @@ dotnet add package ably.io ## Using the Realtime API -### Introduction +The Realtime library is typically used client-side in your applications. It maintains a persistent connection to Ably and is a stateful library. [Find out when you should use the REST or Realtime library](https://faqs.ably.com/should-i-use-the-rest-or-realtime-library). -All examples assume a client has been created as follows: +### Instancing a Realtime client + +Creating a Realtime client: ```csharp // Using basic auth with API key +// Note in production, an API key should not be used in untrusted mobile/browser clients var realtime = new AblyRealtime(""); ``` ```csharp // Using token auth with token string +// Note this token is not renewable - a token callback should be used in production var realtime = new AblyRealtime(new ClientOptions { Token = "token" }); ``` @@ -122,13 +97,15 @@ realtime.Connection.On(args => ### Subscribing to a channel -Create a channel +[Channels](https://ably.com/docs/realtime/channels?lang=javascript) are the medium through which messages are distributed. + +To create a channel object: ```csharp IRealtimeChannel channel = realtime.Channels.Get("test"); ``` -Subscribing to all events: +Subscribe to all events published on that channel: ```csharp channel.Subscribe(message => @@ -167,45 +144,6 @@ channel.On(ChannelState.Attached, args => }); ``` -### Enable logging - -Define a new class that implements `ILoggerSink` interface. - -```csharp -class CustomLogHandler : ILoggerSink -{ - public void LogEvent(LogLevel level, string message) - { - Console.WriteLine($"Handler LogLevel : {level}, Data :{message}"); - } -} -``` - -Update clientOptions for `LogLevel` and `LogHandler`. - -```csharp -clientOpts.LogLevel = LogLevel.Debug; -clientOpts.LogHandler = new CustomLogHandler(); -``` - -### Subscribing to a channel in delta mode - -Subscribing to a channel in delta mode enables [delta compression](https://ably.com/docs/realtime/channels/channel-parameters/deltas). This is a way for a client to subscribe to a channel so that message payloads sent contain only the difference (ie the delta) between the present message and the previous message on the channel. - -Request a `Vcdiff` formatted delta stream using channel options when you get the channel: - -```csharp -var channelParams = new ChannelParams(); -channelParams.Add("delta", "vcdiff"); -var channelOptions = new ChannelOptions(); -channelOptions.Params = channelParams; -IRealtimeChannel channel = ably.Channels.Get(ChannelName, channelOptions); -``` - -Beyond specifying channel options, the rest is transparent and requires no further changes to your application. The `message.Data` instances that are delivered to your `Action` handler continue to contain the values that were originally published. - -If you would like to inspect the `Message` instances in order to identify whether the `Data` they present was rendered from a delta message from Ably then you can see if `Extras.Delta.Format` equals `"vcdiff"`. - ### Publishing to a channel The client support a callback and async publishing. The simplest way to publish is: @@ -280,6 +218,24 @@ foreach (var presence in presenceHistory.Items) var presenceNextPage = await presenceHistory.NextAsync(); ``` +### Subscribing to a channel in delta mode + +Subscribing to a channel in delta mode enables [delta compression](https://ably.com/docs/realtime/channels/channel-parameters/deltas). This is a way for a client to subscribe to a channel so that message payloads sent contain only the difference (ie the delta) between the present message and the previous message on the channel. + +Request a `Vcdiff` formatted delta stream using channel options when you get the channel: + +```csharp +var channelParams = new ChannelParams(); +channelParams.Add("delta", "vcdiff"); +var channelOptions = new ChannelOptions(); +channelOptions.Params = channelParams; +IRealtimeChannel channel = ably.Channels.Get(ChannelName, channelOptions); +``` + +Beyond specifying channel options, the rest is transparent and requires no further changes to your application. The `message.Data` instances that are delivered to your `Action` handler continue to contain the values that were originally published. + +If you would like to inspect the `Message` instances in order to identify whether the `Data` they present was rendered from a delta message from Ably then you can see if `Extras.Delta.Format` equals `"vcdiff"`. + ### Symmetric end-to-end encrypted payloads on a channel When a 128-bit or 256-bit key is provided to the library, all payloads are encrypted and decrypted automatically using that key on the channel. The secret key is never transmitted to Ably and thus it is the developer's responsibility to distribute a secret key to both publishers and subscribers. @@ -302,17 +258,51 @@ encryptedChannel.Publish("name (not encrypted)", "sensitive data (encrypted befo options.CustomContext = SynchronizationContext.Current; ``` +### Increase Transport send and receive buffers + +In .NET Framework projects, we discovered issues with the .NET implementation of the web socket protocol during times of high load with large payloads (over 50kb). This is better described in `https://github.com/ably/ably-dotnet/issues/446` +To work around the problem, you need to adjust websocket library's buffer to it's maximum size of 64kb. Here is an example of how to do it. + +```csharp +var maxBufferSize = 64 * 1024; +var options = new ClientOptions(); +var websocketOptions = new MsWebSocketOptions() { SendBufferInBytes = maxBufferSize, ReceiveBufferInBytes = maxBufferSize }; +options.TransportFactory = new MsWebSocketTransport.TransportFactory(websocketOptions); +var realtime = new AblyRealtime(options); +``` + +## Enable logging + +Define a new class that implements `ILoggerSink` interface. + +```csharp +class CustomLogHandler : ILoggerSink +{ + public void LogEvent(LogLevel level, string message) + { + Console.WriteLine($"Handler LogLevel : {level}, Data :{message}"); + } +} +``` + +Update clientOptions for `LogLevel` and `LogHandler`. + +```csharp +clientOpts.LogLevel = LogLevel.Debug; +clientOpts.LogHandler = new CustomLogHandler(); +``` + ## Using the REST API -### Introduction +The REST library is typically used server-side in your applications and is stateless. [Find out when you should use the REST or Realtime library](https://faqs.ably.com/should-i-use-the-rest-or-realtime-library). -The rest client provides a fully async wrapper around the Ably service web api. +### Instancing a REST client -All examples assume a client and/or channel has been created as follows: +Creating a REST client and channel: ```csharp var client = new AblyRest(""); -IRealtimeChannel channel = client.Channels.Get("test"); +IRealtimeChannel channel = client.Channels.Get("chat"); ``` If you do not have an API key, [sign up for a free API key now](https://ably.com/signup) @@ -437,7 +427,7 @@ DateTimeOffset time = await client.TimeAsync(); ### Getting the channel status -Getting the current status of a channel, including details of the current number of `Publishers`, `Subscribers` and `PresenceMembers` etc is simple +Getting the current status of a channel, including details of the current number of `Publishers`, `Subscribers` and `PresenceMembers` etc: ```csharp ChannelDetails details = await channel.StatusAsync(); @@ -446,9 +436,10 @@ ChannelMetrics metrics = details.Status.Occupancy.Metrics; ``` ### Making explicit HTTP requests to Ably Rest Endpoints / Batch publish -- The `AblyRest->Request` method should be used to make explicit HTTP requests. +- The `AblyRest->Request` method can be used to make explicit HTTP requests to the [Ably REST API](https://ably.com/docs/api/rest-api). - It automatically adds necessary auth headers based on the initial auth config and supports pagination. - The following is an example of using the batch publish API based on the [Ably batch publish rest endpoint documentation](https://ably.com/docs/api/rest-api#batch-publish). + ```csharp var objectPayload = new { @@ -465,39 +456,14 @@ ChannelMetrics metrics = details.Status.Occupancy.Metrics; var jsonPayload = JsonConvert.SerializeObject(objectPayload); var paginatedResponse = await ablyRest.RequestV2(HttpMethod.Post, "/messages", null, jsonPayload, null); ``` -- Follow official [ably rest endpoint doc](https://ably.com/docs/api/rest-api) for more information on other endpoints. - -### Increase Transport send and receive buffers - -In .NET Framework projects, we discovered issues with the .NET implementation of the web socket protocol during times of high load with large payloads (over 50kb). This is better described in `https://github.com/ably/ably-dotnet/issues/446` -To work around the problem, you need to adjust websocket library's buffer to it's maximum size of 64kb. Here is an example of how to do it. - -```csharp -var maxBufferSize = 64 * 1024; -var options = new ClientOptions(); -var websocketOptions = new MsWebSocketOptions() { SendBufferInBytes = maxBufferSize, ReceiveBufferInBytes = maxBufferSize }; -options.TransportFactory = new MsWebSocketTransport.TransportFactory(websocketOptions); -var realtime = new AblyRealtime(options); -``` +- See the [ably rest endpoint doc](https://ably.com/docs/api/rest-api) for more information on other endpoints. -### MAUI configuration -- Since `ably-dotnet` makes use of the reflection API, MAUI assembly trimming may cause issues. -- When using MAUI, we recommend adding the following to your `.csproj` file to disable assembly trimming. - -```xml - - - -``` -- For more information related to assembly trimming, check [MAUI trimming doc](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options). -- To resolve issues related to iOS signed release, [update csproj config](https://github.com/ably/ably-dotnet/issues/1259#issuecomment-1723307985) - -### Examples +## Examples * More Examples can be found under ```examples``` directory. * While working with console app, make sure to put explicit await for async methods. -#### Sample .NET Core implementation +### Sample .NET Core implementation ```csharp using System; @@ -520,7 +486,7 @@ namespace testing_ably_console } ``` -#### Sample .NET Framework implementation (when you don't have async main method)* +### Sample .NET Framework implementation (when you don't have async main method)* ```csharp using System; @@ -547,6 +513,33 @@ namespace testing_ably_console } ``` +## MAUI configuration +- Since `ably-dotnet` makes use of the reflection API, MAUI assembly trimming may cause issues. +- When using MAUI, we recommend adding the following to your `.csproj` file to disable assembly trimming. + +```xml + + + +``` +- For more information related to assembly trimming, check [MAUI trimming doc](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options). +- To resolve issues related to iOS signed release, [update csproj config](https://github.com/ably/ably-dotnet/issues/1259#issuecomment-1723307985) + +## Push notification + +The Ably.net library fully supports Ably's push notifications. The feature set consists of two distinct areas: [Push Admin](https://ably.com/docs/general/push/admin), [Device Push Notifications](https://ably.com/docs/realtime/push). + +The [Push Notifications Readme](PushNotifications.md) describes: + +* How to setup Push notifications for Xamarin mobile apps. +* How to use the Push Admin api to send push notifications directly to a devices or a client. +* How to subscribe to channels that support push notification. +* How to send Ably messages that include a notification. + +### Known Limitations +* Browser push notifications in [Blazor](https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor) are not supported. + + ## Dependencies This library has dependencies that can differ depending on the target platform. diff --git a/unity/README.md b/unity/README.md index 77506509a..efa2a8337 100644 --- a/unity/README.md +++ b/unity/README.md @@ -1,13 +1,6 @@ # Ably Unity SDK -- Unity support is currently in beta. - Supports both [Mono](https://docs.unity3d.com/Manual/Mono.html) and [IL2CPP](https://docs.unity3d.com/Manual/IL2CPP.html) builds. - -Considerations: -* We are actively working towards automated testing by integrating Unity Cloud Build into our .NET CI pipeline. -* Installation requires developers to import a custom Unity package that includes all of Ably's dependencies. - -### Supported Platforms -- Windows, MacOS, Linux, Android and iOS. +- Supports **Windows**, **MacOS**, **Linux**, **Android** and **iOS**. ### System Requirements * Unity 2019.x.x or newer @@ -70,11 +63,13 @@ namespace Example.ChatApp } } ``` -- Please take a look at [Unity Demo Chat App](./Assets/Ably/Examples/Chat/) to see a functioning Ably SDK setup. +- Please take a look at [Unity demo chat app](./Assets/Ably/Examples/Chat/) to see a functioning Ably SDK setup. +- Also check blog on [Multiplayer game in unity with ably](https://ably.com/blog/multiplayer-game-in-unity-with-ably). ### Unsupported Platforms -- WebGL: Due to incompatibility with WebSockets.
-For more information on this, read the [Direct Socket Access](https://docs.unity3d.com/2019.3/Documentation/Manual/webgl-networking.html) section under WebGL Networking in the Unity documentation. +- It doesn't support **WebGL** due to incompatibility with WebSockets. Read the [Direct Socket Access](https://docs.unity3d.com/2019.3/Documentation/Manual/webgl-networking.html) section under WebGL Networking. We have active issue to add support for the same https://github.com/ably/ably-dotnet/issues/1211. +- To support **WebGL**, you should refer to [interation with browser javascript from WebGL](https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html). You can import [ably-js](https://github.com/ably/ably-js) as a browser javascript and call it from WebGL. For more information, refer to the project [Ably Tower Defence](https://github.com/ably-labs/ably-tower-defense/tree/js-branch/). + ### Contributing - Please take a look at the [contributing doc](CONTRIBUTING.md) for information relating to local development setup, writing and running tests.