From 0f56cc7d83e7a09ac83dda9d66b13b5fdc168e85 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Fri, 20 Jan 2017 18:25:37 +0100 Subject: [PATCH 01/19] Bump working 0.9 version to 1.0 release version --- .../features.textile | 16 ++++++++-------- content/realtime/usage.textile | 2 +- content/rest-api/index.textile | 6 +++--- content/rest/usage.textile | 2 +- docs.gemspec | 4 ++-- lib/helpers/versions_helper.rb | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/content/client-lib-development-guide/features.textile b/content/client-lib-development-guide/features.textile index 80f96e4814..3c723999da 100644 --- a/content/client-lib-development-guide/features.textile +++ b/content/client-lib-development-guide/features.textile @@ -42,7 +42,7 @@ h2(#test-guidelines). Test guidelines * @(G1)@ Every test should be executed using all supported protocols (i.e. JSON and "MessagePack":http://msgpack.org/ if supported). This includes both sending & receiving data * @(G2)@ All tests by default are run against a special Ably sandbox environment. This environment allows apps to be provisioned without any authentication that can then be used for client library testing. Bear in mind that all apps created in the sandbox environment are automatically deleted after 60 minutes and have low limits to prevent abuse. Apps are configured by sending a @POST@ request to @https://sandbox-rest.ably.io/apps@ with a JSON body that specifies the keys and their associated capabilities, channel namespace rules and any presence fixture data that is required; see "ably-common test-app-setup.json":https://github.com/ably/ably-common/blob/master/test-resources/test-app-setup.json. Presence fixture data is necessary for the REST library presence tests as there is no way to register presence on a channel in the REST library * @(G3)@ Testing statistics can be tricky due to timing issues and slow test suites as a result of sending requests to generate statistics. As such, we provide a special stats endpoint in our sandbox environment that allows stats to be injected into our metrics system so that stats tests can make predictable assertions. To create stats you must send an authenticated @POST@ request to the stats JSON to @https://sandbox-rest.ably.io/stats@ with the stats data you wish to create. See the "Javascript stats fixture":https://github.com/ably/ably-js/blob/4e65d4e13eb8750a375b9511e4dd059092c0e481/spec/rest/stats.test.js#L8-L51 and "setup helper":https://github.com/ably/ably-js/blob/4e65d4e13eb8750a375b9511e4dd059092c0e481/spec/common/modules/testapp_manager.js#L158-L182 as an example -* @(G4)@ All REST requests and WebSocket connections to Ably must include the current API version @0.9@. Should any new API version with breaking changes be released, the client library will continue to use the API version explicitly requested +* @(G4)@ All REST requests and WebSocket connections to Ably must include the current API version @1.0@. Should any new API version with breaking changes be released, the client library will continue to use the API version explicitly requested h2(#rest). REST client library @@ -62,9 +62,9 @@ h3(#restclient). RestClient *** @(RSC6b4)@ @unit@ is the period for which the stats will be aggregated by, values supported are @minute@, @hour@, @day@ or @month@; if omitted the unit defaults to the REST API default (@minute@) * @(RSC16)@ @RestClient#time@ function sends a get request to @rest.ably.io/time@ and returns the server time in milliseconds since epoch or as a Date/Time object where suitable * @(RSC7)@ Sends REST requests over HTTP and HTTPS to the REST endpoint @rest.ably.io@ -** @(RSC7a)@ The header @X-Ably-Version: 0.9@ must be included in all REST requests to the Ably endpoint -** @(RSC7b)@ The header @X-Ably-Lib: [lib][.optional variant]?-[version]@ should be included in all REST requests to the Ably endpoint where @[lib]@ is the name of the library such as @js@ for @ably-js@, @[.optional variant]@ is an optional library variant, such as @laravel@ for the @php@ library, which is always delimited with a period such as @php.laravel@, and where @[version]@ is the full client library version using "Semver":http://semver.org/ such as @0.9.2@. For example, the 0.9.0 version of the Javascript library would use the header @X-Ably-Lib: js-0.9.0@ -*** @(RSC7b1)@ When it is not possible to send the @X-Ably-Lib@ header, such as for @JSONP@ requests, the library version should be sent as a query param such as @lib=js-0.9.0@ +** @(RSC7a)@ The header @X-Ably-Version: 1.0@ must be included in all REST requests to the Ably endpoint +** @(RSC7b)@ The header @X-Ably-Lib: [lib][.optional variant]?-[version]@ should be included in all REST requests to the Ably endpoint where @[lib]@ is the name of the library such as @js@ for @ably-js@, @[.optional variant]@ is an optional library variant, such as @laravel@ for the @php@ library, which is always delimited with a period such as @php.laravel@, and where @[version]@ is the full client library version using "Semver":http://semver.org/ such as @1.0.2@. For example, the 1.0.0 version of the Javascript library would use the header @X-Ably-Lib: js-1.0.0@ +*** @(RSC7b1)@ When it is not possible to send the @X-Ably-Lib@ header, such as for @JSONP@ requests, the library version should be sent as a query param such as @lib=js-1.0.0@ * @(RSC18)@ If @ClientOptions#tls@ is true, then all communication is over HTTPS. If false, all communication is over HTTP however "Basic Auth":https://en.wikipedia.org/wiki/Basic_access_authentication over HTTP will result in an error as private keys cannot be submitted over an insecure connection. See @Auth@ below * @(RSC8)@ Supports two protocols: ** @(RSC8a)@ "MessagePack":http://msgpack.org/ binary protocol (this is the default for environments having a suitable level or support for binary data) @@ -293,8 +293,8 @@ h3(#realtime-connection). Connection ** @(RTN2b)@ @echo@ should be @true@ by default; @false@ will prevent messages published by the client being echoed back ** @(RTN2d)@ @clientId@ contains the provided @clientId@ option of @ClientOptions@, unless @clientId@ is @null@ ** @(RTN2e)@ Depending on the authentication scheme, either @accessToken@ contains the token string, or @key@ contains the API key -** @(RTN2f)@ API version param @v@ should be @0.9@ -** @(RTN2g)@ Library and version param @lib@ should include the header value described in "RSC7b":#RSC7b. For example, the 0.9.0 version of the Javascript library would use the param @lib=js-0.9.0@ +** @(RTN2f)@ API version param @v@ should be @1.0@ +** @(RTN2g)@ Library and version param @lib@ should include the header value described in "RSC7b":#RSC7b. For example, the 1.0.0 version of the Javascript library would use the param @lib=js-1.0.0@ * @(RTN3)@ If connection option @autoConnect@ is true, a connection is initiated immediately; otherwise a connection is only initiated following an explicit call to @connect()@ * @(RTN4)@ The @Connection@ implements @EventEmitter@ and emits @ConnectionEvent@ events ** @(RTN4a)@ It emits a @ConnectionState@ event (one of @INITIALIZED@, @CONNECTING@, @CONNECTED@, @DISCONNECTED@, @SUSPENDED@, @CLOSING@, @CLOSED@, @FAILED@) for every connection state change @@ -874,7 +874,7 @@ h4. Message ** @(TM2g)@ @name@ string ** @(TM2d)@ @data@ string, buffer or JSON-encodable object or array ** @(TM2e)@ @encoding@ string -** @(TM2i)@ @extras@ JSON-encodable object, used to contain any arbitrary key value pairs which may also contain other primitive JSON types, JSON-encodable objects or JSON-encodable arrays. The extras field is provided to contain message metadata and/or ancillary payloads in support of specific functionality, e.g. push. Each of these supported extensions is documented separately; for 0.9 the only supported extension is @push@, via the @extras.push@ member. The processing of any other members is undefined +** @(TM2i)@ @extras@ JSON-encodable object, used to contain any arbitrary key value pairs which may also contain other primitive JSON types, JSON-encodable objects or JSON-encodable arrays. The extras field is provided to contain message metadata and/or ancillary payloads in support of specific functionality, e.g. push. Each of these supported extensions is documented separately; for 1.0 the only supported extension is @push@, via the @extras.push@ member. The processing of any other members is undefined ** @(TM2f)@ @timestamp@ time in milliseconds since epoch. If a message received from Ably does not contain a @timestamp@, it should be set to the @timestamp@ of the encapsulating @ProtocolMessage@ * @(TM3)@ @fromEncoded@ and @fromEncodedArray@ are alternative constructors that take an (already deserialized) @Message@-like object (or array of such objects), and optionally a @channelOptions@, and return a @Message@ (or array of such @Messages@) that's decoded and decrypted as specified in @RSL6@, using the cipher in the @channelOptions@ if the message is encrypted, with any residual transforms (ones that the library cannot decode or decrypt) left in the @encoding@ property per @RSL6b@. This is intended for users receiving messages other than from a REST or Realtime channel (for example, from a queue), to avoid them having to parse the @encoding@ string themselves. @@ -1509,4 +1509,4 @@ h2(#old-specs). Old specs Use the version navigation to view older versions. References to diffs for each version are maintained below: -* v0.8 deprecated in Jan 2017. "View 0.8 → 0.9 changes":https://github.com/ably/docs/blob/source/content/client-lib-development-guide/versions/features-0-8__0-9.diff +* v0.8 deprecated in Jan 2017. "View 0.8 → 1.0 changes":https://github.com/ably/docs/blob/source/content/client-lib-development-guide/versions/features-0-8__1-0.diff diff --git a/content/realtime/usage.textile b/content/realtime/usage.textile index 1fef3d2571..87dc8ac134 100644 --- a/content/realtime/usage.textile +++ b/content/realtime/usage.textile @@ -48,7 +48,7 @@ blang[javascript]. var realtime = new Ably.Realtime({ key: apiKey }); ``` - When referencing the client library from our CDN, we recommend that you include a major version number in the URL so that breaking changes, according to the "semantic versioning scheme":http://semver.org/, are never mistakenly used. For example, if you want to ensure that you only use the @MAJOR@ version @0@, then use "@https://cdn.ably.io/lib/ably.min-0.js@":https://cdn.ably.io/lib/ably.min-0.js. If you want to ensure that the @MINOR@ version @0.9@ is used, then use "@https://cdn.ably.io/lib/ably.min-0.9.js@":https://cdn.ably.io/lib/ably.min-0.9.js. Additionally, the @.min@ suffix can be dropped if you specifically want to use the non-minified version for debugging. + When referencing the client library from our CDN, we recommend that you include a major version number in the URL so that breaking changes, according to the "semantic versioning scheme":http://semver.org/, are never mistakenly used. For example, if you want to ensure that you only use the @MAJOR@ version @0@, then use "@https://cdn.ably.io/lib/ably.min-0.js@":https://cdn.ably.io/lib/ably.min-0.js. If you want to ensure that the @MINOR@ version @1.0@ is used, then use "@https://cdn.ably.io/lib/ably.min-1.0.js@":https://cdn.ably.io/lib/ably.min-1.0.js. Additionally, the @.min@ suffix can be dropped if you specifically want to use the non-minified version for debugging. "View a complete list of the Javascript library releases":https://github.com/ably/ably-js/releases diff --git a/content/rest-api/index.textile b/content/rest-api/index.textile index 79f54ee69f..6c47752e10 100644 --- a/content/rest-api/index.textile +++ b/content/rest-api/index.textile @@ -127,18 +127,18 @@ Wherever possible, success response bodies contain links, in "HATEOS":http://en. h3(#versioning). Versioning -By default, all requests receive the latest version of the API, which is currently @0.9@. +By default, all requests receive the latest version of the API, which is currently @1.0@. When we make backwards-incompatible API changes to the API, we release new versions. Therefore, we encourage you to explicitly request the version you are interfacing with in all requests using one of the following mechanisms: 1. Include a @X-Ably-Version@ header. Example: bc[sh]. curl https://rest.ably.io/time \ - -H "X-Ably-Version: 0.9" + -H "X-Ably-Version: 1.0" 2. Include the version query string param @v@. Example: -bc[sh]. curl https://rest.ably.io/time?v=0.9 +bc[sh]. curl https://rest.ably.io/time?v=1.0 h3(#pagination). Pagination diff --git a/content/rest/usage.textile b/content/rest/usage.textile index 9b93702dab..a5ef19cf83 100644 --- a/content/rest/usage.textile +++ b/content/rest/usage.textile @@ -46,7 +46,7 @@ blang[javascript]. var rest = new Ably.Rest({ key: apiKey }); ``` - When referencing the client library from our CDN, we recommend that you include a major version number in the URL so that breaking changes, according to the "semantic versioning scheme":http://semver.org/, are never mistakenly used. For example, if you want to ensure that you only use the @MAJOR@ version @0@, then use "@https://cdn.ably.io/lib/ably.min-0.js@":https://cdn.ably.io/lib/ably.min-0.js. If you want to ensure that the @MINOR@ version @0.9@ is used, then use "@https://cdn.ably.io/lib/ably.min-0.9.js@":https://cdn.ably.io/lib/ably.min-0.9.js. Additionally, the @.min@ suffix can be dropped if you specifically want to use the non-minified version for debugging. + When referencing the client library from our CDN, we recommend that you include a major version number in the URL so that breaking changes, according to the "semantic versioning scheme":http://semver.org/, are never mistakenly used. For example, if you want to ensure that you only use the @MAJOR@ version @0@, then use "@https://cdn.ably.io/lib/ably.min-0.js@":https://cdn.ably.io/lib/ably.min-0.js. If you want to ensure that the @MINOR@ version @1.0@ is used, then use "@https://cdn.ably.io/lib/ably.min-1.0.js@":https://cdn.ably.io/lib/ably.min-1.0.js. Additionally, the @.min@ suffix can be dropped if you specifically want to use the non-minified version for debugging. "View a complete list of the Javascript library releases":https://github.com/ably/ably-js/releases diff --git a/docs.gemspec b/docs.gemspec index ba703e4080..dd1e8bee6f 100644 --- a/docs.gemspec +++ b/docs.gemspec @@ -1,8 +1,8 @@ Gem::Specification.new do |spec| spec.name = 'ably-docs' - spec.version = '0.9.0' + spec.version = '1.0.0' spec.authors = ["Matthew O'Riordan"] - spec.email = ['matt@ably.io'] + spec.email = ['support@ably.io'] spec.description = %q{Documentation repository Gem for Ably} spec.summary = %q{Allows the Ably documentation Textile files to be accessed by other Ruby applications} spec.homepage = 'http://github.com/ably/docs' diff --git a/lib/helpers/versions_helper.rb b/lib/helpers/versions_helper.rb index 5f56a7275e..0bbe1b7206 100644 --- a/lib/helpers/versions_helper.rb +++ b/lib/helpers/versions_helper.rb @@ -1,5 +1,5 @@ module VersionsHelper - CURRENT_VERSION = '0.9' unless defined?(CURRENT_VERSION) + CURRENT_VERSION = '1.0' unless defined?(CURRENT_VERSION) VERSIONED_FOLDERS = %w( client-lib-development-guide From 31368de26a1efaf885143318e4e88d28ea226d9e Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Fri, 20 Jan 2017 18:58:01 +0100 Subject: [PATCH 02/19] api: Lock into a major version for Javascript always Do not allow people to use the CDN without a major version so that we have the flexibility moving forwards to introduce breaking changes with major version releases. --- .../code/authentication/auth-callback.code | 2 +- content/code/authentication/basic-auth.code | 2 +- content/code/authentication/capabilities.code | 2 +- .../authentication/create-token-request.code | 2 +- .../code/authentication/request-token.code | 2 +- .../client-lib-development-guide/example.code | 2 +- content/code/quick-start-guide/connect.code | 2 +- .../code/quick-start-guide/send-message.code | 2 +- content/code/realtime/auth-client-id.code | 2 +- .../code/realtime/auth-token-callback.code | 2 +- content/code/realtime/channel-encrypted.code | 2 +- .../channel-history-until-attach.code | 2 +- content/code/realtime/channel-history.code | 2 +- content/code/realtime/channel-implicit.code | 2 +- content/code/realtime/channel-publish.code | 2 +- content/code/realtime/channel-states.code | 2 +- content/code/realtime/channel.code | 2 +- content/code/realtime/connection-states.code | 2 +- content/code/realtime/connection.code | 2 +- content/code/realtime/presence-events.code | 2 +- .../realtime/presence-multiple-client-id.code | 2 +- content/code/realtime/presence-simple.code | 2 +- content/code/realtime/stats.code | 2 +- content/code/rest/channel-history.code | 2 +- content/code/rest/channel-publish.code | 2 +- .../rest/publish-on-behalf-of-client.code | 2 +- content/code/rest/stats.code | 2 +- .../code/website-examples/angular-todo.code | 2 +- .../code/website-examples/backbone-todo.code | 2 +- content/code/website-examples/ember-todo.code | 2 +- content/code/website-examples/home-page.code | 2 +- .../website-examples/simple-chat.code.erb | 2 +- content/realtime/usage.textile | 4 +- content/realtime/versions/v0.8/usage.textile | 4 +- content/rest/usage.textile | 4 +- content/rest/versions/v0.8/usage.textile | 4 +- content/root/quick-start-guide.textile | 4 +- content/tutorials/history.textile | 4 +- content/tutorials/presence.textile | 4 +- content/tutorials/publish-subscribe.textile | 8 +- .../tutorials/token-authentication.textile | 2 +- data/jsbins.yaml | 134 +++++++++--------- layouts/_head.html.erb | 2 +- 43 files changed, 118 insertions(+), 120 deletions(-) diff --git a/content/code/authentication/auth-callback.code b/content/code/authentication/auth-callback.code index cfa5aba4ed..450e2979e9 100644 --- a/content/code/authentication/auth-callback.code +++ b/content/code/authentication/auth-callback.code @@ -23,7 +23,7 @@ $('input#connect').on('click', function() { [--- /Javascript ---] [--- HTML ---] - +

Ably authCallback example

diff --git a/content/code/authentication/basic-auth.code b/content/code/authentication/basic-auth.code index 2c1b402b02..c417a26583 100644 --- a/content/code/authentication/basic-auth.code +++ b/content/code/authentication/basic-auth.code @@ -14,7 +14,7 @@ $('input#connect').on('click', function() { [--- /Javascript ---] [--- HTML ---] - +

Ably Basic Auth Example

diff --git a/content/code/authentication/capabilities.code b/content/code/authentication/capabilities.code index f811f9d40b..ab3da2c6e7 100644 --- a/content/code/authentication/capabilities.code +++ b/content/code/authentication/capabilities.code @@ -107,7 +107,7 @@ function scrollBottom() { [--- /Javascript ---] [--- HTML ---] - +

Ably Capabilities Example

diff --git a/content/code/authentication/create-token-request.code b/content/code/authentication/create-token-request.code index ec9ad1c77b..1d1e55c018 100644 --- a/content/code/authentication/create-token-request.code +++ b/content/code/authentication/create-token-request.code @@ -32,7 +32,7 @@ $('input#connect').on('click', function() { [--- /Javascript ---] [--- HTML ---] - +

Ably Signed Token Request Example

diff --git a/content/code/authentication/request-token.code b/content/code/authentication/request-token.code index 4b58d5e4e4..593f659271 100644 --- a/content/code/authentication/request-token.code +++ b/content/code/authentication/request-token.code @@ -28,7 +28,7 @@ $('input#connect').on('click', function() { [--- /Javascript ---] [--- HTML ---] - +

Ably Request Token Example

diff --git a/content/code/client-lib-development-guide/example.code b/content/code/client-lib-development-guide/example.code index e86f4b029f..e97373a04e 100644 --- a/content/code/client-lib-development-guide/example.code +++ b/content/code/client-lib-development-guide/example.code @@ -7,7 +7,7 @@ ably.connection.on('connected', function() { [--- /Javascript ---] [--- HTML ---] - +

Ably Quickstart Connect Example

[--- /HTML ---] diff --git a/content/code/quick-start-guide/connect.code b/content/code/quick-start-guide/connect.code index 44b67e14cd..d5274c8e73 100644 --- a/content/code/quick-start-guide/connect.code +++ b/content/code/quick-start-guide/connect.code @@ -7,7 +7,7 @@ ably.connection.on('connected', function() { [--- /Javascript ---] [--- HTML ---] - +

Ably Quickstart Connect Example

diff --git a/content/code/quick-start-guide/send-message.code b/content/code/quick-start-guide/send-message.code index 002b4944c8..9f6fb92bdc 100644 --- a/content/code/quick-start-guide/send-message.code +++ b/content/code/quick-start-guide/send-message.code @@ -17,7 +17,7 @@ $('input[type=button]').on('click', function() { [--- HTML ---] - +

Ably Quickstart Publish & Subscribe Example

diff --git a/content/code/realtime/auth-client-id.code b/content/code/realtime/auth-client-id.code index dbc3e26ff4..3d73d50431 100644 --- a/content/code/realtime/auth-client-id.code +++ b/content/code/realtime/auth-client-id.code @@ -47,7 +47,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Auth Client ID Example

diff --git a/content/code/realtime/auth-token-callback.code b/content/code/realtime/auth-token-callback.code index 3d895a7889..8f8075fb1e 100644 --- a/content/code/realtime/auth-token-callback.code +++ b/content/code/realtime/auth-token-callback.code @@ -29,7 +29,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Auth Token Example

diff --git a/content/code/realtime/channel-encrypted.code b/content/code/realtime/channel-encrypted.code index bbd5fb9a08..ba271d873d 100644 --- a/content/code/realtime/channel-encrypted.code +++ b/content/code/realtime/channel-encrypted.code @@ -48,7 +48,7 @@ function arrayBufferToHex(arrayBuffer) { [--- /Javascript ---] [--- HTML ---] - +

Ably Encrypted Channel Example

diff --git a/content/code/realtime/channel-history-until-attach.code b/content/code/realtime/channel-history-until-attach.code index 544e86f0bf..d7ef36646e 100644 --- a/content/code/realtime/channel-history-until-attach.code +++ b/content/code/realtime/channel-history-until-attach.code @@ -59,7 +59,7 @@ $('input#history').on('click', attachAndGetHistory); [--- /Javascript ---] [--- HTML ---] - +

Ably Channel History Example

diff --git a/content/code/realtime/channel-history.code b/content/code/realtime/channel-history.code index 638771ddc4..86df95a8c6 100644 --- a/content/code/realtime/channel-history.code +++ b/content/code/realtime/channel-history.code @@ -46,7 +46,7 @@ $('input#history').on('click', getHistory); [--- /Javascript ---] [--- HTML ---] - +

Ably Channel History Example

diff --git a/content/code/realtime/channel-implicit.code b/content/code/realtime/channel-implicit.code index 93657a0795..4b22a368c7 100644 --- a/content/code/realtime/channel-implicit.code +++ b/content/code/realtime/channel-implicit.code @@ -26,7 +26,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Implicit Attach Channel Example

diff --git a/content/code/realtime/channel-publish.code b/content/code/realtime/channel-publish.code index f2ad98a998..5030604e26 100644 --- a/content/code/realtime/channel-publish.code +++ b/content/code/realtime/channel-publish.code @@ -24,7 +24,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Channel Example

diff --git a/content/code/realtime/channel-states.code b/content/code/realtime/channel-states.code index e5cb9c64ee..3bffda222a 100644 --- a/content/code/realtime/channel-states.code +++ b/content/code/realtime/channel-states.code @@ -24,7 +24,7 @@ function logState(currentState) { [--- HTML ---] - +

Ably Realtime Channel States Example

Channel state history

diff --git a/content/code/realtime/channel.code b/content/code/realtime/channel.code index 1af7b377de..a0015bb7fb 100644 --- a/content/code/realtime/channel.code +++ b/content/code/realtime/channel.code @@ -29,7 +29,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Channel Example

diff --git a/content/code/realtime/connection-states.code b/content/code/realtime/connection-states.code index 85000dacc2..97c818619b 100644 --- a/content/code/realtime/connection-states.code +++ b/content/code/realtime/connection-states.code @@ -22,7 +22,7 @@ function logState(currentState, stateChangeObj) { [--- HTML ---] - +

Ably Realtime Connection States Example

Connection state history

diff --git a/content/code/realtime/connection.code b/content/code/realtime/connection.code index 18e8222535..9a8923910d 100644 --- a/content/code/realtime/connection.code +++ b/content/code/realtime/connection.code @@ -22,7 +22,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Connection Example

diff --git a/content/code/realtime/presence-events.code b/content/code/realtime/presence-events.code index 47cffaa8d1..b0b110ed17 100644 --- a/content/code/realtime/presence-events.code +++ b/content/code/realtime/presence-events.code @@ -42,7 +42,7 @@ function append(message, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Presence Example

diff --git a/content/code/realtime/presence-multiple-client-id.code b/content/code/realtime/presence-multiple-client-id.code index 7854835e83..d8c7efbff8 100644 --- a/content/code/realtime/presence-multiple-client-id.code +++ b/content/code/realtime/presence-multiple-client-id.code @@ -29,7 +29,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Presence Example

diff --git a/content/code/realtime/presence-simple.code b/content/code/realtime/presence-simple.code index 2eea25fdcd..e4a8a389af 100644 --- a/content/code/realtime/presence-simple.code +++ b/content/code/realtime/presence-simple.code @@ -24,7 +24,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Presence Example

diff --git a/content/code/realtime/stats.code b/content/code/realtime/stats.code index f82976be17..df373315b3 100644 --- a/content/code/realtime/stats.code +++ b/content/code/realtime/stats.code @@ -44,7 +44,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Stats Example

diff --git a/content/code/rest/channel-history.code b/content/code/rest/channel-history.code index 572739b5a4..af7980e180 100644 --- a/content/code/rest/channel-history.code +++ b/content/code/rest/channel-history.code @@ -46,7 +46,7 @@ $('input#history').on('click', getHistory); [--- /Javascript ---] [--- HTML ---] - +

Ably REST History Example

diff --git a/content/code/rest/channel-publish.code b/content/code/rest/channel-publish.code index b38ddca9a4..d8b4238862 100644 --- a/content/code/rest/channel-publish.code +++ b/content/code/rest/channel-publish.code @@ -20,7 +20,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably REST Publish Example

diff --git a/content/code/rest/publish-on-behalf-of-client.code b/content/code/rest/publish-on-behalf-of-client.code index 9432eedb3d..d3fff60cd0 100644 --- a/content/code/rest/publish-on-behalf-of-client.code +++ b/content/code/rest/publish-on-behalf-of-client.code @@ -51,7 +51,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably: Publishing over REST on behalf of a Realtime client example

diff --git a/content/code/rest/stats.code b/content/code/rest/stats.code index fc0b9f8a7e..d7371e8c64 100644 --- a/content/code/rest/stats.code +++ b/content/code/rest/stats.code @@ -40,7 +40,7 @@ function show(status, color) { [--- /Javascript ---] [--- HTML ---] - +

Ably Stats Example

diff --git a/content/code/website-examples/angular-todo.code b/content/code/website-examples/angular-todo.code index 68f8c06e35..d626a4e6ba 100644 --- a/content/code/website-examples/angular-todo.code +++ b/content/code/website-examples/angular-todo.code @@ -110,7 +110,7 @@ function toDoEntry() { - + diff --git a/content/code/website-examples/backbone-todo.code b/content/code/website-examples/backbone-todo.code index 3344034144..36bce28ef7 100644 --- a/content/code/website-examples/backbone-todo.code +++ b/content/code/website-examples/backbone-todo.code @@ -105,7 +105,7 @@ $(function() { - + diff --git a/content/code/website-examples/ember-todo.code b/content/code/website-examples/ember-todo.code index c34af271ee..e3fe427838 100644 --- a/content/code/website-examples/ember-todo.code +++ b/content/code/website-examples/ember-todo.code @@ -113,7 +113,7 @@ App.CreateToDoButtonView = Ember.Button.extend({ - + diff --git a/content/code/website-examples/home-page.code b/content/code/website-examples/home-page.code index b19e70a3f2..3d3b02d4e7 100644 --- a/content/code/website-examples/home-page.code +++ b/content/code/website-examples/home-page.code @@ -16,7 +16,7 @@ function show(status) { [--- /Javascript ---] [--- HTML ---] - +

Ably: Simple API Example

diff --git a/content/code/website-examples/simple-chat.code.erb b/content/code/website-examples/simple-chat.code.erb index 578af5de12..a53dce7a63 100644 --- a/content/code/website-examples/simple-chat.code.erb +++ b/content/code/website-examples/simple-chat.code.erb @@ -44,7 +44,7 @@ $(function() { - + diff --git a/content/realtime/usage.textile b/content/realtime/usage.textile index 87dc8ac134..1301565b74 100644 --- a/content/realtime/usage.textile +++ b/content/realtime/usage.textile @@ -37,7 +37,7 @@ blang[javascript]. The Realtime library for browser Javascript environments should be loaded from the Ably CDN as follows: ```[javascript] - + ``` You can also obtain the library as an "NPM module":https://www.npmjs.com/package/ably, or download the source directly from "Github":https://github.com/ably/ably-js @@ -48,7 +48,7 @@ blang[javascript]. var realtime = new Ably.Realtime({ key: apiKey }); ``` - When referencing the client library from our CDN, we recommend that you include a major version number in the URL so that breaking changes, according to the "semantic versioning scheme":http://semver.org/, are never mistakenly used. For example, if you want to ensure that you only use the @MAJOR@ version @0@, then use "@https://cdn.ably.io/lib/ably.min-0.js@":https://cdn.ably.io/lib/ably.min-0.js. If you want to ensure that the @MINOR@ version @1.0@ is used, then use "@https://cdn.ably.io/lib/ably.min-1.0.js@":https://cdn.ably.io/lib/ably.min-1.0.js. Additionally, the @.min@ suffix can be dropped if you specifically want to use the non-minified version for debugging. + When including the client library from our CDN, we recommend you lock into major version @1@ of the library. According to the "semantic versioning scheme":http://semver.org/ we adopt, you will then automatically receive minor and patch updates but you will never receive breaking changes. For example, if you lock into major version @1@ of the library by including "@https://cdn.ably.io/lib/ably.min-1.js@":https://cdn.ably.io/lib/ably.min-1.js, you will receive all minor updates and patch fixes automatically (i.e @1.*.*@). If you want to lock into minor version @1.0@ and receive all patch fixes automatically (i.e. @1.0.*@), then use "@https://cdn.ably.io/lib/ably.min-1.0.js@":https://cdn.ably.io/lib/ably.min-1.0.js. Additionally, the @.min@ suffix can be dropped if you want the non-minified version for debugging. "View a complete list of the Javascript library releases":https://github.com/ably/ably-js/releases diff --git a/content/realtime/versions/v0.8/usage.textile b/content/realtime/versions/v0.8/usage.textile index d92f28b76b..da2cd4e97a 100644 --- a/content/realtime/versions/v0.8/usage.textile +++ b/content/realtime/versions/v0.8/usage.textile @@ -36,7 +36,7 @@ blang[javascript]. The Realtime library for browser Javascript environments should be loaded from the Ably CDN as follows: ```[javascript] - + ``` You can also obtain the library as an "NPM module":https://www.npmjs.com/package/ably, or download the source directly from "Github":https://github.com/ably/ably-js @@ -46,7 +46,7 @@ blang[javascript]. var rest = new Ably.Rest({ key: apiKey }); ``` - When referencing the client library from our CDN, we recommend that you include a major version number in the URL so that breaking changes, according to the "semantic versioning scheme":http://semver.org/, are never mistakenly used. For example, if you want to ensure that you only use the @MAJOR@ version @0@, then use "@https://cdn.ably.io/lib/ably.min-0.js@":https://cdn.ably.io/lib/ably.min-0.js. If you want to ensure that the @MINOR@ version @1.0@ is used, then use "@https://cdn.ably.io/lib/ably.min-1.0.js@":https://cdn.ably.io/lib/ably.min-1.0.js. Additionally, the @.min@ suffix can be dropped if you specifically want to use the non-minified version for debugging. + When including the client library from our CDN, we recommend you lock into major version @1@ of the library. According to the "semantic versioning scheme":http://semver.org/ we adopt, you will then automatically receive minor and patch updates but you will never receive breaking changes. For example, if you lock into major version @1@ of the library by including "@https://cdn.ably.io/lib/ably.min-1.js@":https://cdn.ably.io/lib/ably.min-1.js, you will receive all minor updates and patch fixes automatically (i.e @1.*.*@). If you want to lock into minor version @1.0@ and receive all patch fixes automatically (i.e. @1.0.*@), then use "@https://cdn.ably.io/lib/ably.min-1.0.js@":https://cdn.ably.io/lib/ably.min-1.0.js. Additionally, the @.min@ suffix can be dropped if you want the non-minified version for debugging. "View a complete list of the Javascript library releases":https://github.com/ably/ably-js/releases diff --git a/content/rest/versions/v0.8/usage.textile b/content/rest/versions/v0.8/usage.textile index a4ae608e5a..cb63842a54 100644 --- a/content/rest/versions/v0.8/usage.textile +++ b/content/rest/versions/v0.8/usage.textile @@ -24,7 +24,7 @@ blang[javascript]. The REST library for browser Javascript environments should be loaded from the Ably CDN as follows: ```[javascript] - + bc[html]. You can also obtain the library as an "NPM module":https://www.npmjs.com/package/ably. @@ -252,7 +252,7 @@ We've demonstrated how easy it is to get up and running with Ably, however behin * "Sign up for a free account":/signup - our generous free packages give you a healthy quota of messages and connections allowing you to build a production ready app now * "Considering another solution?":/compare - see how we compare and why developers are moving to Ably - + + + + + + +

Publish & Subscribe sample

@@ -270,7 +270,7 @@ blang[python]. $def with (apiKey) - +

Publish & Subscribe sample

@@ -767,7 +767,7 @@ h2. Next steps 3. Gain a good technical "overview of how the Ably realtime platform works":https://www.ably.io/documentation/how-ably-works 4. "Get in touch if you need help":https://www.ably.io/contact - + +

Token auth example

diff --git a/data/jsbins.yaml b/data/jsbins.yaml index e473d81177..c75ad82d1a 100644 --- a/data/jsbins.yaml +++ b/data/jsbins.yaml @@ -1,75 +1,73 @@ --- jsbin_hash: - urUBwIWkiIJIxLBR/bJCTh1h6x8=: ogegab - K3P/Q3XJhTH3IgjXtLpvms6Oxj4=: utaheq - p1/pqACkeo44u0FjhN0Eji9RWLk=: ehifaw - zk7FX/AyP4oxoUjn/BbpHAI5l14=: ezuzot - fgmPOgOzPCYgez4/1ShC0by9Npk=: onocan - "/pVQtGRIlb2gkvOLc67w6QYFAJA=": ipafox - 0RvVdY26nyDSEp/44R0XdZ2cJfA=: acipov - uei0PmgeNjDQxqHo+P98Q74Rs7c=: izarad - Z3snHiRTp+zD6FhleU1/l/ZfH7A=: erebiv - nJjVPxO61tQZ8OeSLEBSWHWyB/M=: onurog - 2bwTxrI/373YZcO2+I7KwX6nH0I=: ajaxip - z11TvEkzpm2u64YIaSuUvqjEoQw=: ovavik - kakVQRsQ8tXEuc3DuwMGsJ4dVqI=: epolus - eMQP66FDY/MO/zWbFohUlqLI9LY=: aredoz - qYYVlE2GZsmEBiXnAwwrurAVtXo=: awuyot - 2G08Z4A2FN9m7c+XknPNWRlL3+Y=: ewimim - W06poXp+qjetSLWZ7cjafRk23uo=: ewiduf - UWnz6sn5xwMKZMU+OYEWIVKU7CI=: ixowal - Yb++VD1ZGZ+J77VTPv7GtgOIncs=: uqidub - CMyVpRUU+KM5hvED3v4N7b2lOxU=: ocodaf - ZyIss5caeeJ+cpSaLfIPHFh1e+M=: opapoc - m5oFFFUyk92pE+/HT+E3vj4eaNI=: ovojij - DJMTt2LuCaK3Gy3JUJ1VwhT8I28=: exedir - Oi423Oq5OQFOuA24IPmrLYdlBo4=: ifokom - y6nV8eTUT8o9fywImMXZA5GloN8=: efulug - 8dUC3fAy5LfCY7Oj/1TNC14WVTw=: umebiy - 12RoaIk5Xe8DZfHn6AlZ5kDcsYY=: ecebek - BySh1fBFeWfeORxW5kM4kLoNe6c=: ixiyot - 56fqxP8kkxgONFn+16PRAINpA90=: ilupuf - YuO2+EE7oigITwEqrbpZKS6sa38=: adacub jQncq6OcBR6KCAsxnz3q5mit6m4=: uyuyap - zNy+aAFPEDw4u2XTVaE57JQQPsc=: equyip - "+6+xX3++oxaKA3z5HbC6pvdpKDI=": ekafon - 2BVlKC4nL0eGC29JwK4hfMIjXog=: ewagog pw5duE254r4vCBZRry9w8oUD4A4=: etazid - 47EZnNG2R7EQ+CiKkZIVHeI3W+E=: uvogah + crxhojzcwnL63vjgYuQNm0yYcqk=: avaper + rf/oVbwi8uhndGbToJqYKG1sOIA=: onefuy + HAlskL/HxlVrp85zn77PHOGKuz0=: upedip + Ul7K8Isb1l450hdTi6HNZFsrFXk=: ewelul + EjhhGNY3f3dw55pyTen7hGEhUow=: ififuj + d6fvP62mwfb3LX3MOzxPRwODVBU=: utonoq + bYp5xl1rMqBWZ/WK9Kx6+CxZ828=: umovar + 6Ovum/7TCpAi1/NnWL+XsaQtqzA=: uxigok + 6GBW1O2815lZDupYJrTv1fNm4qk=: uzeger + r5IyoDhRy4gFszYu5DPnq3EfNUk=: ofuzev + KIPLFYj83Zqdh2YaYNtZMPdVY1A=: oveyiw + Vepzrg9pY/wPh+HapyGyFBpRMqk=: ukehog + BG6jpw/jw944/AWfQdtc+2GPrHw=: omelow + Imjfkh6eozxXxqg4sb762zGvmA4=: agiyos + KdrSTHQ0R+vyuwS0OJN0M+ijKuk=: idesem + 5I87XPHCIUtjB/okT0sRAHP1Q7Y=: amamin + fuo+Ii32Chc00ttAco9WAPu4sq0=: ohovec + 26G4unFcIgMJ7fw/7WDPNEyVBPo=: ebumop + 8d3JA2U+QssdT3U3I83THN9HDcw=: iyeqoz + Pp6loZQi9lSKlkJfdJFVKVkXRGY=: evomoh + cqhAxQS9InsxQR59gSHCYI4aXkM=: irewoh + rnwPhTS4IMwf/LJyYfbrJnK4Axc=: ojerak + eduuYgC4F3a9ZTtDVVA8dbYI514=: ekuxet + hNVfELEBYK20P4mzjqNcGsIzSHQ=: ajuwaz + viiNiyWEjefdf6NvWwEz4sleQ5w=: aribex + yjmAl+R0AZRrjn0GSBEfXu/Oi+o=: osameq + UUnvqzI4R3pyI8P3dBIGGjEl52o=: agusit + VenfatP77eh2z5Mf3ODJo7Xy8Lg=: inozoc + y1IO7M+5WWk3h+03xCQyRmzHbl8=: alazeh + XQfd2DiAARhlJfSSku2egIAG/Yw=: ugehef + tFdUSLgmUuF6+xdeyztpD2RR6PI=: iburuq + 3auIhOVQgxbiToyS78PwEpQ0caQ=: okipoh + YuO2+EE7oigITwEqrbpZKS6sa38=: edalaf jsbin_id: - client-lib-development-guide/example: urUBwIWkiIJIxLBR/bJCTh1h6x8= - authentication/basic-auth: K3P/Q3XJhTH3IgjXtLpvms6Oxj4= - authentication/create-token-request: Yb++VD1ZGZ+J77VTPv7GtgOIncs= - authentication/request-token: p1/pqACkeo44u0FjhN0Eji9RWLk= - quick-start-guide/connect: zk7FX/AyP4oxoUjn/BbpHAI5l14= - quick-start-guide/send-message: fgmPOgOzPCYgez4/1ShC0by9Npk= - realtime/channel-implicit: nJjVPxO61tQZ8OeSLEBSWHWyB/M= - realtime/channel-publish: Oi423Oq5OQFOuA24IPmrLYdlBo4= - realtime/channel: y6nV8eTUT8o9fywImMXZA5GloN8= - realtime/connection-getting-started: "/pVQtGRIlb2gkvOLc67w6QYFAJA=" - realtime/connection-states: "+6+xX3++oxaKA3z5HbC6pvdpKDI=" - realtime/connection: eMQP66FDY/MO/zWbFohUlqLI9LY= - website-examples/angular-todo: 0RvVdY26nyDSEp/44R0XdZ2cJfA= - website-examples/backbone-todo: uei0PmgeNjDQxqHo+P98Q74Rs7c= - website-examples/ember-todo: Z3snHiRTp+zD6FhleU1/l/ZfH7A= - website-examples/simple-chat: ZyIss5caeeJ+cpSaLfIPHFh1e+M= - realtime/channel-states: 2BVlKC4nL0eGC29JwK4hfMIjXog= - realtime/presence-simple: 2bwTxrI/373YZcO2+I7KwX6nH0I= - realtime/presence-events: z11TvEkzpm2u64YIaSuUvqjEoQw= - realtime/presence-multiple-client-id: kakVQRsQ8tXEuc3DuwMGsJ4dVqI= - realtime/channel-history: BySh1fBFeWfeORxW5kM4kLoNe6c= - realtime/channel-history-until-attach: W06poXp+qjetSLWZ7cjafRk23uo= - realtime/stats: UWnz6sn5xwMKZMU+OYEWIVKU7CI= - realtime/auth-token-callback: 2G08Z4A2FN9m7c+XknPNWRlL3+Y= - realtime/auth-client-id: qYYVlE2GZsmEBiXnAwwrurAVtXo= - realtime/channel-encrypted: DJMTt2LuCaK3Gy3JUJ1VwhT8I28= - rest/channel-history: 56fqxP8kkxgONFn+16PRAINpA90= - rest/channel-publish: 8dUC3fAy5LfCY7Oj/1TNC14WVTw= - rest/stats: 47EZnNG2R7EQ+CiKkZIVHeI3W+E= - authentication/capabilities: zNy+aAFPEDw4u2XTVaE57JQQPsc= - authentication/auth-callback: CMyVpRUU+KM5hvED3v4N7b2lOxU= - website-examples/home-page: m5oFFFUyk92pE+/HT+E3vj4eaNI= - rest/publish-on-behalf-of-client: 12RoaIk5Xe8DZfHn6AlZ5kDcsYY= - adapters/pubnub-pub-sub: YuO2+EE7oigITwEqrbpZKS6sa38= adapters/pusher-pub-sub: jQncq6OcBR6KCAsxnz3q5mit6m4= + adapters/pubnub-pub-sub: YuO2+EE7oigITwEqrbpZKS6sa38= + authentication/auth-callback: eduuYgC4F3a9ZTtDVVA8dbYI514= + authentication/basic-auth: crxhojzcwnL63vjgYuQNm0yYcqk= + authentication/capabilities: rf/oVbwi8uhndGbToJqYKG1sOIA= + authentication/create-token-request: HAlskL/HxlVrp85zn77PHOGKuz0= + authentication/request-token: Ul7K8Isb1l450hdTi6HNZFsrFXk= + client-lib-development-guide/example: EjhhGNY3f3dw55pyTen7hGEhUow= + quick-start-guide/connect: d6fvP62mwfb3LX3MOzxPRwODVBU= + quick-start-guide/send-message: bYp5xl1rMqBWZ/WK9Kx6+CxZ828= reactor/webhook-hmac-sha-256: pw5duE254r4vCBZRry9w8oUD4A4= + realtime/auth-client-id: hNVfELEBYK20P4mzjqNcGsIzSHQ= + realtime/auth-token-callback: viiNiyWEjefdf6NvWwEz4sleQ5w= + realtime/channel-encrypted: 6Ovum/7TCpAi1/NnWL+XsaQtqzA= + realtime/channel-history-until-attach: 6GBW1O2815lZDupYJrTv1fNm4qk= + realtime/channel-history: yjmAl+R0AZRrjn0GSBEfXu/Oi+o= + realtime/channel-implicit: r5IyoDhRy4gFszYu5DPnq3EfNUk= + realtime/channel-publish: KIPLFYj83Zqdh2YaYNtZMPdVY1A= + realtime/channel-states: Vepzrg9pY/wPh+HapyGyFBpRMqk= + realtime/channel: BG6jpw/jw944/AWfQdtc+2GPrHw= + realtime/connection-states: Imjfkh6eozxXxqg4sb762zGvmA4= + realtime/connection: UUnvqzI4R3pyI8P3dBIGGjEl52o= + realtime/presence-events: KdrSTHQ0R+vyuwS0OJN0M+ijKuk= + realtime/presence-multiple-client-id: 5I87XPHCIUtjB/okT0sRAHP1Q7Y= + realtime/presence-simple: VenfatP77eh2z5Mf3ODJo7Xy8Lg= + realtime/stats: fuo+Ii32Chc00ttAco9WAPu4sq0= + rest/channel-history: y1IO7M+5WWk3h+03xCQyRmzHbl8= + rest/channel-publish: 26G4unFcIgMJ7fw/7WDPNEyVBPo= + rest/publish-on-behalf-of-client: XQfd2DiAARhlJfSSku2egIAG/Yw= + rest/stats: tFdUSLgmUuF6+xdeyztpD2RR6PI= + website-examples/angular-todo: 3auIhOVQgxbiToyS78PwEpQ0caQ= + website-examples/backbone-todo: 8d3JA2U+QssdT3U3I83THN9HDcw= + website-examples/ember-todo: Pp6loZQi9lSKlkJfdJFVKVkXRGY= + website-examples/home-page: cqhAxQS9InsxQR59gSHCYI4aXkM= + website-examples/simple-chat: rnwPhTS4IMwf/LJyYfbrJnK4Axc= diff --git a/layouts/_head.html.erb b/layouts/_head.html.erb index 3b26e5ed7d..5ce25dac9f 100644 --- a/layouts/_head.html.erb +++ b/layouts/_head.html.erb @@ -19,7 +19,7 @@ - + From 68c8f8ce0123394a016b657f7d50718d5f86e992 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Fri, 20 Jan 2017 18:58:37 +0100 Subject: [PATCH 03/19] api: Update Java references to 1.0 --- content/realtime/usage.textile | 4 ++-- content/rest/usage.textile | 4 ++-- content/root/quick-start-guide.textile | 4 ++-- content/tutorials/history.textile | 4 ++-- content/tutorials/publish-subscribe.textile | 4 ++-- content/tutorials/token-authentication.textile | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/content/realtime/usage.textile b/content/realtime/usage.textile index 1301565b74..d3e42615c5 100644 --- a/content/realtime/usage.textile +++ b/content/realtime/usage.textile @@ -95,13 +95,13 @@ blang[java]. For Java applications: ```[java] - compile 'io.ably:ably-java:0.8.7' + compile 'io.ably:ably-java:1.0.0' ``` For Android apps: ```[java] - compile 'io.ably:ably-android:0.8.7' + compile 'io.ably:ably-android:1.0.0' ``` In the above example a specific version of the library is referenced, however we recommend you check which is the latest stable version and always use that. Follow links to get the latest stable release for "Java":https://bintray.com/ably-io/ably/ably-java and "Android":https://bintray.com/ably-io/ably/ably-android. diff --git a/content/rest/usage.textile b/content/rest/usage.textile index 70e5002039..144aaa0412 100644 --- a/content/rest/usage.textile +++ b/content/rest/usage.textile @@ -122,13 +122,13 @@ blang[java]. For Java applications: ```[java] - compile 'io.ably:ably-java:0.8.7' + compile 'io.ably:ably-java:1.0.0' ``` For Android apps: ```[java] - compile 'io.ably:ably-android:0.8.7' + compile 'io.ably:ably-android:1.0.0' ``` In the above example a specific version of the library is referenced, however we recommend you check which is the latest stable version and always use that. Follow links to get the latest stable release for "Java":https://bintray.com/ably-io/ably/ably-java and "Android":https://bintray.com/ably-io/ably/ably-android. diff --git a/content/root/quick-start-guide.textile b/content/root/quick-start-guide.textile index 29ed8192b5..a0a4cdb32e 100644 --- a/content/root/quick-start-guide.textile +++ b/content/root/quick-start-guide.textile @@ -62,13 +62,13 @@ blang[java]. For Java applications: ```[java] - compile 'io.ably:ably-java:0.8.7' + compile 'io.ably:ably-java:1.0.0' ``` For Android apps: ```[java] - compile 'io.ably:ably-android:0.8.7' + compile 'io.ably:ably-android:1.0.0' ``` In the above example a specific version of the library is referenced, however we recommend you check which is the latest stable version and always use that. Follow links to get the latest stable release for "Java":https://bintray.com/ably-io/ably/ably-java and "Android":https://bintray.com/ably-io/ably/ably-android. diff --git a/content/tutorials/history.textile b/content/tutorials/history.textile index d91ccd6d65..0437f81799 100644 --- a/content/tutorials/history.textile +++ b/content/tutorials/history.textile @@ -48,7 +48,7 @@ blang[java]. } dependencies { - compile 'io.ably:ably-java:0.8.7' + compile 'io.ably:ably-java:1.0.0' } ``` @@ -87,7 +87,7 @@ blang[android]. ... dependencies { ... - compile 'io.ably:ably-android:0.8.7' + compile 'io.ably:ably-android:1.0.0' } ``` diff --git a/content/tutorials/publish-subscribe.textile b/content/tutorials/publish-subscribe.textile index 3a0a95c0c5..347479a084 100644 --- a/content/tutorials/publish-subscribe.textile +++ b/content/tutorials/publish-subscribe.textile @@ -31,7 +31,7 @@ blang[java]. } dependencies { - compile 'io.ably:ably-java:0.8.7' + compile 'io.ably:ably-java:1.0.0' } ``` @@ -71,7 +71,7 @@ blang[android]. ... dependencies { ... - compile 'io.ably:ably-android:0.8.7' + compile 'io.ably:ably-android:1.0.0' } ``` diff --git a/content/tutorials/token-authentication.textile b/content/tutorials/token-authentication.textile index 80eb0a88bc..bfd0a1dd80 100644 --- a/content/tutorials/token-authentication.textile +++ b/content/tutorials/token-authentication.textile @@ -25,7 +25,7 @@ blang[java]. } dependencies { - compile 'io.ably:ably-java:0.8.7' + compile 'io.ably:ably-java:1.0.0' } ``` @@ -607,7 +607,7 @@ blang[android]. ... dependencies { ... - compile 'io.ably:ably-android:0.8.7' + compile 'io.ably:ably-android:1.0.0' } ``` From 9c157cec3835b9c01a9f96b31664a7747ea8aa5f Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Fri, 20 Jan 2017 18:58:55 +0100 Subject: [PATCH 04/19] api: Enable Ruby, Java, iOS for v1.0 --- content/realtime/authentication.textile | 8 ++++---- content/realtime/channels-messages.textile | 8 ++++---- content/realtime/connection.textile | 8 ++++---- content/realtime/encryption.textile | 8 ++++---- content/realtime/history.textile | 8 ++++---- content/realtime/presence.textile | 8 ++++---- content/realtime/statistics.textile | 8 ++++---- content/realtime/types.textile | 8 ++++---- content/realtime/usage.textile | 8 ++++---- content/rest/authentication.textile | 6 +++--- content/rest/channels-messages.textile | 6 +++--- content/rest/encryption.textile | 6 +++--- content/rest/history.textile | 6 +++--- content/rest/presence.textile | 6 +++--- content/rest/statistics.textile | 6 +++--- content/rest/types.textile | 6 +++--- content/rest/usage.textile | 6 +++--- 17 files changed, 60 insertions(+), 60 deletions(-) diff --git a/content/realtime/authentication.textile b/content/realtime/authentication.textile index 95f9297514..52b0c417cb 100644 --- a/content/realtime/authentication.textile +++ b/content/realtime/authentication.textile @@ -5,10 +5,10 @@ index: 40 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/realtime/channels-messages.textile b/content/realtime/channels-messages.textile index 47876a8df7..60ee88f2c6 100644 --- a/content/realtime/channels-messages.textile +++ b/content/realtime/channels-messages.textile @@ -5,10 +5,10 @@ index: 30 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/realtime/connection.textile b/content/realtime/connection.textile index 77e2dd44d7..4beebcedd5 100644 --- a/content/realtime/connection.textile +++ b/content/realtime/connection.textile @@ -5,10 +5,10 @@ index: 20 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/realtime/encryption.textile b/content/realtime/encryption.textile index be7483a29f..aa5b389e34 100644 --- a/content/realtime/encryption.textile +++ b/content/realtime/encryption.textile @@ -5,10 +5,10 @@ index: 70 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/realtime/history.textile b/content/realtime/history.textile index d781192d43..722133fa89 100644 --- a/content/realtime/history.textile +++ b/content/realtime/history.textile @@ -5,10 +5,10 @@ index: 50 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/realtime/presence.textile b/content/realtime/presence.textile index 80bb4cb9fc..cdcef2b267 100644 --- a/content/realtime/presence.textile +++ b/content/realtime/presence.textile @@ -5,10 +5,10 @@ index: 40 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/realtime/statistics.textile b/content/realtime/statistics.textile index e5f94df186..2fe882c068 100644 --- a/content/realtime/statistics.textile +++ b/content/realtime/statistics.textile @@ -5,10 +5,10 @@ index: 100 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/realtime/types.textile b/content/realtime/types.textile index a3fc673576..2fa682c606 100644 --- a/content/realtime/types.textile +++ b/content/realtime/types.textile @@ -5,10 +5,10 @@ index: 500 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Data types: diff --git a/content/realtime/usage.textile b/content/realtime/usage.textile index d3e42615c5..96d31f2227 100644 --- a/content/realtime/usage.textile +++ b/content/realtime/usage.textile @@ -5,10 +5,10 @@ index: 10 languages: - javascript - nodejs - - ruby,0.8 - - java,0.8 - - swift,0.8 - - objc,0.8 + - ruby + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/rest/authentication.textile b/content/rest/authentication.textile index e7bf39237c..5ebdeecbc1 100644 --- a/content/rest/authentication.textile +++ b/content/rest/authentication.textile @@ -8,9 +8,9 @@ languages: - php - python,0.8 - ruby - - java,0.8 - - swift,0.8 - - objc,0.8 + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/rest/channels-messages.textile b/content/rest/channels-messages.textile index 3daaa3cb89..64c8d23182 100644 --- a/content/rest/channels-messages.textile +++ b/content/rest/channels-messages.textile @@ -8,9 +8,9 @@ languages: - php - python,0.8 - ruby - - java,0.8 - - swift,0.8 - - objc,0.8 + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/rest/encryption.textile b/content/rest/encryption.textile index 86aa92b720..a774c149fb 100644 --- a/content/rest/encryption.textile +++ b/content/rest/encryption.textile @@ -8,9 +8,9 @@ languages: - php - python,0.8 - ruby - - java,0.8 - - swift,0.8 - - objc,0.8 + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/rest/history.textile b/content/rest/history.textile index 5bec641d81..4d8b543671 100644 --- a/content/rest/history.textile +++ b/content/rest/history.textile @@ -8,9 +8,9 @@ languages: - php - python,0.8 - ruby - - java,0.8 - - swift,0.8 - - objc,0.8 + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/rest/presence.textile b/content/rest/presence.textile index 3637b2e235..efbeedfa28 100644 --- a/content/rest/presence.textile +++ b/content/rest/presence.textile @@ -8,9 +8,9 @@ languages: - php - python,0.8 - ruby - - java,0.8 - - swift,0.8 - - objc,0.8 + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/rest/statistics.textile b/content/rest/statistics.textile index 4b03816732..43bd32ddb3 100644 --- a/content/rest/statistics.textile +++ b/content/rest/statistics.textile @@ -8,9 +8,9 @@ languages: - php - python,0.8 - ruby - - java,0.8 - - swift,0.8 - - objc,0.8 + - java + - swift + - objc - csharp,0.8 jump_to: Help with: diff --git a/content/rest/types.textile b/content/rest/types.textile index 059039ca62..dfde556747 100644 --- a/content/rest/types.textile +++ b/content/rest/types.textile @@ -8,9 +8,9 @@ languages: - php - python,0.8 - ruby - - java,0.8 - - swift,0.8 - - objc,0.8 + - java + - swift + - objc - csharp,0.8 jump_to: REST Data types: diff --git a/content/rest/usage.textile b/content/rest/usage.textile index 144aaa0412..c8a74459cc 100644 --- a/content/rest/usage.textile +++ b/content/rest/usage.textile @@ -8,9 +8,9 @@ languages: - php - python,0.8 - ruby - - java,0.8 - - swift,0.8 - - objc,0.8 + - java + - swift + - objc - csharp,0.8 jump_to: Help with: From 86e7e3e0306d0384d9451b0ef0604beca6f41774 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Fri, 20 Jan 2017 19:00:40 +0100 Subject: [PATCH 05/19] spec: Update 0.8 to 1.0 diff Run command: $ git diff v0.8 master content/client-lib-development-guide/features.textile > content/client-lib-development-guide/versions/features-0-8__1-0.diff --- .../versions/features-0-8__1-0.diff | 1055 +++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 content/client-lib-development-guide/versions/features-0-8__1-0.diff diff --git a/content/client-lib-development-guide/versions/features-0-8__1-0.diff b/content/client-lib-development-guide/versions/features-0-8__1-0.diff new file mode 100644 index 0000000000..29ef922116 --- /dev/null +++ b/content/client-lib-development-guide/versions/features-0-8__1-0.diff @@ -0,0 +1,1055 @@ +diff --git a/content/client-lib-development-guide/features.textile b/content/client-lib-development-guide/features.textile +index bff9943..731e0b4 100644 +--- a/content/client-lib-development-guide/features.textile ++++ b/content/client-lib-development-guide/features.textile +@@ -1,8 +1,10 @@ + --- +-title: Features spec v0.8 ++title: Features spec + section: client-lib-development-guide + index: 1 + anchor_specs: true ++languages: ++ - none + jump_to: + General: + - Test guidelines +@@ -25,27 +27,25 @@ jump_to: + - Options#options + Interface Definition: + - Complete API IDL#idl ++ Previous version: ++ - Old specs + --- + +-A detailed "test specification":https://github.com/ably/ably-ruby/blob/master/SPEC.md that applies to all client libraries is generated from the Ably Ruby client library's acceptance and test suites. Whilst every official Ably client library has test coverage, the amount of test coverage varies, and as such our recommendation is to refer to the official "test specification":https://github.com/ably/ably-ruby/blob/master/SPEC.md when developing a client library. ++This document outlines the complete feature set of both the REST and Realtime client libraries. It is expected that every client library developer refers to this document to ensure that their client library provides the same API and features as the existing Ably client libraries. In addition to this, it is essential that there is test coverage over all of the features described below. As an example, see the Ruby library "test specification and coverage":https://github.com/ably/ably-ruby/blob/master/SPEC.md generated from the test suite. + +-However, we have found the "test specification":https://github.com/ably/ably-ruby/blob/master/SPEC.md can be difficult as a reference because of both its breadth and the fact that it applies to the Ruby client library which may be unfamiliar as a language for a lot of developers. ++We recommend you use the "IDL (Interface Definition Language)":#idl and refer to other existing libraries that adhere to this spec as a reference when reviewing how the API has been implemented. + +-As a result, this document outlines the complete feature set of both the REST and Realtime client libraries. It is expected that every client library developer refers to this document to ensure that their client library provides the same API and features as the existing Ably client libraries. In addition to this, it is essential that there is test coverage over all of the features described below. +- +-We recommend you use the "IDL (Interface Definition Language)":#idl and the "Ably Java library":https://github.com/ably/ably-java as a reference when reviewing how the API has been implemented. ++__Please note we maintain a separate Google Sheet that keeps track of which features are implemented and matching test coverage for each client library. If you intend to work on an Ably client library, please "contact us":https://www.ably.io/contact for access to this Google Sheet as it is useful as a reference and also needs to be kept up to date__ + + h2(#test-guidelines). Test guidelines + + * @(G1)@ Every test should be executed using all supported protocols (i.e. JSON and "MessagePack":http://msgpack.org/ if supported). This includes both sending & receiving data +-* @(G2)@ All tests by default are run against a special Ably sandbox environment. This environment allows apps to be provisioned without any authentication that can then be used for client library testing. Bear in mind that all apps created in the sandbox environment are automatically deleted after 60 minutes and have low limits to prevent abuse. Apps are configured by sending a @POST@ request to @https://sandbox-rest.ably.io/apps@ with a JSON body that specifies the keys and their associated capabilities, channel namespace rules and any presence fixture data that is required; see "ably-common test-app-setup.json":https://github.com/ably/ably-common/blob/master/test-resources/test-app-setup.json. See the "Java test setup":https://github.com/ably/ably-java/blob/master/test/io/ably/test/rest/RestSetup.java. Presence fixture data is necessary for the REST library presence tests as there is no way to register presence on a channel in the REST library ++* @(G2)@ All tests by default are run against a special Ably sandbox environment. This environment allows apps to be provisioned without any authentication that can then be used for client library testing. Bear in mind that all apps created in the sandbox environment are automatically deleted after 60 minutes and have low limits to prevent abuse. Apps are configured by sending a @POST@ request to @https://sandbox-rest.ably.io/apps@ with a JSON body that specifies the keys and their associated capabilities, channel namespace rules and any presence fixture data that is required; see "ably-common test-app-setup.json":https://github.com/ably/ably-common/blob/master/test-resources/test-app-setup.json. Presence fixture data is necessary for the REST library presence tests as there is no way to register presence on a channel in the REST library + * @(G3)@ Testing statistics can be tricky due to timing issues and slow test suites as a result of sending requests to generate statistics. As such, we provide a special stats endpoint in our sandbox environment that allows stats to be injected into our metrics system so that stats tests can make predictable assertions. To create stats you must send an authenticated @POST@ request to the stats JSON to @https://sandbox-rest.ably.io/stats@ with the stats data you wish to create. See the "Javascript stats fixture":https://github.com/ably/ably-js/blob/4e65d4e13eb8750a375b9511e4dd059092c0e481/spec/rest/stats.test.js#L8-L51 and "setup helper":https://github.com/ably/ably-js/blob/4e65d4e13eb8750a375b9511e4dd059092c0e481/spec/common/modules/testapp_manager.js#L158-L182 as an example +-* @(G4)@ All REST requests and WebSocket connections to Ably must include the current API version @0.8@. Should any new API version with breaking changes be released, the client library will continue to use the API version explicitly requested ++* @(G4)@ All REST requests and WebSocket connections to Ably must include the current API version @1.0@. Should any new API version with breaking changes be released, the client library will continue to use the API version explicitly requested + + h2(#rest). REST client library + +-Client library developers - clone our "REST client library Google Doc spec":https://docs.google.com/spreadsheets/d/1vBzr9N-0ovtVZ0mxTeg7zLMEhcgj5lB9ivmkOcO-9J0/edit?usp=sharing when developing a REST client library to help you keep track of feature compliance and test coverage. +- + h3(#restclient). RestClient + + * @(RSC1)@ The constructor accepts either an API key, a token string, or a set of "@ClientOptions@":#options. If invalid arguments are provided such as a no API key, no token and no means to create a token, then this will result in an error +@@ -61,51 +61,60 @@ h3(#restclient). RestClient + *** @(RSC6b3)@ @limit@ supports up to 1,000 items; if omitted the limit defaults to the REST API default (100) + *** @(RSC6b4)@ @unit@ is the period for which the stats will be aggregated by, values supported are @minute@, @hour@, @day@ or @month@; if omitted the unit defaults to the REST API default (@minute@) + * @(RSC16)@ @RestClient#time@ function sends a get request to @rest.ably.io/time@ and returns the server time in milliseconds since epoch or as a Date/Time object where suitable +-* @(RSC7)@ Sends REST requests over HTTP and HTTPS to the REST end-point @rest.ably.io@ +-** @(RSC7a)@ The header @X-Ably-Version: 0.8@ must be included in all REST requests to the Ably end-point ++* @(RSC7)@ Sends REST requests over HTTP and HTTPS to the REST endpoint @rest.ably.io@ ++** @(RSC7a)@ The header @X-Ably-Version: 1.0@ must be included in all REST requests to the Ably endpoint ++** @(RSC7b)@ The header @X-Ably-Lib: [lib][.optional variant]?-[version]@ should be included in all REST requests to the Ably endpoint where @[lib]@ is the name of the library such as @js@ for @ably-js@, @[.optional variant]@ is an optional library variant, such as @laravel@ for the @php@ library, which is always delimited with a period such as @php.laravel@, and where @[version]@ is the full client library version using "Semver":http://semver.org/ such as @1.0.2@. For example, the 1.0.0 version of the Javascript library would use the header @X-Ably-Lib: js-1.0.0@ ++*** @(RSC7b1)@ When it is not possible to send the @X-Ably-Lib@ header, such as for @JSONP@ requests, the library version should be sent as a query param such as @lib=js-1.0.0@ + * @(RSC18)@ If @ClientOptions#tls@ is true, then all communication is over HTTPS. If false, all communication is over HTTP however "Basic Auth":https://en.wikipedia.org/wiki/Basic_access_authentication over HTTP will result in an error as private keys cannot be submitted over an insecure connection. See @Auth@ below + * @(RSC8)@ Supports two protocols: + ** @(RSC8a)@ "MessagePack":http://msgpack.org/ binary protocol (this is the default for environments having a suitable level or support for binary data) + ** @(RSC8b)@ JSON text protocol (used when @useBinaryProtocol@ option is false) + * @(RSC9)@ Uses @Auth@ to establish what authentication scheme to use, how to authenticate, and automatic issuing of tokens when necessary +-* @(RSC10)@ If a REST request responds with a token error (401 HTTP status code and an Ably error value @40140 <= @code < 40150@), then the Auth class is responsible for reissuing a token and the request should be reattempted, see "RSC14c":#RSC14c and "RSC14d":#RSC14d +-* @(RSC11)@ Requests are sent to the default endpoint @rest.ably.io@. However, if the @restHost@ option is set, the client will send requests to the specified host. If @environment@ option is configured and is not "production", the environment name is prefixed to the default host endpoint and the @restHost@ is set accordingly. For example, if the @environment@ is set to sandbox, then the @restHost@ endpoint will become @sandbox-rest.ably.io@ ++* @(RSC10)@ If a REST request responds with a token error (401 HTTP status code and an Ably error value @40140 <= code < 40150@), then the Auth class is responsible for reissuing a token and the request should be reattempted, see "RSC14c":#RSC14c and "RSC14d":#RSC14d ++* @(RSC11)@ Requests are sent to the default endpoint @rest.ably.io@. However, if the @restHost@ option is set, the client will send requests to the specified host. If @environment@ option is configured and is not "production", the environment name is prefixed to the default host endpoint and the @restHost@ is set accordingly. For example, if the @environment@ is set to sandbox, then the @restHost@ endpoint will become @sandbox-rest.ably.io@. See "TO3k2":#TO3k2 for constraints. + * @(RSC12)@ REST endpoint host is configurable in the Client constructor with the option @restHost@ + * @(RSC13)@ The client library must use the connection and request timeouts specified in the @ClientOptions@, falling back to the defaults described in @ClientOptions@ below +-* @(RSC14)@ Authentication +-** @(RSC14a)@ Supports basic authentication when an API key is provided with the @key@ option. The API key follows the format @"KEY_NAME:KEY_SECRET"@ so when authenticating using "Basic Auth":https://en.wikipedia.org/wiki/Basic_access_authentication, the key name can be used as the username and the key secret as the password +-** @(RSC14b)@ Uses token authentication whenever the criteria of "RSA4":#RSA4 are met +-** @(RSC14c)@ When a @token@ or @tokenDetails@ is used to instance the library, and no means to renew the token is provided (either an API key, @authCallback@ or @authUrl@), if the server responds with a token error (401 HTTP status code and an Ably error value @40140 <= @code < 40150@), then the client library should indicate an error and not retry the request +-** @(RSC14d)@ When the client does have a means to renew the token automatically, and the token has expired or the server has responded with a token error (@statusCode@ value of 401 and error @code@ value in the range @40140 <= @code < 40150@), then the client should automatically make a single attempt to reissue the token and resend the request using the new token. If the token creation failed or the subsequent request with the new token failed due to a token error, then the request should result in an error + * @(RSC15)@ Host Fallback +-** @(RSC15b)@ The fallback behaviour described below only applies when the default @rest.ably.io@ endpoint is being used and has not been overriden, see "RSC11":#RSC11. If host fallback is not supported, failing HTTP requests that would have "qualified for a retry against a fallback host (see RSC15d)":#RSC15d, will instead result in an error immediately +-** @(RSC15e)@ By default, every new HTTP request is first attempted to the primary host @rest.ably.io@, which, through DNS, is automatically routed to the client's closest data centre. The client library must always prefer the default endpoint (closest data centre), even if a previous request to that endpoint has failed +-** @(RSC15a)@ In the case of an error necessitating use of an alternative host (see "RSC15d":#RSC15d), try fallback hosts in random order, continuing to try further hosts if "qualifying errors":#RSC15d occur, failing when all have been tried or the configured @httpMaxRetryCount@ has been reached (see "@TO3l5@":#TO3l5). This ensures that a client library is able to work around routing or other problems for the user's closest data centre. For example, if a @POST@ request to @rest.ably.io@ fails because the default endpoint is unreachable or unserviceable, then the @POST@ request should be retried again against the fallback hosts in attempt to find an alternate healthy data centre to service the request. The five fallback hosts are @[a-e].ably-realtime.com@. +-** @(RSC15d)@ Errors that necessitate use of an alternative host include: host unresolvable or unreachable, request timeout, or a response but with an applicable HTTP status code in the range @500 <= code <= 504@. Resending requests that have failed for other failure conditions will not fix the problem and will simply increase the load on other data centres unnecessarily ++** @(RSC15b)@ The fallback behavior described below only applies when the default @rest.ably.io@ endpoint is being used and has not been overriden (see "RSC11":#RSC11), @ClientOptions#fallbackHostsUseDefault@ is @true@, or an array of @ClientOptions#fallbackHosts@ is provided. If host fallback is not supported, failing HTTP requests that would have "qualified for a retry against a fallback host (see RSC15d)":#RSC15d, will instead result in an error immediately ++** @(RSC15e)@ By default, every new HTTP request is first attempted to the default primary host @rest.ably.io@ (unless overriden in @ClientOptions#restHost@), which, through DNS, is automatically routed to the client's closest data center. The client library must always prefer the default endpoint (closest data center), even if a previous request to that endpoint has failed ++** @(RSC15a)@ In the case of an error necessitating use of an alternative host (see "RSC15d":#RSC15d), try fallback hosts in random order, continuing to try further hosts if "qualifying errors":#RSC15d occur, failing when all have been tried or the configured @httpMaxRetryCount@ has been reached (see "@TO3l5@":#TO3l5). This ensures that a client library is able to work around routing or other problems for the user's closest data center. For example, if a @POST@ request to @rest.ably.io@ fails because the default endpoint is unreachable or unserviceable, then the @POST@ request should be retried again against the fallback hosts in attempt to find an alternate healthy data center to service the request. The five default fallback hosts are @[a-e].ably-realtime.com@. If an array of custom fallback hosts are provided in @ClientOptions#fallbackHosts@, then they will be used instead. If an empty array of fallback hosts is provided, then fallback host functionality is disabled ++** @(RSC15d)@ Errors that necessitate use of an alternative host include: host unresolvable or unreachable, request timeout, or a response but with an applicable HTTP status code in the range @500 <= code <= 504@. Resending requests that have failed for other failure conditions will not fix the problem and will simply increase the load on other data-centers unnecessarily + * @(RSC17)@ When instancing the library, if a @clientId@ attribute is set in @ClientOptions@, then the @Auth#clientId@ attribute will contain the provided @clientId@ ++* @(RSC19)@ @RestClient#request@ function is provided as a convenience for customers who wish to use bleeding edge REST API functionality that is either not documented or is not included in the API for our client libraries. The REST client library provides a function to issue HTTP requests to the Ably endpoints with all the built in functionality of the library such as authentication, paging, fallback hosts, MsgPack and JSON support etc. The function: ++** @(RSC19a)@ Method signature is @request(string method, string path, Hash params?, JsonObject | JsonArray body?, Hash headers?) -> HttpPaginatedResponse@ with arguments: @method@ is a valid "HTTP verb":https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html (must support @"GET"@, @"POST"@, and @"PUT"@, should support @"PATCH"@, may support others); @path@ is the path component of the URL such as @"/channels"@; @params@ and @headers@ are optional arguments containing pairs of key value strings (multi-valued headers are not supported) that will result in query params and HTTP headers being added respectively in the request (the argument types can be idiomatic for the language such as @Object@ in the case of Javascript); @body@ is an optional @JsonObject@ or @JsonArray@ like object argument that can be easily serialized to MsgPack or JSON ++** @(RSC19b)@ All requests will unconditionally use the default authentication mechanism configured for the REST client i.e. basic or token authentication (see "Auth":#rest-auth) ++** @(RSC19c)@ The library will configure the @Accept@ and @Content-Type@ type headers to reflect whether the client is configured to use a binary or JSON based protocol (see "RSC8":#RSC8). All requests are encoded and decoded into Json or MsgPack as appropriate automatically by the library. Binary @body@ payloads are not supported at this time ++** @(RSC19d)@ @request@ method returns an @HttpPaginatedResponse@ object that inherits from the @PaginatedResult@ object to provide details on the response plus paging support where applicable. See "HP1":#HP1 for more details ++** @(RSC19e)@ If the HTTP network request fails for reasons such as a timeout (after the underlying fallback host attempts have failed where applicable, see "RSC15":#RSC15), then the @request@ method should indicate an error in an idiomatic way for the platform + + h3(#rest-auth). Auth + +-* @(RSA1)@ "Basic Auth":https://en.wikipedia.org/wiki/Basic_access_authentication connects over HTTPS by default. Any attempt to use Basic Auth over HTTP will result in an error +-* @(RSA11)@ When using Basic Auth, the API key is Base64 encoded and included in an @Authorization@ header, as specified in "RFC7235":https://tools.ietf.org/html/rfc7235 ++* @(RSA1)@ "Basic Auth":https://en.wikipedia.org/wiki/Basic_access_authentication connects over HTTPS by default. Any attempt to use Basic Auth over HTTP without TLS will result in an error ++* @(RSA11)@ When using Basic Auth, the API key is Base64 encoded and included in an @Authorization@ header, as specified in "RFC7235":https://tools.ietf.org/html/rfc7235. The API key follows the format @"KEY_NAME:KEY_SECRET"@ so when authenticating using "Basic Auth":https://en.wikipedia.org/wiki/Basic_access_authentication, the key name can be used as the username and the key secret as the password + * @(RSA2)@ "Basic Auth":https://en.wikipedia.org/wiki/Basic_access_authentication is the default authentication scheme if an API key exists + * @(RSA3)@ Token Auth: + ** @(RSA3a)@ Can be used over HTTP or HTTPs + ** @(RSA3b)@ For REST requests, the token string is Base64 encoded and used in the @Authorization: Bearer@ header + ** @(RSA3c)@ For Realtime connections, the querystring param @accessToken@ is appended to the URL endpoint + * @(RSA4)@ Token Auth is used if @useTokenAuth@ is set to true, or if @useTokenAuth@ is unspecified and any one of the following conditions are met: a @clientId@ is specified; @authUrl@ or @authCallback@ is provided; an explicit @token@ or @TokenDetails@ is provided ++** @(RSA4a)@ When a @token@ or @tokenDetails@ is used to instance the library, and no means to renew the token is provided (either an API key, @authCallback@ or @authUrl@), if the server responds with a token error (401 HTTP status code and an Ably error value @40140 <= code < 40150@), then the client library should indicate an error, not retry the request and in the case of the realtime library, transition the connection to the @FAILED@ state ++** @(RSA4b)@ When the client does have a means to renew the token automatically, and the token has expired or the server has responded with a token error (@statusCode@ value of 401 and error @code@ value in the range @40140 <= code < 40150@), then the client should automatically make a single attempt to reissue the token and resend the request using the new token. If the token creation failed or the subsequent request with the new token failed due to a token error, then the request should result in an error ++** @(RSA4c)@ If an attempt by the realtime client library to authenticate is made using the @authUrl@ or @authCallback@, and the request to @authUrl@ fails, the callback @authCallback@ results in an error, the provided token is in an invalid format, or the attempt times out after "@realtimeRequestTimeout@":#DF1b, then: ++*** @(RSA4c1)@An @ErrorInfo@ with @code@ @80019@ and description of the underlying failure should be emitted with the state change, in the @errorReason@ and/or in the callback as appropriate ++*** @(RSA4c2)@If the connection is @CONNECTING@, then the connection attempt should be treated as unsuccessful, and as such the connection should transition to the @DISCONNECTED@ or @SUSPENDED@ state as defined in "RTN14":#RTN14 and "RTN15":#RTN15 ++*** @(RSA4c3)@If the connection is @CONNECTED@, then the connection should remain @CONNECTED@ + * @(RSA14)@ If Token Auth is selected, yet a token is not provided and there is no means to generate a token, then this will result in an error. For example, if only the option @useTokenAuth@ is specified, and a @key@ is not provided, then the client library is unable to authenticate or issue a token + * @(RSA15)@ If Token Auth is selected and @clientId@ has been set in the @ClientOptions@ when the library was instanced: + ** @(RSA15a)@ Any @clientId@ provided in @ClientOptions@ must match any non wildcard (@'*'@) @clientId@ value in @TokenDetails@ or @connectionDetails@ of the @CONNECTED@ @ProtocolMessage@, where applicable +-** @(RSA15b)@ If the @clientId@ from @TokenDetails@ or @connectionDetails@ contains only a wildcard string @'*'@, then the client is permitted to be either unidentified (i.e. anonymous without a @clientId@) or identified by providing a @clientId@ when communicating with Ably +-** @(RSA15c)@ Following an auth request which uses a @TokenDetails@ or @TokenRequest@ object that contains an incompatible @clientId@, the library should in the case of Realtime change the connection state to @FAILED@ and emit an error, and in the case of REST result in an appropriate error response +-* @(RSA5)@ TTL for new tokens is specified in milliseconds (REST API default is 1 hour, see "TK2a":#TK2a) +-* @(RSA6)@ The @capability@ for new tokens is JSON stringified (REST API default is allow all @{"*":["*"]}@, see "TK2b":#TK2b) ++** @(RSA15b)@ If the clientId from @TokenDetails@ or @connectionDetails@ contains only a wildcard string '*', then the client is permitted to be either unidentified (i.e. authorised to act on behalf of any clientId) or identified by providing a @clientId@ when communicating with Ably ++** @(RSA15c)@ Following an auth request which uses a @TokenDetails@ or @TokenRequest@ object that contains an incompatible @clientId@, the library should in the case of Realtime transition the connection state to @FAILED@, and in the case of REST result in an appropriate error response ++* @(RSA5)@ TTL for new tokens is specified in milliseconds. If the user-provided @tokenParams@ does not specify a TTL, the TTL field should be omitted from the @tokenRequest@, and Ably will supply a token with a TTL of 60 minutes. See "TK2a":#TK2a ++* @(RSA6)@ The @capability@ for new tokens is JSON stringified. If If the user-provided @tokenParams@ does not specify capabilities, the @capability@ field should be omitted from the @tokenRequest@, and Ably will supply a token with the capabilities of the underlying key. See "TK2b":#TK2b + * @(RSA7)@ @clientId@ and authenticated clients: + ** @(RSA7a)@ If a @clientId@ is provided in the @ClientOptions@, or is present in the current authentication token, then the client is considered to be identified (it has a @clientId@ that is implicit in all operations). Note that an authentication token @clientId@ wildcard value of @'*'@ is the exception where the client is unidentified and any @clientId@ is permitted in operations with Ably. The following applies to identified clients: + *** @(RSA7a1)@ All operations (such as message publishing or presence) will have an implicit @clientId@. The Ably service automatically updates the @clientId@ attribute (when empty) for all @Message@ and @PresenceMessage@ messages received from that identified client, and any messages then published from the Ably service will have the @clientId@ attribute populated. It is therefore expected that Ably client libraries do not explicitly set the @clientId@ field on messages published when @clientId@ is implicit in the connection or authentication scheme + *** @(RSA7a2)@ If @clientId@ is provided in @ClientOptions@, and an API key is provided along with no other means to generate a token, the client library will authenticate with Ably and obtain a token using the provided @clientId@ ensuring the token is restricted to operations for that @clientId@ +-*** @(RSA7a4)@ When a @clientId@ value is provided in both @ClientOptions#clientId@ and @ClientOptions#defaultTokenParams@, the @ClientOptions#clientId@ takes precendence and is used for all Auth operations ++*** @(RSA7a4)@ When a @clientId@ value is provided in both @ClientOptions#clientId@ and @ClientOptions#defaultTokenParams@, the @ClientOptions#clientId@ takes precedence and is used for all Auth operations + ** @(RSA12)@ @Auth#clientId@ attribute is @null@ when: + *** @(RSA12a)@ The @clientId@ attribute of a @TokenRequest@ or @TokenDetails@ used for authentication is @null@, or @ConnectionDetails#clientId@ is @null@ following a connection to Ably. In this case, the @null@ value indicates that a @clientId@ identity may not be assumed by this client i.e. the client is anonymous for all operations + *** @(RSA12b)@ The client was instanced without assigning a value for @ClientOptions#clientId@ (@null@), and the client has not yet authenticated or connected to Ably. In this case, the @null@ value indicates that the client has not yet been able to confirm its identity, and therefore may change and become identified following later authentication or establishment of a connection with Ably +@@ -121,10 +130,10 @@ h3(#rest-auth). Auth + ** @(RSA8b)@ Supports all @TokenParams@ in the function arguments, which override defaults for @Client@ @Auth@ + ** @(RSA8c)@ When @authUrl@ option is set, it will query the provided URL to obtain a @TokenRequest@ or the token itself (either a token string or a @TokenDetails@). The query is performed using the given URL using the HTTP method in @authMethod@, headers (from @authHeaders@) and supplementary params (from @authParams@). The token retrieved is assumed by the library to be a token string if the response has @Content-Type@ @"text/plain"@, or taken to be a @TokenRequest@ or @TokenDetails@ object if the response has @Content-Type@ @"application/json"@. @authMethod@ can be either @GET@ or @POST@, or if not specified, will default to @GET@. It can be quite difficult to add test coverage for these scenarios - as such, we have developed a simple echo server that can be used in your tests, see the "ably-js authUrl echo tests":https://github.com/ably/ably-js/commit/e77b2c6c197bc71f3d27084fe54524724a00bc92 + *** @(RSA8c1)@ @TokenParams@ and any configured @authParams@ and @authHeaders@ are always sent to the @authUrl@ as follows: +-**** @(RSA8c1a)@ When the @authMethod@ is @GET@ or unspecified, the @TokenParams@ and @authParams@ are merged and appened to the URL as query string params, and the @authHeaders@ are sent as HTTP headers ++**** @(RSA8c1a)@ When the @authMethod@ is @GET@ or unspecified, the @TokenParams@ and @authParams@ are merged and appended to the URL as query string params, and the @authHeaders@ are sent as HTTP headers + **** @(RSA8c1b)@ When the @authMethod@ is @POST@, the @TokenParams@ and @authParams@ are merged and sent form-encoded in the body of the @POST@ request, and the @authHeaders@ are sent as HTTP headers + *** @(RSA8c2)@ @TokenParams@ take precedence over any configured @authParams@ when a name conflict occurs +-*** @(RSA8c3)@ Specifying @authParams@ or @authHeaders@ as part of @AuthOptions@ replaces any configured @authParams@ or @authHeaders@ specified in @ClientOptions@ respectively. As the provided key/value pairs are not merged with the @ClientOptions@ configured key/vaue pairs, this enables a developer to delete @authParams@ or @authHeaders@ where necessary by providing an entire new set of key/value pairs ++*** @(RSA8c3)@ Specifying @authParams@ or @authHeaders@ as part of @AuthOptions@ replaces any configured @authParams@ or @authHeaders@ specified in @ClientOptions@ respectively. As the provided key/value pairs are not merged with the @ClientOptions@ configured key/value pairs, this enables a developer to delete @authParams@ or @authHeaders@ where necessary by providing an entire new set of key/value pairs + ** @(RSA8d)@ When @authCallback@ option is set, it will invoke the callback, passing in the @TokenParams@, and expects either a token string, a @TokenDetails@ object or a @TokenRequest@ object to be returned, which will in turn be used to request a token from Ably + ** @(RSA8f)@ A test should exist for the following: + *** @(RSA8f1)@ Request a token with a @null@ value @clientId@, authenticate a client with the token, publish a message without an explicit @clientId@, and ensure the message published does not have a @clientId@. Check that @Auth#clientId@ is @null@ +@@ -138,21 +147,20 @@ h3(#rest-auth). Auth + ** @(RSA9c)@ Generates a unique 16+ character @nonce@ if none is provided; the nonce is used to protect against replay attacks + ** @(RSA9d)@ Generates a @timestamp@ from current time if not provided, will retrieve the server time if @queryTime@ is true + ** @(RSA9e)@ TTL is optional and specified in milliseconds +-** @(RSA9f)@ Capability JSON text can be provided that specifies the rights of the token in terms of the channel(s) authorised and the permitted operations on each ++** @(RSA9f)@ Capability JSON text can be provided that specifies the rights of the token in terms of the channel(s) authorized and the permitted operations on each + ** @(RSA9g)@ A valid HMAC is created using the key secret to sign the @TokenRequest@ so that it can be used by any client to request a token without having or exchanging any secrets + ** @(RSA9i)@ Adheres to all requirements in @RSA8@ relating to @TokenParams@ +-* @(RSA10)@ @Auth#authorise@ function: +-** @(RSA10a)@ Instructs the library to create a token if needed and uses Token Auth for all future requests +-** @(RSA10j)@ Method signature is @authorise(TokenParams, AuthOptions)@. @TokenParams@ and @AuthOptions@ are optional. When the arguments are present, even if empty, the @TokenParams@ and @AuthOptions@ supersede any previously client library configured @TokenParams@ and @AuthOptions@. For example, if a client is initialised with @TokenParams#ttl@ configured with a custom value, and a @TokenParams@ object is passed in as an argument to @#authorise@ with a @null@ value for @ttl@, then the @ttl@ used for every subsequent authorisation will be @null@. See "@RSA10d@":#RSA10d for an exception ++* @(RSA10)@ @Auth#authorize@ function: ++** @(RSA10a)@ Instructs the library to create a token immediately and ensures Token Auth is used for all future requests. See "RTC8":#RTC8 for re-authentication behavior when called for a realtime client ++** @(RSA10j)@ Method signature is @authorize(TokenParams, AuthOptions)@. @TokenParams@ and @AuthOptions@ are optional. When the arguments are present, even if empty, the @TokenParams@ and @AuthOptions@ supersede any previously client library configured @TokenParams@ and @AuthOptions@. For example, if a client is initialized with @TokenParams#ttl@ configured with a custom value, and a @TokenParams@ object is passed in as an argument to @#authorize@ with a @null@ or missing value for @ttl@, then the @ttl@ used for every subsequent authorization will be @null@ + ** @(RSA10b)@ Supports all @AuthOptions@ and @TokenParams@ in the function arguments +-** @(RSA10c)@ Will not create a new token unless no previous token exists or current token has expired. Please note that a buffer of 15s for token expiry is recommended to avoid race conditions where the token is valid at the time of the request, but invalid when it reaches the server. Therefore, we recommend that a token is considered expired 15s before the time field `expires` +-** @(RSA10d)@ If the @AuthOption@ argument's @force@ attribute is true, it will force @Auth#authorise@ to issue a new token even if an existing token exists. A special case convenience exists for @AuthOption@ stating that if all its attributes are @null@ apart from @force@, then when passed to @authorise@ as an argument, the previously configured authentication options will remain intact. This behaviour takes precedence over "@RSA10j@":#RSA10j +-** @(RSA10k)@ If the @AuthOption@ argument's @queryTime@ attribute is true, it will obtain the server time once and persist the offset from the local clock. All future token requests generated directly or indirectly via a call to authorise will not obtain the server time, but instead use the local clock offset to calculate the server time. A client MAY discard the cached local clock offset in situations in which it may have been invalidated, such as if there is a local change to the date, time, or timezone, of the client device ++** @(RSA10k)@ If the @AuthOption@ argument's @queryTime@ attribute is true, it will obtain the server time once and persist the offset from the local clock. All future token requests generated directly or indirectly via a call to @authorize@ will not obtain the server time, but instead use the local clock offset to calculate the server time. The client library itself MAY internally discard the cached local clock offset in situations in which it may have been invalidated, such as if there is a local change to the date, time, or timezone, of the client device. For clarity however, there is no requirement for this cache invalidation to be available to consumers of the client library API. + ** @(RSA10e)@ Adheres to the implementation of @requestToken@ when issuing new tokens + ** @(RSA10f)@ Returns a @TokenDetails@ object that contains the token string + token metadata +-** @(RSA10g)@ Stores the @AuthOptions@ and @TokenParams@ arguments as defaults for subsequent authorisations with the exception of the attributes @TokenParams#timestamp@, @AuthOptions#queryTime@ and @AuthOptions#force@ ++** @(RSA10g)@ Stores the @AuthOptions@ and @TokenParams@ arguments as defaults for subsequent authorizations with the exception of the attributes @TokenParams#timestamp@ and @AuthOptions#queryTime@ + ** @(RSA10h)@ Will use the value from @Auth#clientId@ by default, if not @null@ + ** @(RSA10i)@ Adheres to all requirements in @RSA8@ relating to @TokenParams@, @authCallback@ and @authUrl@ ++** @(RSA10l)@ Has an alias method @RestClient#authorise@ and @RealtimeClient#authorise@ that will log a deprecation warning stating that this alias method will be removed in @v1.0@ and the user should instead use @authorize@ + + h3(#rest-channels). Channels + +@@ -167,7 +175,7 @@ h3(#rest-channels). Channels + + h3(#rest-channel). Channel + +-* @(RSL1)@ @Channels#publish@ function: ++* @(RSL1)@ @Channel#publish@ function: + ** @(RSL1a)@ Expects either an array of @Message@ objects or a @name@ string and @data@ payload + ** @(RSL1b)@ When @name@ and @data@ is provided, a single message is published to Ably + ** @(RSL1c)@ When an array of @Message@ objects is provided, a single request is made to Ably. When publishing multiple messages, this approach is more efficient. However, a yet to be implemented feature should limit the total number of messages bundled in a single POST based on the default max request size, and would reject the publish and indicate an error if any single message exceeds that limit +@@ -182,14 +190,14 @@ h3(#rest-channel). Channel + *** @(RSL1g2)@ When publishing a @Message@ with the @clientId@ attribute value set to the identified client's @clientId@, Ably will accept the message and publish it. A test should assert that the @clientId@ value is populated for the @Message@ when received + *** @(RSL1g3)@ When publishing a @Message@ with a different @clientId@ attribute value to the identified client's @clientId@, the client library should reject the message, and indicate an error. The connection and channel remain available for further operations + *** @(RSL1g4)@ When publishing a message with an explicit @clientId@ that is incompatible with the identified client's @clientId@ (either inferred or explicitly configured in the token or @ClientOptions@), the library will reject the message immediately and indicate an error +-** @(RSL1h)@ Where the library language permits, the @Channel#publish(name, data)@ method should provide an optional argument that allows the @clientId@ value to be specified such as @Channel#publish('event', 'data', { clientId: 'John' })@ ++** @(RSL1h)@ Where the library language permits, the @Channel#publish(name, data)@ method should provide an optional argument that allows the @clientId@ value to be specified such as @Channel#publish('event', 'data', { clientId: 'John' })@, and/or the @extras@ field to be specified such as @Channel#publish('event', 'data', { extras: { push: { 'key': 'value' } })@ + * @(RSL2)@ @Channel#history@ function: + ** @(RSL2a)@ Returns a @PaginatedResult@ page containing the first page of messages in the @PaginatedResult#items@ attribute returned from the history request + ** @(RSL2b)@ Supports the following params: + *** @(RSL2b1)@ @start@ and @end@ are timestamp fields represented as milliseconds since epoch, or where suitable to the language, Time objects. @start@ must be equal to or less than @end@ and is unaffected by the request direction + *** @(RSL2b2)@ @direction@ backwards or forwards; if omitted the direction defaults to the REST API default (backwards) + *** @(RSL2b3)@ @limit@ supports up to 1,000 items; if omitted the direction defaults to the REST API default (100) +-* @(RSL3)@ @Channel#presence@ attribute returns a @Presence@ object for this channel ++* @(RSL3)@ @Channel#presence@ attribute contains a @Presence@ object for this channel + * @(RSL4)@ Message encoding + ** @(RSL4a)@ Payloads must be binary, strings, or objects capable of JSON representation, or can be empty (omitted). Any other data type should not be permitted and result in an error + ** @(RSL4b)@ If a message is encoded, the @encoding@ attribute represents the encoding(s) applied in right to left format i.e. "utf-8/base64" indicates that the original payload has "utf-8" encoding and has subsequently been encoded in Base64 format +@@ -209,6 +217,8 @@ h3(#rest-channel). Channel + ** @(RSL5c)@ Tests must exist that encrypt and decrypt the following fixture data for "AES 128":https://github.com/ably/ably-common/blob/master/test-resources/crypto-data-128.json and "AES 256":https://github.com/ably/ably-common/blob/master/test-resources/crypto-data-256.json to ensure the client library encryption is compatible across libraries + * @(RSL6)@ Message decoding + ** @(RSL6a)@ All messages received will be decoded automatically based on the @encoding@ field and the payloads will be converted into the format they were originally sent using i.e. binary, string, or JSON ++*** @(RSL6a1)@ A set of tests must exist to ensure that the client library provides data encoding & decoding interoperability with other client libraries. The tests must use the "set of predefined interoperability message fixtures":https://github.com/ably/ably-common/blob/master/test-resources/messages-encoding.json to 1) publish a raw message to the REST API using the JSON transport and subscribe to the message using Realtime to ensure the @data@ attribute matches the fixture; 2) publish a message using the REST client library and retrieve the raw message using the history REST API using the JSON transport ensuring the @data@ matches the fixture; 3) perform the client library operation using both @JSON@ and @MsgPack@ transports. For reference, see the "Ruby":https://github.com/ably/ably-ruby/pull/94 and "iOS":https://github.com/ably/ably-ios/pull/459 implementations ++*** @(RSL6a2)@ A set of tests must exist to ensure that the client library provides interoperability for the @extras@ field which is a JSON-encodable object. The test, at a minimum, should publish a message with an @extras@ object such as @{"push":[{"title":"Testing"}]}@ and ensure it is received with an equivalent JSON-encodable object + ** @(RSL6b)@ If, for example, incompatible encryption details are provided or invalid Base64 is detected in the message payload, an error message will be sent to the logger, but the message will still be delivered with last successful decoding and the @encoding@ field. For example, if a message had a decoding of "utf-8/cipher+aes-128-cbc/base64", and the payload was successfully Base64 decoded but the payload could not be encrypted because the @CipherParam@ details were not configured, the message would be delivered with a binary payload and an @encoding@ with the value "utf-8/cipher+aes-128-cbc" + + h3(#rest-presence). Presence +@@ -242,7 +252,7 @@ h2(#realtime). Realtime client library features + + The Ably Realtime client libraries establish and maintain a persistent connection to Ably and provide methods to publish and subscribe to messages over a low latency realtime connection. + +-The Realtime library is a superset of the REST library and as such all Realtime libraries provide the functionality available in the REST library in addition to Realtime-specific features. ++The Realtime library is a super-set of the REST library and as such all Realtime libraries provide the functionality available in the REST library in addition to Realtime-specific features. + + The threading and/or asynchronous model for each realtime library will vary by language and it is therefore up to the developer to decide on the best approach for each given client library. For example, Node.js and Ruby (EventMachine) use a similar callback single threaded evented approach that ensures all public methods are non-blocking. Java and .NET use a threaded model whereby the @Connection@ runs in its own thread. Go makes extensive use of goroutines and channels. + +@@ -253,18 +263,27 @@ h3(#realtimeclient). RealtimeClient + ** @(RTC1b)@ @autoConnect@ boolean is true by default. If true, as soon as the client library is instanced, it will connect to Ably. If false, the client library will wait for an explicit @Connection#connect@ to be called before connecting + ** @(RTC1c)@ @recover@ string, when set, will attempt to recover the connection state of a previous connection + ** @(RTC1d)@ @realtimeHost@ string, when set, will modify the realtime endpoint host used by this client library +-** @(RTC1e)@ @environment@ string, when set, will modify both the REST and realtime endpoint hosts by prefixing the environment to the default endpoint host with a hypen delimiter. For example, a @RealtimeClient@ with an @environment@ of "sandbox", would use "sandbox-rest.ably.io" as the @restHost@ and @sandbox-realtime.ably.io@ as the @realtimeHost@ ++** @(RTC1e)@ @environment@ string, when set, will modify both the REST and realtime endpoint hosts by prefixing the environment to the default endpoint host with a hypen delimiter. For example, a @RealtimeClient@ with an @environment@ of "sandbox", would use "sandbox-rest.ably.io" as the @restHost@ and @sandbox-realtime.ably.io@ as the @realtimeHost@. See "TO3k3":#TO3k3 for constraints. + * @(RTC2)@ @RealtimeClient#connection@ attribute provides access to the underlying @Connection@ object + * @(RTC3)@ @RealtimeClient#channels@ attribute provides access to the underlying @Channels@ object + * @(RTC4)@ @RealtimeClient#auth@ attribute provides access to the @Auth@ object that was instanced with the @ClientOptions@ provided in the @RealtimeClient@ constructor +-** @(RTC4a)@ Unlike the stateless REST client library, the @Auth#clientId@ is populated when the connection is established. The @CONNECTED@ @ProtocolMessage@ contains the confirmed @clientId@ for this connected client i.e. the client is considered identified. See "@RSA7b@":#RSA7b and "@RSA12@":#RSA12 for futher info ++** @(RTC4a)@ Unlike the stateless REST client library, the @Auth#clientId@ is populated when the connection is established. The @CONNECTED@ @ProtocolMessage@ contains the confirmed @clientId@ for this connected client i.e. the client is considered identified. See "@RSA7b@":#RSA7b and "@RSA12@":#RSA12 for further info + * @(RTC5)@ @RealtimeClient#stats@ function: + ** @(RTC5a)@ Proxy to @RestClient#stats@ presented with an async or threaded interface as appropriate + ** @(RTC5b)@ Accepts all the same params as @RestClient#stats@ and provides all the same functionality + * @(RTC6)@ @RealtimeClient#time@ function: + ** @(RTC6a)@ Proxy to @RestClient#time@ presented with an async or threaded interface as appropriate + * @(RTC7)@ The client library must use the configured timeouts specified in the @ClientOptions@, falling back to the "client library defaults":#defaults and defaults described in @ClientOptions@ below +-* @(RTC8)@ Authentication token changes for the current connection are possible when the client is in the @CONNECTED@, @CONNECTING@ or @DISCONNECTED@ states. If @auth.authorise@ is called with @AuthOptions#force@ set to @true@ and the state is @CONNECTED@, @CONNECTING@, or @DISCONNECTED@, the client will obtain a new token, disconnect the current transport and resume the connection (see "@RTN15c@":#RTN15c for details on resume). A test should exist that performs an upgrade of capabilities without any message loss during the upgrade process. A test should also exist for a token change that fails due to an incompatible token, which should result in the connection entering the @FAILED@ state ++* @(RTC8)@ For a realtime client, @Auth#authorize@ instructs the library to obtain a token using the provided @tokenParams@ and @authOptions@ and upgrade the current connection to use that token; or if not currently connected, to connect with the token. ++** @(RTC8a)@ If the connection is in the @CONNECTED@ state and @auth#authorize@ is called or Ably requests a re-authentication (see "RTN22":#RTN22), the client must obtain a new token, then send an @AUTH@ @ProtocolMessage@ to Ably with an @auth@ attribute containing an @AuthDetails@ object with the token string ++*** @(RTC8a1)@ If the authentication token change is successful, then Ably will send a new @CONNECTED@ @ProtocolMessage@. The @connectionDetails@ provided in the @CONNECTED@ @ProtocolMessage@ must override any existing defaults, see "RTN21":#RTN21. The @Connection@ should emit an @UPDATE@ event per @RTN24@. A test should exist that performs an upgrade of capabilities without any loss of continuity or connectivity during the upgrade process. Another test should exist where the capabilities are downgraded resulting in Ably sending an @ERROR@ @ProtocolMessage@ with a @channel@ property, causing the channel to enter the @FAILED@ state. That test must assert that the channel becomes failed soon after the token update and the reason is included in the channel state change event ++*** @(RTC8a2)@ If the authentication token change fails, then Ably will send an @ERROR@ @ProtocolMessage@ triggering the connection to transition to the @FAILED@ state. A test should exist for a token change that fails (such as sending a new token with an incompatible @clientId@) ++*** @(RTC8a3)@ The @authorize@ call should be indicated as completed with the new token or error only once realtime has responded to the @AUTH@ with either a @CONNECTED@ or @ERROR@ respectively. ++** @(RTC8b)@ If the connection is in the @CONNECTING@ state when @auth#authorize@ is called, all current connection attempts should be halted, and after obtaining a new token the library should immediately initiate a connection attempt using the new token ++*** @(RTC8b1)@ The @authorize@ call should be indicated as completed with the new token once the connection has moved to the @CONNECTED@ state, or with an error if the connection instead moves to the @FAILED@, @SUSPENDED@, or @CLOSED@ states ++** @(RTC8c)@ If the connection is in the @DISCONNECTED@, @SUSPENDED@, @FAILED@, or @CLOSED@ state when @auth#authorize@ is called, after obtaining a token the library should move to the @CONNECTING@ state and initiate a connection attempt using the new token, and @RTC8b1@ applies. ++* @(RTC9)@ @RealtimeClient#request@ is a wrapper around @RestClient#request@ (see "RSC19":#RSC19) delivered in an idiomatic way for the realtime library, e.g. in the case of Ruby, with an evented async callback interface ++* @(RTC10)@ The client library should never register any listeners for internal use with the public @EventEmitter@ interfaces (such as @Connection#on@) or message/event subscription interfaces (such as @Channel#subscribe@) in such a way that a user of the library calling @Connection#off()@ or @Channel#unsubscribe()@ to remove all listeners would result in the library not working as expected + + h3(#realtime-connection). Connection + +@@ -274,22 +293,27 @@ h3(#realtime-connection). Connection + ** @(RTN2b)@ @echo@ should be @true@ by default; @false@ will prevent messages published by the client being echoed back + ** @(RTN2d)@ @clientId@ contains the provided @clientId@ option of @ClientOptions@, unless @clientId@ is @null@ + ** @(RTN2e)@ Depending on the authentication scheme, either @accessToken@ contains the token string, or @key@ contains the API key +-** @(RTN2f)@ API version param @v@ should be @0.8@ ++** @(RTN2f)@ API version param @v@ should be @1.0@ ++** @(RTN2g)@ Library and version param @lib@ should include the header value described in "RSC7b":#RSC7b. For example, the 1.0.0 version of the Javascript library would use the param @lib=js-1.0.0@ + * @(RTN3)@ If connection option @autoConnect@ is true, a connection is initiated immediately; otherwise a connection is only initiated following an explicit call to @connect()@ +-* @(RTN4)@ EventEmitter and states: +-** @(RTN4a)@ Implements @EventEmitter@ and emits events for state changes @INITIALIZED@, @CONNECTING@, @CONNECTED@, @DISCONNECTED@, @SUSPENDED@, @CLOSING@, @CLOSED@, @FAILED@ ++* @(RTN4)@ The @Connection@ implements @EventEmitter@ and emits @ConnectionEvent@ events ++** @(RTN4a)@ It emits a @ConnectionState@ event (one of @INITIALIZED@, @CONNECTING@, @CONNECTED@, @DISCONNECTED@, @SUSPENDED@, @CLOSING@, @CLOSED@, @FAILED@) for every connection state change ++** @(RTN4h)@ It can emit an @UPDATE@ event (this is the only @ConnectionEvent@ which is not a @ConnectionState@). This is used for changes to connection conditions for which the @ConnectionState@ (e.g. @CONNECTED@) does not change. (The library must never emit a @ConnectionState@ event for a state equal to the previous state). + ** @(RTN4b)@ A new connection will emit the following events in order when connecting: @CONNECTING@, then @CONNECTED@ + ** @(RTN4c)@ A connection will emit the following events when closing the connection: @CLOSING@, then @CLOSED@ + ** @(RTN4d)@ @Connection#state@ attribute is the current state of the connection +-** @(RTN4e)@ A @ConnectionStateChange@ object is emitted as the first argument for every connection state change +-** @(RTN4f)@ Additionally, a @ConnectionStateChange@ can be emitted that contains a @reason@ which contains an @ErrorInfo@ object with details of the error that has occurred for the @Connection@ ++** @(RTN4e)@ A @ConnectionStateChange@ object is emitted as the first argument for every @ConnectionEvent@ (including both @RTN4a@ connection state changes and @RTL4h@ @UPDATE@ events) ++** @(RTN4f)@ The @ConnectionStateChange@ object may contain a @reason@ consisting of an @ErrorInfo@ object with details of the error that has occurred for the @Connection@. Any state change triggered by a @ProtocolMessage@ that contains an @error@ member should populate the @reason@ with that error in the corresponding state change event ++** @(RTN4i)@ Optionally, for backwards compatibility with 0.8 libraries, the @Connection@ @EventEmitter@ can provide an overloaded method that supports @on(ConnectionState)@, but must issue a deprecation warning + * @(RTN5)@ A test should exist that instances many (50+) clients simultaneously and performs a few basic operations such as attaching to a channel, publishing a message, and expecting all of those messages to arrive on all clients to ensure that there are no concurrency issues with the client library +-* @(RTN6)@ A @Connection@ is successful and considered @CONNECTED@ once the websocket connection is open and the intial @CONNECTED@ @ProtocolMessage@ has been received +-* @(RTN19)@ If the @CONNECTED@ @ProtocolMessage@ contains a @connectionDetails@ property, the attributes within @ConnectionDetails@ will be used as the defaults for this client library, overriding any configured options at the time the @CONNECTED@ @ProtocolMessage@ is received ++* @(RTN6)@ A @Connection@ is successful and considered @CONNECTED@ once the websocket connection is open and the initial @CONNECTED@ @ProtocolMessage@ has been received ++* @(RTN21)@ If the @CONNECTED@ @ProtocolMessage@ contains a @connectionDetails@ property, the attributes within @ConnectionDetails@ will be used as the defaults for this client library, overriding any configured options at the time the @CONNECTED@ @ProtocolMessage@ is received + * @(RTN7)@ @ACK@ and @NACK@: +-** @(RTN7a)@ All @ProtocolMessage@ @Presence@ and @Message@ objects sent to Ably expect either an @ACK@ or @NACK@ from Ably to confirm successful receipt and acceptance or failure respectively ++** @(RTN7a)@ All @ProtocolMessage@ @Presence@ and @Message@ objects sent to Ably expect either an @ACK@ or @NACK@ from Ably to confirm successful receipt and acceptance or failure respectively. For clarity, it is unnecessary to fail the publish operation of a message using a timer. Instead the client library can rely on: the realtime system will send an @ACK@ or @NACK@ when connected; the client library will fail all awaiting messages once @SUSPENDED@ (see "RTN7c":#RTN7c); upon reconnecting, the client will resend all message awaiting a response, and the realtime system in turn will respond with an @ACK@ or @NACK@ (see "RTN19a":#RTN19a) + ** @(RTN7b)@ Every @ProtocolMessage@ sent must contain a unique serially incrementing @msgSerial@ integer value starting at zero. The @msgSerial@ along with the @count@ for incoming @ACK@ and @NACK@ @ProtocolMessages@ indicates which messages succeeded or failed to be delivered +-** @(RTN7c)@ If a connection enters the @CLOSED@ or @FAILED@ state, or if the connection state is lost, and a @ACK@ or @NACK@ has not yet been received for a message, the client should consider the delivery of those messages as failed ++** @(RTN7c)@ If a connection enters the @SUSPENDED@, @CLOSED@ or @FAILED@ state, or if the connection state is lost, and an @ACK@ or @NACK@ has not yet been received for a message, the client should consider the delivery of those messages as failed ++* @(RTN22)@ Ably can request that a connected client re-authenticates by sending the client an @AUTH@ @ProtocolMessage@. The client must then immediately start a new authentication process as described in "RTC8":#RTC8 ++** @(RTN22a)@ Ably reserves the right to forcibly disconnect a client that does not re-authenticate within an acceptable period of time, or at any time the token is deemed no longer valid. A client is forcibly disconnected following a @DISCONNECTED@ message containing an error code in the range @40140 <= code < 40150@. This will in effect force the client to re-authenticate and resume the connection immediately, see "RTN15h":#RTN15h + * @(RTN8)@ @Connection#id@ attribute: + ** @(RTN8a)@ Is @null@ until connected + ** @(RTN8b)@ Is a unique string provided by Ably. You should have a test to ensure multiple connected clients have unique connection IDs +@@ -304,63 +328,66 @@ h3(#realtime-connection). Connection + ** @(RTN11a)@ Explicitly connects to the Ably service if not already connected + ** @(RTN11b)@ If the state is @CLOSING@, the client should make a new connection with a new transport instance and remove all references to the old one. In particular, it should make sure that, when the @CLOSED@ @ProtocolMessage@ arrives for the old connection, it doesn't affect the new one. + ** @(RTN11c)@ If the state is @DISCONNECTED@ or @SUSPENDED@, aborts the retry process described in "RTN14d":#RTN14d and "RTN14e":#RTN14e and immediately tries to reconnect. +-** @(RTN11d)@ If the state is @FAILED@, moves all the channels to @INITIALIZED@, sets their @errorReason@ to @null@, and sets the connection's @errorReason@ to @null@. ++** @(RTN11d)@ If the state is @FAILED@, transitions all the channels to @INITIALIZED@, sets their @errorReason@ to @null@, and sets the connection's @errorReason@ to @null@. + * @(RTN12)@ @Connection#close@ function: + ** @(RTN12f)@ If the connection state is @CONNECTING@, moves immediately to @CLOSING@. If the connection attempt succeeds, ie. a @CONNECTED@ @ProtocolMessage@ arrives from Ably, then do as specified in "RTN12a":#RTN12a. If it doesn't succeed, move to @CLOSED@. +-** @(RTN12a)@ If the connection state is @CONNECTED@, sends a @CLOSE@ @ProtocolMessage@ to the server, sets the state to @CLOSING@ and waits for a @CLOSED@ @ProtocolMessage@ to be received +-** @(RTN12b)@ If the @CLOSED@ @ProtocolMessage@ is not received within the "default realtime request timeout":#defaults, the transport will be disconnected and the connection will automatically move to the @CLOSED@ state +-** @(RTN12c)@ If the transport is abruptly closed following a @CLOSE@ @ProtocolMessage@ being sent, then the connection will automatically move to the @CLOSED@ state +-** @(RTN12d)@ If the connection state is @DISCONNECTED@ or @SUSPENDED@, aborts the retry process described in "RTN14d":#RTN14d and "RTN14e":#RTN14e and moves the connection immediately to the @CLOSED@ state ++** @(RTN12a)@ If the connection state is @CONNECTED@, sends a @CLOSE@ @ProtocolMessage@ to the server, transitions the state to @CLOSING@ and waits for a @CLOSED@ @ProtocolMessage@ to be received ++** @(RTN12b)@ If the @CLOSED@ @ProtocolMessage@ is not received within the "default realtime request timeout":#defaults, the transport will be disconnected and the connection will automatically transition to the @CLOSED@ state ++** @(RTN12c)@ If the transport is abruptly closed following a @CLOSE@ @ProtocolMessage@ being sent, then the connection will automatically transition to the @CLOSED@ state ++** @(RTN12d)@ If the connection state is @DISCONNECTED@ or @SUSPENDED@, aborts the retry process described in "RTN14d":#RTN14d and "RTN14e":#RTN14e and transitions the connection immediately to the @CLOSED@ state + * @(RTN13)@ @Connection#ping@ function: +-** @(RTN13c)@ If the connection state is @CONNECTING@ or @DISCONNECTED@, do the operation once the connection state is @CONNECTED@ ++** @(RTN13d)@ If the connection state is @CONNECTING@ or @DISCONNECTED@, do the operation once the connection state is @CONNECTED@ + ** @(RTN13a)@ Will send a @ProtocolMessage@ with action @HEARTBEAT@ the Ably service when connected and expects a @HEARTBEAT@ message in response. If the client library language supports callbacks, then the callback will be called with the response time or error +-** @(RTN13b)@ Will indicate an error if in, or has moved to, the @INITIALIZED@, @SUSPENDED@, @CLOSING@, @CLOSED@ or @FAILED@ state ++** @(RTN13b)@ Will indicate an error if in, or has transitioned to, the @INITIALIZED@, @SUSPENDED@, @CLOSING@, @CLOSED@ or @FAILED@ state + ** @(RTN13c)@ Will fail if a @HEARTBEAT@ @ProtocolMessage@ is not received within the "default realtime request timeout":#defaults ++** @(RTN13e)@ The @ProtocolMessage@ sent should include an @id@ property, with value a random string. If so, only a @HEARTBEAT@ response which includes an @id@ property with the same value should be considered a response to that ping, in order to disambiguate from normal heartbeats and other pings. + * @(RTN14)@ @Connection@ opening failures: +-** @(RTN14a)@ If an API key is invalid, then the connection will enter the @FAILED@ state and the @Connection#errorReason@ will be set on the @Connection@ object as well as the emitted @ConnectionStateChange@ +-** @(RTN14b)@ If a connection request fails due to an @ERROR@ ProtocolMessage being sent to the client containing a token error (@statusCode@ value of 401 and error @code@ value in the range @40140 <= @code < 40150@), then if the token is renewable, the error should not emitted, a single attempt to create a new token will be made and a new connection attempt will be initiated using the new token. If the token creation fails, the next connection attempt fails again due to a token error, or the token was not renewable, the connection will transition to the @FAILED@ state and the @Connection#errorReason@ will be set ++** @(RTN14a)@ If an API key is invalid, then the connection will transition to the @FAILED@ state and the @Connection#errorReason@ will be set on the @Connection@ object as well as the emitted @ConnectionStateChange@ ++** @(RTN14b)@ If a connection request fails due to an @ERROR@ @ProtocolMessage@ being received by the client containing a token error (@statusCode@ value of 401 and error @code@ value in the range @40140 <= code < 40150@) and an empty @channel@ attribute, then if the token is renewable, a single attempt to create a new token should be made and a new connection attempt initiated using the newly created token. If the attempt to create a new token fails, or the subsequent connection attempt fails due to another token error, then the connection will transition to the @FAILED@ state and the @Connection#errorReason@ should be set ++** @(RTN14g)@ If an @ERROR@ @ProtocolMessage@ with an empty @channel@ attribute is received for any reason other than "RTN14b":#RTN14b, then the connection will transition to the @FAILED@ state and the server will terminate the connection. Additionally the @Connection#errorReason@ must be set with the error from the @ERROR@ @ProtocolMessage@ + ** @(RTN14c)@ A new connection attempt will fail if not connected within the "default realtime request timeout":#defaults +-** @(RTN14d)@ If a connection attempt fails for any recoverable reason (i.e. a network failure or a recoverable authentication failure), the @Connection#state@ will change to @DISCONNECTED@, the @Connection#errorReason@ will be updated, a @ConnectionStateChange@ with the @reason@ will be emitted, and new connection attempts will periodically be made until the maximum time in that state threshold is reached. The @retryIn@ attribute of the @ConnectionStateChange@ object will contain the time in milliseconds until the next connection attempt. See the @disconnectedRetryTimeout@ of @ClientOptions@ below. Each time a new connection attempt is made the state will change to @CONNECTING@ and then to @CONNECTED@ if successful, or @DISCONNECTED@ if unsuccessful and the "default @connectionStateTtl@":#defaults has not been exceeded ++** @(RTN14d)@ If a connection attempt fails for any recoverable reason (i.e. a network failure or timeout such as "RTN14c":#RTN14c other than a token failure "RTN14b":#RTN14b), the @Connection#state@ will transition to @DISCONNECTED@, the @Connection#errorReason@ will be updated, a @ConnectionStateChange@ with the @reason@ will be emitted, and new connection attempts will periodically be made until the maximum time in that state threshold is reached. The @retryIn@ attribute of the @ConnectionStateChange@ object will contain the time in milliseconds until the next connection attempt. See the @disconnectedRetryTimeout@ of @ClientOptions@ below. Each time a new connection attempt is made the state will transition to @CONNECTING@ and then to @CONNECTED@ if successful, or @DISCONNECTED@ if unsuccessful and the "default @connectionStateTtl@":#defaults has not been exceeded + ** @(RTN14e)@ Once the connection state has been in the @DISCONNECTED@ state for more than the "default @connectionStateTtl@":#defaults, the state will change to @SUSPENDED@ and be emitted with the @reason@, and the @Connection#errorReason@ will be updated. In this state, a new connection attempt will be made periodically as specified within @suspendedRetryTimeout@ of @ClientOptions@ + ** @(RTN14f)@ The connection will remain in the @SUSPENDED@ state indefinitely, whilst periodically attempting to reestablish a connection + * @(RTN15)@ @Connection@ failures once @CONNECTED@: +-** @(RTN15h)@ If a @DISCONNECTED@ message is received from Ably, then that transport will subsequently be closed by Ably. If the @DISCONNECTED@ message contains a token error (@statusCode@ value of 401 and error @code@ value in the range @40140 <= @code < 40150@), if the token is renewable, the error should not emitted, a single attempt to create a new token will be made and a new connection attempt will be initiated using the new token. If the token creation fails, the next connection attempt fails due to a token error, or the token was not renewable, the connection will transition to the @FAILED@ state and the @Connection#errorReason@ will be set +-** @(RTN15a)@ If a @Connection@ transport is disconnected unexpectedly or if a token expires, then the @Connection@ manager will immediately attempt to reconnect and restore the connection state. Connection state recovery is provided by the Ably service and ensures that whilst the client is disconnected, all events are queued and channel state is retained on the Ably servers. When a new connection is made with the correct connection recovery key, the client is able to catch up by receiving the queued @ProtocolMessages@ from Ably. Connection state is only maintained for a brief period, up to a minute, so if a client is disconnected for a longer period connection state cannot be resumed ++** @(RTN15h)@ If a @DISCONNECTED@ message is received from Ably, then that transport will subsequently be closed by Ably. If the @DISCONNECTED@ message contains a token error (@statusCode@ value of 401 and error @code@ value in the range @40140 <= code < 40150@), if the token is renewable, a single attempt to create a new token should be made and a new connection attempt initiated using the new token. If the token creation fails, the next connection attempt fails due to a token error, or the token was not renewable, the connection will transition to the @FAILED@ state and the @Connection#errorReason@ will be set ++** @(RTN15i)@ If an @ERROR@ @ProtocolMessage@ is received, this indicates a fatal error in the connection. The server will close the transport immediately after. The client should transition to the @FAILED@ state triggering all attached channels to transition to the @FAILED@ state as well. Additionally the @Connection#errorReason@ should be set with the error received from Ably ++** @(RTN15a)@ If a @Connection@ transport is disconnected unexpectedly or if a token expires, then the @Connection@ manager will immediately attempt to reconnect and restore the connection state. Connection state recovery is provided by the Ably service and ensures that whilst the client is disconnected, all events are queued and channel state is retained on the Ably servers. When a new connection is made with the correct connection recovery key, the client is able to catch up by receiving the queued @ProtocolMessages@ from Ably. Connection state is only maintained for a brief period, up to two minutes, so if a client is disconnected for a longer period connection state cannot be resumed + ** @(RTN15b)@ In order for a connection to be resumed and connection state to be recovered, the client library reconnects to the websocket endpoint with two additional querystring params: + *** @(RTN15b1)@ @resume@ is the private connection key assigned to the connection when the first @CONNECTED@ @ProtocolMessage@ was received + *** @(RTN15b2)@ @connectionSerial@ is the most recent @ProtocolMessage#connectionSerial@ received from Ably or @Connection#serial@ which should be identical + ** @(RTN15c)@ The system's response to a resume request will be one of the following: + **** @(RTN15c1)@ @CONNECTED@ @ProtocolMessage@ with the same @connectionId@ as the current client, and no @error@. In this case, the server is indicating that the resume succeeded, all channels are still attached, and all backlog messages are available. The client should not change the state of attached channels, and immediately process any queued messages for that channel +-**** @(RTN15c2)@ @CONNECTED@ @ProtocolMessage@ with the same @connectionId@ as the current client, and an @error@. In this case, the server is indicating that the resume succeeded but with a non-fatal error, all channels are still attached, and some backlog messages may be unavailable. The @ErrorInfo@ received should be emitted on the client @Connection@ and the @Connection#errorReason@ should be set. The client should not change the state of attached channels, and immediately process any queued messages for that channel. Any channels that are not resumed in full may receive an @ATTACHED@ @ProtocolMessage@ with an @error@, see "@RTL12@":#RTL12 +-**** @(RTN15c3)@ @CONNECTED@ @ProtocolMessage@ with a new @connectionId@, and an error in @error@. In this case, a new connection has been established, the resume has failed, the channels are no longer attached, and the error indicates the resume problem which should be emitted. The client library should immediately detach all channels, fail any queued messages on those channels, and set the @Channel#errorReason@ on each detached @Channel@. Additionally, the internal @msgSerial@ counter is reset so that the first message published to Ably will contain a @msgSerial@ value of @0@ +-**** @(RTN15c4)@ @ERROR@ @ProtocolMessage@ indicating a fatal error in the connection. The server will close the transport immediately after. If the @ERROR@ is non-recoverable, the client will move to the @FAILED@ state triggering all attached channels to move to the @FAILED@ state as well +-** @(RTN15g)@ When the connection resume has failed, all channels should be detached with a suitable error reason ++**** @(RTN15c2)@ @CONNECTED@ @ProtocolMessage@ with the same @connectionId@ as the current client, and an @error@. In this case, the server is indicating that the resume succeeded but with a non-fatal error, all channels are still attached, and some backlog messages may be unavailable. The @ErrorInfo@ received should be set as the @reason@ in the @CONNECTED@ event, and the @Connection#errorReason@ should be set. The client should not change the state of attached channels, and immediately process any queued messages for that channel. Any channels that are not resumed in full may receive an @ATTACHED@ @ProtocolMessage@ with an @error@, see "@RTL12@":#RTL12 ++**** @(RTN15c3)@ @CONNECTED@ @ProtocolMessage@ with a new @connectionId@, and an error in @error@. In this case, a new connection has been established, the resume was unsuccessful, the channels are no longer attached, and the error indicates the cause of the unsuccessful resume. The @ErrorInfo@ should be set as the @reason@ in the @CONNECTED@ event, and the @Connection#errorReason@ should be set. The client library should initiate an attach for channels that are in the @SUSPENDED@ state. For all channels in the @ATTACHING@ or @ATTACHED@ state, the client library should fail any previously queued messages for that channel and initiate a new attach i.e. a new @ATTACH@ @ProtocolMessage@ must be sent for each channel. Finally, the internal @msgSerial@ counter is reset so that the first message published to Ably will contain a @msgSerial@ value of @0@ ++**** @(RTN15c5)@ @ERROR@ @ProtocolMessage@ indicating a failure to authenticate as a result of a token error (see "RTN15h":#RTN15h). The transport will be closed by the server. The spec described in "RTN15h":#RTN15h must be followed for a connection being resumed with a token error ++**** @(RTN15c4)@ Any other @ERROR@ @ProtocolMessage@ indicating a fatal error in the connection. The server will close the transport immediately after. The client should transition to the @FAILED@ state triggering all attached channels to transition to the @FAILED@ state as well. Additionally the @Connection#errorReason@ will be set should be set with the error received from Ably + ** @(RTN15f)@ @ACK@ and @NACK@ responses for published messages can only ever be received on the transport connection on which those messages were sent. Therefore, once a transport drops, the client library must either fail the publish attempt, or re-attempt by re-sending the messages on a new transport if the resume was successful (i.e. the @CONNECTED@ response includes the expected @connectionId@) +-** @(RTN15d)@ Client libraries should have test coverage to ensure connection state recovery is working as expected by forciby disconnecting a client and checking that messages published on channels are delivered once the connection is resumed ++** @(RTN15d)@ Client libraries should have test coverage to ensure connection state recovery is working as expected by forcibly disconnecting a client and checking that messages published on channels are delivered once the connection is resumed + ** @(RTN15e)@ When a connection is resumed, the @Connection#key@ may change and will be provided in the first @CONNECTED@ @ProtocolMessage#connectionDetails@ when the connection is established. The client library must update the @Connection#key@ value with the new @connectionKey@ value every time + * @(RTN20)@ When the client library can subscribe to the Operating System events for network/internet connectivity changes: +-** @(RTN20a)@ When @CONNECTED@, @CONNECTING@ or @DISCONNECTING@, if the operating system indicates that the underlying internet connection is no longer available, then the client library should immediately change the state to @DISCONNECTED@ with emit a state change with an appropriate @reason@. This state change will automatically trigger the client library to attempt to reconnect, see @RTN15@ above ++** @(RTN20a)@ When @CONNECTED@, @CONNECTING@ or @DISCONNECTING@, if the operating system indicates that the underlying internet connection is no longer available, then the client library should immediately transition the state to @DISCONNECTED@ with emit a state change with an appropriate @reason@. This state change will automatically trigger the client library to attempt to reconnect, see @RTN15@ above + ** @(RTN20b)@ When @DISCONNECTED@ or @SUSPENDED@, if the operating system indicates that the underlying internet connection is now available, the client library should immediately attempt to connect + * @(RTN16)@ @Connection@ recovery: +-** @(RTN16a)@ Connection recovery is similar to the automatic connection resume except that connection state is recovered explicitly because a @recover@ key is passed to the Realtime library when instanced. Once a connection is recovered, all channels must be explicitly attached by the developer, and any messages queued to be delivered whilst the client was disconnected will be delivered ++** @(RTN16a)@ Connection recovery follows the resume spec "RTN15c":#RTN15c in respect to the expected response from the server. However, connection recovery is different in that the library has no state at the time of connection and recovers the connection based as a result of @recover@ key being explicitly provided to the Realtime library when instanced. Once a connection is recovered, all channels must be explicitly attached by the developer + ** @(RTN16b)@ @Connection#recoveryKey@ is an attribute composed of the connection key and latest serial received on the connection + ** @(RTN16c)@ @Connection#recoveryKey@ becomes @Null@ when a connection is explicitly @CLOSED@ or @CLOSED@ by the server, as connection state is not retained for connections closed intentionally. The @Connection#key@ and @Connection#id@ is set to @Null@ + ** @(RTN16d)@ When a connection is successfully recovered, the @Connection#id@ will be identical to the @id@ of the connection that was recovered, and @Connection#key@ will always be updated to the @ConnectionDetails#connectionKey@ provided in the first @CONNECTED@ @ProtocolMessage@ + ** @(RTN16e)@ If the @recover@ option is missing or no longer valid when connecting to Ably, the client will connect anyway, but emit a @ConnectionStateChange@ with a @reason@, and will additionally set the @Connection#errorReason@ with an @ErrorInfo@ object describing the failure + * @(RTN17)@ Host Fallback +-** @(RTN17b)@ The fallback behaviour described below only applies when the default @realtime.ably.io@ endpoint is being used and has not been overriden, see "RTC1d":#RTC1d and "RTC1e":#RTC1e. +-** @(RTN17a)@ By default, every connection attempt is first attempted to the primary host @realtime.ably.io@, which, through DNS, is automatically routed to the client's closest data centre. The client library must always prefer the default endpoint (closest data centre), even if a previous connection attempt to that endpoint has failed +-** @(RTN17c)@ In the case of an error necessitating use of an alternative host (see "RTN17d":#RTN17d), the @Connection@ manager should first check if an internet connection is available by issuing a @GET@ request to @https://internet-up.ably-realtime.com/is-the-internet-up.txt@. If the request succeeds and the text "yes" is included in the body, then the client library can assume it has a viable internet connection and should then immediately retry the connection against all fallback hosts to find an alternative healthy data centre. The five fallback hosts are @[a-e].ably-realtime.com@ and should be attempted in random order +-** @(RTN17d)@ Errors that necessitate use of an alternative host include: host unresolvable or unreachable, connection timeout, or a response but with an "error body @statusCode@":/rest-api#error-response or HTTP response status code in the range @500 <= code <= 504@. Attempting to reconnect to a fallback host for other failure conditions will not fix the problem and will simply increase the load on other data centres unnecessarily +-** @(RTN17e)@ If the realtime client is connected to a fallback host endpoint, then for the duration that the transport is connected to that host, all HTTP requests, such as history or token requests, should be first attempted to the same data centre the realtime connection is established with i.e. the same fallback host must be used as the default HTTP request host. If however the HTTP request against that fallback host fails, then the normal fallback host behaviour should be followed attempting the request against another fallback host as described in "RSC15":#RSC15 +-* @(RTN18)@ Connection state change side effects: +-** @(RTN18a)@ When a connection enters the @DISCONNECTED@ state, it will have no effect on the channel states. Channels in the @ATTACHED@ state will queue messages that are sent as soon as the connection is resumed +-** @(RTN18b)@ When a connection enters the @CLOSED@ or @SUSPENDED@ state, all channels will move to the @DETACHED@ state. Channels in the @DETACHED@ state should reject publishing of messages +-** @(RTN18c)@ When a connection enters the @FAILED@ state, all channels will move to the @FAILED@ state. Channels in the @FAILED@ state should reject publishing of messages ++** @(RTN17b)@ The fallback behavior described below only applies when the default @realtime.ably.io@ endpoint is being used and has not been overriden (see "RTC1d":#RTC1d and "RTC1e":#RTC1e), @ClientOptions#fallbackHostsUseDefault@ is @true@, or an array of @ClientOptions#fallbackHosts@ is provided. ++** @(RTN17a)@ By default, every connection attempt is first attempted to the default primary host @realtime.ably.io@ (unless overriden in @ClientOptions#realtimeHost@), which, through DNS, is automatically routed to the client's closest data center. The client library must always prefer the default endpoint (closest data center), even if a previous connection attempt to that endpoint has failed ++** @(RTN17c)@ In the case of an error necessitating use of an alternative host (see "RTN17d":#RTN17d), the @Connection@ manager should first check if an internet connection is available by issuing a @GET@ request to @https://internet-up.ably-realtime.com/is-the-internet-up.txt@. If the request succeeds and the text "yes" is included in the body, then the client library can assume it has a viable internet connection and should then immediately retry the connection against all fallback hosts to find an alternative healthy data center. The five default fallback hosts are @[a-e].ably-realtime.com@ and should be attempted in random order. See "RSC15a":#RSC15a for details on how custom fallback hosts are specified and used ++** @(RTN17d)@ Errors that necessitate use of an alternative host include: host unresolvable or unreachable, connection timeout, or a response but with an "error body @statusCode@":/rest-api#error-response or HTTP response status code in the range @500 <= code <= 504@. Attempting to reconnect to a fallback host for other failure conditions will not fix the problem and will simply increase the load on other data-centers unnecessarily ++** @(RTN17e)@ If the realtime client is connected to a fallback host endpoint, then for the duration that the transport is connected to that host, all HTTP requests, such as history or token requests, should be first attempted to the same data center the realtime connection is established with i.e. the same fallback host must be used as the default HTTP request host. If however the HTTP request against that fallback host fails, then the normal fallback host behavior should be followed attempting the request against another fallback host as described in "RSC15":#RSC15 + * @(RTN19)@ Transport state side effects - when a transport is upgraded or disconnected for any reason: + ** @(RTN19a)@ Any @ProtocolMessage@ that is awaiting an @ACK@/@NACK@ on the old transport will not receive the @ACK@/@NACK@ on the new transport. The client library must therefore resend any @ProtocolMessage@ that is awaiting a @ACK@/@NACK@ to Ably in order to receive the expected @ACK@/@NACK@ for that message. The Ably service is responsible for keeping track of messages, ignoring duplicates and responding with suitable @ACK@/@NACK@ messages + ** @(RTN19b)@ If there are any pending channels i.e. in the @ATTACHING@ or @DETACHING@ state, the respective @ATTACH@ or @DETACH@ message should be resent to Ably + ** @(RTN19b)@ If a @SYNC@ is underway, ensure the client library adheres to @RTP3@ ++* @(RTN23)@ Heartbeats ++** @(RTN23a)@ If a transport does not receive any indication of activity on a transport for a period greater than the sum of the @maxIdleInterval@ (which will be sent in the @connectionDetails@ of the most recent @CONNECTED@ message received on that transport) and the @realtimeRequestTimeout@, that transport should be disconnected. This requirement is not mandatory; in deciding whether to implement, client library developers should take into account whether the transport in question is susceptible to undetected dropped connections. Any message (or non-message indicator, see @RTN23b@) received counts as an indication of activity and should reset the timer, not merely heartbeat messages. However, it must be received (that is, sent from the server to the client); client-sent data does count. ++** @(RTN23b)@ When initiating a connection, the client may send a @heartbeats@ param in the querystring, with value @true@ or @false@. If the value is true, the server will use Ably protocol messages (for example, a message with a @HEARTBEAT@ action) to satisfy the @maxIdleInterval@ requirement. If it is false or unspecified, the server is permitted to use any transport-level mechanism (for example, websocket ping frames) to satisfy this. So for example, for websocket transports, if the client is able to observe websocket pings, then it should send @heartbeats=false@. If not, it should send @heartbeats=true@. ++* @(RTN24)@ A connected client may receive a @CONNECTED@ @ProtocolMessage@ from Ably at any point (though is typically triggered by a reauth, see @RTC8a@). The @connectionDetails@ in the @ProtocolMessage@ must override any stored details, see @RTN21@. The @Connection@ should emit an @UPDATE@ event with a @ChannelStateChange@ object, which should have both @previous@ and @current@ attributes set to @CONNECTED@, and the @reason@ attribute set to to the @error@ member of the @CONNECTED@ @ProtocolMessage@ (if any). (Note that @UPDATE@ should be the only event emitted: in particular, the library must not emit an @CONNECTED@ event if the client was already connected, see @RTL4h@). + + h3(#realtime-channels). Channels + +@@ -375,46 +402,54 @@ h3(#realtime-channels). Channels + + h3(#realtime-channel). Channel + +-* @(RTL1)@ As soon as a @Channel@ becomes attached, all incoming messages and presence messages are processed and emitted where applicable. @PRESENCE@ and @SYNC@ messages are passed to the @Presence@ object ensuring it maintains a map of current members on a channel in realtime +-* @(RTL2)@ EventEmitter and states: +-** @(RTL2a)@ Implements @EventEmitter@ and emits events for state changes @INITIALIZED@, @ATTACHING@, @ATTACHED@, @DETACHING@, @DETACHED@, @FAILED@ ++* @(RTL1)@ As soon as a @Channel@ becomes attached, all incoming messages and presence messages are processed and emitted where applicable. @PRESENCE@ and @SYNC@ messages are passed to the @Presence@ object ensuring it maintains a map of current members on a channel in realtime ++* @(RTL2)@ The @Channel@ implements @EventEmitter@ and emits @ChannelEvent@ events ++** @(RTL2a)@ It emits a @ChannelState@ event (one of @INITIALIZED@, @ATTACHING@, @ATTACHED@, @DETACHING@, @DETACHED@, @SUSPENDED@ and @FAILED@) for every channel state change ++** @(RTL2g)@ It can emit an @UPDATE@ event (this is the only @ChannelEvent@ which is not a @ChannelState@). This is used for changes to channel conditions for which the @ChannelState@ (e.g. @ATTACHED@) does not change. (The library must never emit a @ChannelState@ for a state equal to the previous state). + ** @(RTL2b)@ @Channel#state@ attribute is the current state of the channel +-** @(RTL2c)@ Additionally, an @ERROR@ event is emitted that contains an @ErrorInfo@ object with details on an error that has occurred for the @Channel@ ++** @(RTL2d)@ A @ChannelStateChange@ object is emitted as the first argument for every @ChannelEvent@ (including both @RTL2a@ state changes and @RTL2g@ @UPDATE@ events). It may optionally contain a @reason@ consisting of an @ErrorInfo@ object; any state change triggered by a @ProtocolMessage@ that contains an @error@ member should populate the @reason@ with that error in the corresponding state change event ++** @(RTL2f)@ When a channel @ATTACHED@ @ProtocolMessage@ is received, the @ProtocolMessage@ may contain a @RESUMED@ bit flag indicating that the channel has been resumed. The corresponding @ChannelStateChange@ (either @ATTACHED@ per @RTL2a@, or @UPDATE@ per @RTL12@) will contain a @resumed@ boolean attribute with value @true@ if the bit flag @RESUMED@ was included. When @resumed@ is @true@, this indicates that the channel attach resumed the channel state from an existing connection and there has been no loss of message continuity. In all other cases, @resumed@ is false. A test should exist to ensure that @resumed@ is always false when a channel first becomes @ATTACHED@, it is @true@ when the channel is @ATTACHED@ following a successful "connection recovery":#RTN16, and is @false@ when the channel is @ATTACHED@ following a failed "connection recovery":#RTN16 ++** @(RTL2h)@ Optionally, for backwards compatibility with 0.8 libraries, the @Channel@ @EventEmitter@ can provide an overloaded method that supports @on(ChannelState)@, but must issue a deprecation warning + * @(RTL3)@ Connection state change side effects: +-** @(RTL3a)@ If the connection state changes to @FAILED@ then an @ATTACHING@ or @ATTACHED@ channel state will transition to @FAILED@, set the @Channel#errorReason@ and emit the error event +-** @(RTL3b)@ If the connection state changes to @CLOSED@ or @SUSPENDED@ then an @ATTACHING@ or @ATTACHED@ channel state will transition to @DETACHED@ +-* @(RTL11)@ If a channel enters the @DETACHED@ or @FAILED@ state, then all messages that are still queued for send on that channel should be deleted from the queue triggering a failure for the publish or presence methods invoked for those messages ++** @(RTL3e)@ If the connection state enters the @DISCONNECTED@ state, it will have no effect on the channel states. ++** @(RTL3a)@ If the connection state enters the @FAILED@ state, then an @ATTACHING@ or @ATTACHED@ channel state will transition to @FAILED@ and set the @Channel#errorReason@ ++** @(RTL3b)@ If the connection state enters the @CLOSED@ state, then an @ATTACHING@ or @ATTACHED@ channel state will transition to @DETACHED@ ++** @(RTL3c)@ If the connection state enters the @SUSPENDED@ state, then an @ATTACHING@ or @ATTACHED@ channel state will transition to @SUSPENDED@ ++** @(RTL3d)@ If the connection state enters the @CONNECTED@ state, then a @SUSPENDED@ channel will initiate an attach operation and transition to @ATTACHING@. If the attach operation times out, the channel should return to the @SUSPENDED@ state (see "RTL4f":#RTL4f). ++* @(RTL11)@ If a channel enters the @DETACHED@, @SUSPENDED@ or @FAILED@ state, then all messages that are still queued for send on that channel should be deleted from the queue triggering a failure for the publish or presence methods invoked for those messages ++** @(RTL11a)@ For clarity, any messages awaiting an @ACK@ or @NACK@ are unaffected by channel state changes i.e. a channel that becomes detached following an explicit request to detach may still receive an @ACK@ or @NACK@ for messages published on that channel later + * @(RTL4)@ @Channel#attach@ function: + ** @(RTL4a)@ If already @ATTACHED@ nothing is done + ** @(RTL4h)@ If the channel is in a pending state @DETACHING@ or @ATTACHING@, do the attach operation after the completion of the pending request +-** @(RTL4g)@ If the channel is in the @FAILED@ state, the @attach@ request sets its @errorReason@ to @null@, and proceeds with a channel attach described in "RTL4b":#RTL4b, "RTL4h":#RTL4h and "RTL4c":#RTL4c ++** @(RTL4g)@ If the channel is in the @FAILED@ state, the @attach@ request sets its @errorReason@ to @null@, and proceeds with a channel attach described in "RTL4b":#RTL4b, "RTL4i":#RTL4i and "RTL4c":#RTL4c + ** @(RTL4b)@ If the connection state is @CLOSED@, @CLOSING@, @SUSPENDED@ or @FAILED@, the @attach@ request results in an error +-** @(RTL4h)@ If the connection state is @INITIALIZED@, @CONNECTING@ or @DISCONNECTED@, do the operation once the connection state is @CONNECTED@ +-** @(RTL4c)@ Otherwise an @ATTACH@ ProtocolMessage is sent to the server, the state changes to @ATTACHING@ and the channel becomes @ATTACHED@ when the confirmation @ATTACHED@ ProtocolMessage is received +-** @(RTL4f)@ Once an @ATTACH@ @ProtocolMessage@ is sent, if an @ATTACHED@ @ProtocolMessage@ is not received within the "default realtime request timeout":#defaults, the attach request should be treated as though it has failed and the channel will return to its previous state ++** @(RTL4i)@ If the connection state is @INITIALIZED@, @CONNECTING@ or @DISCONNECTED@, do the operation once the connection state is @CONNECTED@ ++** @(RTL4c)@ Otherwise an @ATTACH@ ProtocolMessage is sent to the server, the state transitions to @ATTACHING@ and the channel becomes @ATTACHED@ when the confirmation @ATTACHED@ ProtocolMessage is received ++** @(RTL4f)@ Once an @ATTACH@ @ProtocolMessage@ is sent, if an @ATTACHED@ @ProtocolMessage@ is not received within the "default realtime request timeout":#defaults, the attach request should be treated as though it has failed and the channel should transition to the @SUSPENDED@ state. The channel will then be subsequently automatically re-attached as described in "RTL13":#RTL13 + ** @(RTL4d)@ If the language permits, a callback can be provided that is called when the channel is attached successfully or the attach fails and the @ErrorInfo@ error is passed as an argument to the callback +-** @(RTL4e)@ If the user does not have sufficient permissions to attach to the channel, the channel state @FAILED@ is emitted with the error @ErrorInfo@. An error event is also emitted, and the @Channel#errorReason@ attribute of the @Channel@ is set to the error @ErrorInfo@ object ++** @(RTL4e)@ If the user does not have sufficient permissions to attach to the channel, the channel will transition to @FAILED@ and set the @Channel#errorReason@ + * @(RTL5)@ @Channel#detach@ function: + ** @(RTL5a)@ If the channel state is @INITIALIZED@ or @DETACHED@ nothing is done + ** @(RTL5i)@ If the channel is in a pending state @DETACHING@ or @ATTACHING@, do the detach operation after the completion of the pending request + ** @(RTL5b)@ If the channel state is @FAILED@, the @detach@ request results in an error ++** @(RTL5j)@ If the channel state is @SUSPENDED@, the @detach@ request transitions the channel immediately to the @DETACHED@ state + ** @(RTL5g)@ If the connection state is @CLOSING@ or @FAILED@, the @detach@ request results in an error + ** @(RTL5h)@ If the connection state is @INITIALIZED@, @CONNECTING@ or @DISCONNECTED@, do the detach operation once the connection state is @CONNECTED@ +-** @(RTL5d)@ Otherwise a @DETACH@ ProtocolMessage is sent to the server, the state changes to @DETACHING@ and the channel becomes @DETACHED@ when the confirmation @DETACHED@ ProtocolMessage is received ++** @(RTL5d)@ Otherwise a @DETACH@ ProtocolMessage is sent to the server, the state transitions to @DETACHING@ and the channel becomes @DETACHED@ when the confirmation @DETACHED@ ProtocolMessage is received + ** @(RTL5f)@ Once a @DETACH@ @ProtocolMessage@ is sent, if a @DETACHED@ @ProtocolMessage@ is not received within the "default realtime request timeout":#defaults, the detach request should be treated as though it has failed and the channel will return to its previous state + ** @(RTL5e)@ If the language permits, a callback can be provided that is called when the channel is detached successfully or the detach fails and the @ErrorInfo@ error is passed as an argument to the callback + * @(RTL6)@ @Channel#publish@ function: + ** @(RTL6a)@ Messages are encoded in the same way as the REST @Channel#publish@ method + ** @(RTL6b)@ An optional callback can be provided to the @#publish@ method that is called when the message is successfully delivered or upon failure with the appropriate @ErrorInfo@ error. A test should exist to publish lots of messages on a few connections to ensure all message success callbacks are called for all messages published + ** @(RTL6i)@ Expects either an array of @Message@ objects or a @name@ string and @data@ payload: +-** @(RTL6i1)@ When @name@ and @data@ is provided, a single @ProtocolMessage@ containing one @Message@ is published to Ably +-** @(RTL6i2)@ When an array of @Message@ objects is provided, a single @ProtocolMessage@ is used to publish all @Message@ objects in the array. However, a yet to be implemented feature should limit the total number of messages bundled in a single ProtocolMessage based on the default max message size +-** @(RTL6i3)@ Allows @name@ and or @data@ to be @null@. If any of the values are @null@, then key is not sent to Ably i.e. a payload with a @null@ value for @data@ would be sent as follows @{ "name": "click" }@ ++*** @(RTL6i1)@ When @name@ and @data@ is provided, a single @ProtocolMessage@ containing one @Message@ is published to Ably ++*** @(RTL6i2)@ When an array of @Message@ objects is provided, a single @ProtocolMessage@ is used to publish all @Message@ objects in the array. However, a yet to be implemented feature should limit the total number of messages bundled in a single ProtocolMessage based on the default max message size ++*** @(RTL6i3)@ Allows @name@ and or @data@ to be @null@. If any of the values are @null@, then key is not sent to Ably i.e. a payload with a @null@ value for @data@ would be sent as follows @{ "name": "click" }@ + ** @(RTL6c)@ Connection and channel state conditions: + *** @(RTL6c1)@ If the connection is @CONNECTED@ and the channel is @ATTACHED@ then the messages are published immediately +-*** @(RTL6c2)@ If the connection is @INITIALIZED@, @CONNECTING@ or @DISCONNECTED@ or the channel is @INITIALIZED@ or @ATTACHING@, and @ClientOptions#queueMessages@ has not been explicitly set to false, then the message will be queued and delivered as soon as the connection state becomes @CONNECTED@ and the channel is @ATTACHED@ +-*** @(RTL6c4)@ If the connection is @SUSPENDED@, @CLOSING@, @CLOSED@, or @FAILED@, or the channel is @DETACHING@, @DETACHED@ or @FAILED@, the operation will result in an error +-*** @(RTL6c3)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in or moves to the @DETACHED@ or @FAILED@ state before the operation succeeds, it will result in an error ++*** @(RTL6c2)@ If the connection is @INITIALIZED@, @CONNECTING@ or @DISCONNECTED@ or the channel is @INITIALIZED@, @ATTACHING@ or @ATTACHED@, and @ClientOptions#queueMessages@ has not been explicitly set to false, then the message will be queued and delivered as soon as the connection state enters the @CONNECTED@ state and the channel is @ATTACHED@ ++*** @(RTL6c4)@ If the connection is @SUSPENDED@, @CLOSING@, @CLOSED@, or @FAILED@, or the channel is @DETACHING@, @DETACHED@, @SUSPENDED@ or @FAILED@, the operation will result in an error ++*** @(RTL6c3)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in enters to the @DETACHED@ or @FAILED@ state before the operation succeeds, it will result in an error + ** @(RTL6d)@ Messages are delivered using a single @ProtocolMessage@ where possible by bundling in all messages for that channel into the @ProtocolMessage#messages@ array. However, a yet to be implemented feature should limit the total number of messages bundled per @ProtocolMessage@ based on the default max message size, and would reject the publish and indicate an error if any single message exceeds that limit + ** @(RTL6e)@ Unidentified clients using "Basic Auth":https://en.wikipedia.org/wiki/Basic_access_authentication (i.e. any @clientId@ is permitted as no @clientId@ specified): + *** @(RTL6e1)@ When a @Message@ with a @clientId@ value is published, Ably will accept and publish that message with the provided @clientId@. A test should assert that the @clientId@ of the published @Message@ is populated +@@ -425,14 +460,14 @@ h3(#realtime-channel). Channel + *** @(RTL6g2)@ When publishing a @Message@ with the @clientId@ attribute value set to the identified client's @clientId@, Ably will accept the message and publish it. A test should assert that the @clientId@ value is populated for the @Message@ when received + *** @(RTL6g3)@ When publishing a @Message@ with a different @clientId@ attribute value from the identified client's @clientId@, the client library should reject that publish operation immediately. The message should not be sent to Ably and it should result in an error, typically in the form of an error callback. The connection and channel must remain available for further operations + *** @(RTL6g4)@ When using Token Auth, unless a @clientId@ has been provided in @ClientOptions@ or inferred following authentication, the client library is unidentified and will not be constrained when publishing messages with any explicit @clientId@. If a @Message@ with a @clientId@ value is published before the @clientId@ is configured or inferred following authentication, the client library should not reject any explicit @clientId@ specified in a message. A test should instance a library without an explicit @clientId@ and an @authCallback@ that returns a @tokenDetails@ object with a @clientId@, then publish a message with the same @clientId@ before authentication, and ensure that the message is published following authentication and received back with the @clientId@ intact. A further test should follow the same sequence of events, but should instead use an incompatible @clientId@ in the message, expecting that the message is rejected by the Ably service and the message error should contain the server error message, and the connection and channel should remain available for further operations +-** @(RTL6h)@ Where the library language permits, the @Channel#publish(name, data)@ method should provide an optional argument that allows the @clientId@ value to be specified such as @Channel#publish('event', 'data', { clientId: 'John' })@ ++** @(RTL6h)@ Where the library language permits, the @Channel#publish(name, data)@ method should provide an optional argument that allows the @clientId@ value to be specified such as @Channel#publish('event', 'data', { clientId: 'John' })@, and/or the @extras@ field to be specified such as @Channel#publish('event', 'data', { extras: { push: { 'key': 'value' } })@ + ** @(RTL6f)@ @Message#connectionId@ should match the current @Connection#id@ for all published messages, a test should exist to ensure the @connectionId@ for received messages matches that of the publisher + * @(RTL7)@ @Channel#subscribe@ function: + ** @(RTL7a)@ Subscribe with no arguments subscribes a listener to all messages + ** @(RTL7b)@ Subscribe with a single name argument subscribes a listener to only messages whose @name@ member matches the string name +-** @(RTL7c)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in or moves to the @DETACHED@ or @FAILED@ state before the operation succeeds, it will result in the listener not being registered and an error being indicated, typically to the optional callback where the language permits +-** @(RTL7d)@ Messages delivered are automatically decoded based on the @encoding@ attribute; see REST @Channel@ encoding features. If there is an error decoding a message, the message is still delivered, but in addition to sending an error message to the logger, an @ErrorInfo@ error object is emitted as an error on the @Channel@. Tests should exist to publish and subscribe to encoded messages using the "AES 128":https://github.com/ably/ably-common/blob/master/test-resources/crypto-data-128.json and "AES 256":https://github.com/ably/ably-common/blob/master/test-resources/crypto-data-256.json fixture test data +-** @(RTL7e)@ If a message cannot be decoded or decrypted successfully, it should be delivered to the listener with the @encoding@ attribute set indicating the residual encoding state, and an error should be emitted on the channel ++** @(RTL7c)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. The optional callback, if provided, is called according to "@RTL4d@":#RTL4d based on the implicit attach operation. The listener will always be registered regardless of the implicit attach result ++** @(RTL7d)@ Messages delivered are automatically decoded based on the @encoding@ attribute; see REST @Channel@ encoding features. Tests should exist to publish and subscribe to encoded messages using the "AES 128":https://github.com/ably/ably-common/blob/master/test-resources/crypto-data-128.json and "AES 256":https://github.com/ably/ably-common/blob/master/test-resources/crypto-data-256.json fixture test data ++** @(RTL7e)@ If a message cannot be decoded or decrypted successfully, it should be delivered to the listener with the @encoding@ attribute set indicating the residual encoding state, and an error should be logged + ** @(RTL7f)@ A test should exist ensuring published messages are not echoed back to the subscriber when @echoMessages@ is set to false in the @Realtime@ library constructor + * @(RTL8)@ @Channel#unsubscribe@ function: + ** @(RTL8a)@ Unsubscribe with no arguments unsubscribes the provided listener to all messages if subscribed +@@ -441,20 +476,49 @@ h3(#realtime-channel). Channel + ** @(RTL9a)@ Returns the @Presence@ object for this channel + * @(RTL10)@ @Channel#history@ function: + ** @(RTL10a)@ Supports all the same params as REST @Channel#history@ +-** @(RTL10b)@ Additionally supports the param @untilAttach@, which if true, will only retrive messages prior to the moment that the channel was attached. This bound is specified by passing the querystring param @fromSerial@ with the serial number assigned to the channel in the @ATTACHED@ @ProtocolMessage@. If the @untilAttach@ param is specified when the channel is not attached, it results in an error ++** @(RTL10b)@ Additionally supports the param @untilAttach@, which if true, will only retrieve messages prior to the moment that the channel was attached or emitted an @UPDATE@ indicating loss of continuity. This bound is specified by passing the querystring param @fromSerial@ with the @Channel#properties.attachSerial@ assigned to the channel in the @ATTACHED@ @ProtocolMessage@ (see "RTL15a":#RTL15a). If the @untilAttach@ param is specified when the channel is not attached, it results in an error + ** @(RTL10c)@ Returns a @PaginatedResult@ page containing the first page of messages in the @PaginatedResult#items@ attribute returned from the history request + ** @(RTL10d)@ A test should exist that publishes messages from one client, and upon confirmation of message delivery, a history request should be made on another client to ensure all messages are available +-* @(RTL12)@ An attached channel may receive an additional @ATTACHED@ @ProtocolMessage@ from Ably at any point, however this is typically triggered following a transport being upgraded or resumed. If the @ATTACHED@ message contains an @error@, the error should be emitted on the channel, the @Channel#errorReason@ should be set, and the channel should remain attached. An @ATTACHED@ state change event should not be emitted by the @Channel@ if the @Channel@ is already @ATTACHED@ (i.e. no state change has occurred) ++* @(RTL12)@ An attached channel may receive an additional @ATTACHED@ @ProtocolMessage@ from Ably at any point. (This is typically triggered following a transport being upgraded or resumed to indicate a partial loss of message continuity on that channel, in which case the @ProtocolMessage@ will have a @resumed@ flag set to false). If and only if the @resumed@ flag is false, this should result in the channel emitting an @UPDATE@ event with a @ChannelStateChange@ object. The @ChannelStateChange@ object should have both @previous@ and @current@ attributes set to @attached@, the @reason@ attribute set to to the @error@ member of the @ATTACHED@ @ProtocolMessage@ (if any), and the @resumed@ attribute set per the @RESUMED@ bitflag of the @ATTACHED@ @ProtocolMessage@. (Note that @UPDATE@ should be the only event emitted: in particular, the library must not emit an @ATTACHED@ event if the channel was already attached, see @RTL2g@). ++* @(RTL15)@ @Channel#properties@ attribute is a @ChannelProperties@ object representing properties of the channel state. @properties@ is a publicly accessible member of the channel, but it is an experimental and unstable API. It has the following attributes: ++** @(RTL15a)@ @attachSerial@ is @null@ when the channel is instanced, and is updated with the @channelSerial@ from each @ATTACHED@ @ProtocolMessage@ received from Ably with a matching @channel@ attribute. The @attachSerial@ value is used for @untilAttach@ queries, see "RTL10b":#RTL10b and "RTP12b":#RTP12b. ++* @(RTL13)@ If the channel receives a server initiated @DETACHED@ message when it is in the @ATTACHING@, @ATTACHED@ or @SUSPENDED@ state (i.e. the client has not explicitly requested a detach putting the channel into the @DETACHING@ state), then the following applies: ++** @(RTL13a)@ If the channel is in the @ATTACHED@ or @SUSPENDED@ states, an attempt to reattach the channel should be made immediately by sending a new @ATTACH@ message and the channel should transition to the @ATTACHING@ state with the error emitted in the @ChannelStateChange@ event. ++** @(RTL13b)@ If the attempt to re-attach fails, or if the channel was already in the @ATTACHING@ state, the channel will transition to the @SUSPENDED@ state and the error will be emitted in the @ChannelStateChange@ event. An attempt to re-attach the channel automatically will then be made after the period defined in @ClientOptions#channelRetryTimeout@. When re-attaching the channel, the channel will transition to the @ATTACHING@ state. If that request to attach fails i.e. it times out or a @DETACHED@ message is received, then the process described here in @RTL13b@ will be repeated, indefinitely ++** @(RTL13c)@ If the connection is no longer @CONNECTED@, then the automatic attempts to re-attach the channel described in "RTL13b":#RTL13b must be cancelled as any implicit channel state changes subsequently will be covered by "RTL3":#RTL3 ++* @(RTL14)@ If an @ERROR ProtocolMessage@ is received for this channel (the channel attribute matches this channel's name), then the channel should immediately transition to the FAILED state, and the @Channel.errorReason@ should be set + + h3(#realtime-presence). Presence + +-* @(RTP1)@ When a channel @ATTACHED@ @ProtocolMessage@ is received, the @ProtocolMessage@ may contain a bit flag with value 1 indicating that there are currently members present on the channel. If members are present, subsequent @ProtocolMessage SYNC@ messages will be delivered with presence members (messages) until the @SYNC@ operation is complete. If there is no flag or the right most bit is zero, then the presence map should be considered in sync immediately as there are no members present on the channel at the time of attach +-* @(RTP2)@ A "PresenceMap":https://github.com/ably/ably-java/blob/master/src/io/ably/realtime/Presence.java#L384-L529 should be used to maintain a list of members present on a channel. As there are no guarantees that during the @SYNC@ phase presence events will arrive in order i.e. a leave event for a member can arrive before that member is later registered as as present as part of the initial @SYNC@ operation. As such, until the @SYNC@ operation is complete, timestamps must be recorded for all members to ensure the most recent present state is used, see the "Java implementation":https://github.com/ably/ably-java/blob/master/src/io/ably/realtime/Presence.java#L418-L431. Once a @SYNC@ event is complete, the members that are now considered @ABSENT@ can be removed from the map, see the "Java implementation":https://github.com/ably/ably-java/blob/master/src/io/ably/realtime/Presence.java#L504-L509 +-* @(RTP3)@ If a @SYNC@ operation is underway but not yet complete, and the transport is disconnected unexpectedly, then if the connection is resumed successfully, it is the responsibility of the client library to complete the @SYNC@ operation. The client library requests a @SYNC@ resume by sending a @SYNC@ @ProtocolMessage@ with the last received sync serial number. See the "Ruby implementation":https://github.com/ably/ably-ruby/blob/7b18a20/lib/ably/realtime/presence/members_map.rb#L169-L176 and the "Ruby test":https://github.com/ably/ably-ruby/blob/7b18a20/spec/acceptance/realtime/presence_spec.rb#L1338-L1357 ++* @(RTP1)@ When a channel @ATTACHED@ @ProtocolMessage@ is received, the @ProtocolMessage@ may contain a @HAS_PRESENCE@ bit flag indicating that there are currently members present on the channel, see "TR3":#TR3 . If the flag is 1, the server will shortly perform a @SYNC@ operation as described in "RTP18":#RTP18 . If that flag is 0 or there is no @flags@ field, the presence map should be considered in sync immediately with no members present on the channel ++* @(RTP2)@ A @PresenceMap@ should be used to maintain a list of members present on a channel. Broadly, this is is a map of "memberKeys":#TP3h to presence messages, all with @PRESENT@ actions (during a sync there may also be ones with an @ABSENT@ action, see "RTP2f":#RTP2f). ++** @(RTP2a)@ All incoming presence messages must be compared for newness with the matching member already in the @PresenceMap@, if one exists, where "matching" means they share the same @memberKey@ (or equivalently, they share both @connectionId@ and @clientId@) ++** @(RTP2b)@ To compare for newness: ++** @(RTP2b1)@ If either presence message has a @connectionId@ which is not an initial substring of its @id@, compare them by @timestamp@ numerically. (This will be the case when one of them is a 'synthesized leave' event sent by realtime to indicate a connection disconnected unexpectedly 15s ago. Such messages will have an @id@ that does not correspond to its @connectionId@, as it wasn't actually published by that connection) ++** @(RTP2b2)@ Else split the @id@ of both presence messages (which will be of the form @connid:msgSerial:index@, e.g. @aaaaaa:0:0@) on the separator @:@, and parse the latter two as integers. Compare them first by @msgSerial@ numerically, then (if @msgSerial@ is equal) by @index@ numerically, larger being newer in both cases ++** @(RTP2c)@ As there are no guarantees that during a @SYNC@ operation presence events will arrive in order, all presence messages from a @SYNC@ must also be compared for newness in the same way as they would from a @PRESENCE@ ++** @(RTP2d)@ When a presence message with an action of @ENTER@, @UPDATE@, or @PRESENT@ arrives, it should be added to the presence map with the action set to @PRESENT@ ++** @(RTP2e)@ If a @SYNC@ is not in progress, then when a presence message with an action of @LEAVE@ arrives, that @memberKey@ should be deleted from the presence map, if present ++** @(RTP2f)@ If a @SYNC@ is in progress, then when a presence message with an action of @LEAVE@ arrives, it should be stored in the presence map with the action set to @ABSENT@. When the @SYNC@ completes, any @ABSENT@ members should be deleted from the presence map. (This is because in a @SYNC@, we might receive a @LEAVE@ before the corresponding @ENTER@). ++** @(RTP2g)@ Any incoming presence message that passes the newness check should be emitted on the @Presence@ object, with an event name set to its original action. Note: this action may not be the same one that it will have when stored in the presence map. For example: an incoming presence message with an @ENTER@ action will be emitted as an @enter@ event, and the emitted presence message will have its action set to @ENTER@. However, it will be stored in the presence map with a @PRESENT@ action. ++* @(RTP3)@ If a @SYNC@ operation is underway but not yet complete, and the transport is disconnected unexpectedly, then if the connection is resumed successfully, it is the responsibility of the client library to complete the @SYNC@ operation. The client library requests a @SYNC@ resume by sending a @SYNC@ @ProtocolMessage@ with the @channelSerial@ set to the same as the @channelSerial@ of the most recently received @SYNC@. ++* @(RTP18)@ The realtime system reserves the right to initiate a sync of the presence members at any point once a channel is attached. A server initiated sync provides Ably with a means to send a complete list of members present on the channel at any point ++** @(RTP18a)@ The client library determines that a new sync has started whenever a @SYNC@ @ProtocolMessage@ is received with a @channel@ attribute and a new sync sequence identifier in the @channelSerial@ attribute. The @channelSerial@ is used as the sync cursor and is a two-part identifier @:@. If a new sequence identifier is sent from Ably, then the client library must consider that to be the start of a new sync sequence and any previous in-flight sync should be discarded ++** @(RTP18b)@ The the sync operation for that sequence identifier has completed once the cursor is empty; that is, when the @channelSerial@ looks like @:@ ++** @(RTP18c)@ a @SYNC@ may also be sent with no @channelSerial@ attribute. In this case, the sync data is entirely contained within that @ProtocolMessage@ ++* @(RTP19)@ If the @PresenceMap@ has existing members when a @SYNC@ is started, the client library must ensure that members no longer present on the channel are removed from the local @PresenceMap@ once the sync is complete. In order to do this, the client library must keep track of any members that have not been added or updated in the @PresenceMap@ during the sync process. Note that a member can be added or updated when received in a @SYNC@ message or when received in a @PRESENCE@ message during the sync process. Once the sync is complete, the members in the @PresenceMap@ that have not been added or updated should be removed from the @PresenceMap@ and a @LEAVE@ event should be published for each. The @PresenceMessage@ published should contain the original attributes of the presence member with the @action@ set to @LEAVE@, @PresenceMessage#id@ set to @null@, and the @timestamp@ set to the current time. This behavior should be tested as follows: @ENTER@ presence on a channel, wait for @SYNC@ to complete, inject a member directly into the local @PresenceMap@ so that it only exists locally and not on the server, send a @SYNC@ message with the @channel@ attribute populated with the current channel which will trigger a server initiated @SYNC@. A @LEAVE@ event should then be published for the injected member, and checking the @PresenceMap@ should reveal that the member was removed and the valid member entered for this connection is still present ++** @(RTP19a)@ If the @PresenceMap@ has existing members when an @ATTACHED@ message is received without a @HAS_PRESENCE@ flag, the client library should emit a @LEAVE@ event for each existing member, and the @PresenceMessage@ published should contain the original attributes of the presence member with the @action@ set to @LEAVE@, @PresenceMessage#id@ set to @null@, and the @timestamp@ set to the current time. Once complete, all members in the @PresenceMap@ should be removed as there are no members present on the channel ++* @(RTP17)@ The Presence object is also responsible for keeping a separate copy of an object logically equivalent to the @PresenceMap@ containing only members that match the current @connectionId@. Any @ENTER@, @PRESENT@, @UPDATE@ or @LEAVE@ event that matches the current @connectionId@ should be applied to this object in the same way it is done for the @PresenceMap@. This object should be private and is used to maintain a list of members that need to be automatically re-entered by the @Presence@ object when a @Channel@ becomes @ATTACHED@ with some or all continuity lost. ++** @(RTP17a)@ All members belonging to the current connection are published as a @PresenceMessage@ on the @Channel@ by the server irrespective of whether the client has permission to subscribe or the @Channel@ is configured to publish presence events. A test should exist that attaches to a @Channel@ with a @presence@ capability and without a @subscribe@ capability. It should then enter the @Channel@ and ensure that the member entered from the current connection is present in the internal and public presence set available via "@Presence#get@":#RTP11 + * @(RTP4)@ Ensure a test exists that enters 250 members using @Presence#enterClient@ on a single connection, and checks for @PRESENT@ events to be emitted on another connection for each member, and once sync is complete, all 250 members should be present in a @Presence#get@ request + * @(RTP5)@ Channel state change side effects: +-** @(RTP5a)@ If the channel enters the @DETACHED@ or @FAILED@ state then all queued presence messages will fail immediately, and the presence map is cleared +-** @(RTP5b)@ If a channel enters the @ATTACHED@ state then all queued presence messages will be sent immediately and a presence @SYNC@ will be initiated implicitly ++** @(RTP5a)@ If the channel enters the @DETACHED@ or @FAILED@ state then all queued presence messages will fail immediately, and the @PresenceMap@ and "internal PresenceMap (see RTP17)":#RTP17 is cleared. The latter ensures members are not automatically re-entered if the @Channel@ later becomes attached. Since channels in the @DETACHED@ and @FAILED@ states will not receive any presence updates from Ably, presence events (specifically @LEAVE@) should not be emitted when the @PresenceMap@ is cleared as each presence member's state is unknown ++** @(RTP5f)@ If the channel enters the @SUSPENDED@ state then all queued presence messages will fail immediately, and the @PresenceMap@ is maintained. This ensures that if the channel later becomes @ATTACHED@, it will only publish presence events for the changes in the @PresenceMap@ that have occurred whilst the client was disconnected. A test should exist for a channel that is in the @SUSPENDED@ state containing presence members to transition to the @ATTACHED@ state, and following the @SYNC@ process after attaching, any members present before and after the sync should not emit presence events, all other changes should be reflected in the @PresenceMap@ and should emit presence events on the channel ++** @(RTP5b)@ If a channel enters the @ATTACHED@ state then all queued presence messages will be sent immediately and a presence @SYNC@ may be initiated by the Ably service or the Ably service may indicate there is no @SYNC@ necessary ++** @(RTP5c)@ In addition, when a channel becomes @ATTACHED@, the following must happen in regards to @Presence@: ++*** @(RTP5c1)@ If the "@resumed@ flag":#TH4 is true and no @SYNC@ is initiated as part of the attach, do nothing as there is no loss of continuity on the channel and no change to presence. The @PresenceMap@ is not affected and no members need to be re-entered ++*** @(RTP5c2)@ If either a @SYNC@ is initiated as part of the attach and the @SYNC@ is complete, or if the @resumed@ flag is false and a @SYNC@ is not expected, all members not present in the @PresenceMap@ but present in the "internal @PresenceMap@":#RTP17 must be re-entered automatically by the client using the @clientId@ and @data@ attributes from each. The members re-entered automatically must be removed from the "internal @PresenceMap@":#RTP17 ensuring that members present on the channel are constructed from presence events sent from Ably since the channel became @ATTACHED@ ++*** @(RTP5c3)@ If any of the automatic @ENTER@ presence messages published in "RTP5c2":#RTP5c2 fail, then an @UPDATE@ event should be emitted on the channel with @resumed@ set to true and @reason@ set to an @ErrorInfo@ object with error @code@ value @91004@ and the error @message@ string containing the message received from Ably (if applicable), the @code@ received from Ably (if applicable) and the explicit or implicit @client_id@ of the @PresenceMessage@ + * @(RTP16)@ Connection state conditions: + ** @(RTP16a)@ If the connection is @CONNECTED@ and the channel is @ATTACHED@ then all presence messages are published immediately + ** @(RTP16b)@ If the connection is @INITIALIZED@, @CONNECTING@ or @DISCONNECTED@ or the channel is @ATTACHING@, and @ClientOptions#queueMessages@ has not been explicitly set to false, then all presence messages will be queued and delivered as soon as the connection state returns to @CONNECTED@ and the channel is @ATTACHED@ +@@ -462,7 +526,7 @@ h3(#realtime-presence). Presence + * @(RTP6)@ @Presence#subscribe@ function: + ** @(RTP6a)@ Subscribe with no arguments subscribes a listener to all presence messages + ** @(RTP6b)@ Subscribe with a single action argument - such as @ENTER@, @LEAVE@, @UPDATE@ or @PRESENT@ - subscribes a listener to receive only presence messages with that action +-** @(RTP6c)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in or moves to the @FAILED@ state before the operation succeeds, it will result in the listener not being registered and an error being indicated, typically to the optional callback where the language permits ++** @(RTP6c)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. The optional callback, if provided, is called according to "@RTL4d@":#RTL4d based on the implicit attach operation. The listener will always be registered regardless of the implicit attach result + * @(RTP7)@ @Presence#unsubscribe@ function: + ** @(RTP7a)@ Unsubscribe with no arguments unsubscribes the listener if previously subscribed with an action-specific subscription + ** @(RTP7b)@ Unsubscribe with a single action argument unsubscribes the provided listener to all presence messages for that action +@@ -486,21 +550,22 @@ h3(#realtime-presence). Presence + ** @(RTP10a)@ Leaves this client from the channel and the data will be updated with the value provided. If the language permits the data argument to be omitted, then the previously set data value will be sent as a convenience + ** @(RTP10b)@ Optionally a callback can be provided that is called for both success or failure to leave + ** @(RTP10c)@ A @PRESENCE ProtocolMessage@ with a @PresenceMessage@ with the action @LEAVE@ is sent to the Ably service. The @clientId@ attribute of the @PresenceMessage@ must not be present. Leaving without an explicit @PresenceMessage#clientId@, implicitly uses the @clientId@ for the current connection +-** @(RTP10d)@ If the client is not currently @ENTERED@, it will result in an error ++** @(RTP10d)@ If the client is not currently @ENTERED@, Ably will respond with an @ACK@ and the request will succeed (i.e. the outcome of asking to @LEAVE@ when not present vs being present is the same) + ** @(RTP10e)@ In all other ways, this method is identical to @Presence#enter@ and should have matching tests + * @(RTP11)@ @Presence#get@ function: + ** @(RTP11a)@ Returns the list of current members on the channel in a callback. By default, will wait for the @SYNC@ to be completed, see "RTP11c1":#RTP11c1 +-** @(RTP11b)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in or moves to the @DETACHED@ or @FAILED@ state before the operation succeeds, it will result in an error ++** @(RTP11b)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in or enters the @DETACHED@ or @FAILED@ state before the operation succeeds, it will result in an error ++** @(RTP11d)@ If the @Channel@ is in the @SUSPENDED@ state then the @get@ function will by default, or if @waitForSync@ is set to @true@, result in an error with @code@ @91005@ and a @message@ stating that the presence state is out of sync due to the channel being in a @SUSPENDED@ state. If however the @get@ function is called with @waitForSync@ set to @false@, then it immediately returns the members currently stored in the @PresenceMap@ giving developers access to the members that were present at the time the channel became @SUSPENDED@ + ** @(RTP11c)@ An optional set of params can be provided: + *** @(RTP11c1)@ @waitForSync@ (default @true@). When @true@, method will wait until @SYNC@ is complete before returning a list of members. When @false@, known set of presence members is returned immediately, which may be incomplete if the @SYNC@ is not finished + *** @(RTP11c2)@ @clientId@ filters members by the provided @clientId@ + *** @(RTP11c3)@ @connectionId@ filters members by the provided @connectionId@ + * @(RTP12)@ @Presence#history@ function: + ** @(RTP12a)@ Supports all the same params as REST @Presence#history@ +-** @(RTP12b)@ Additionally supports the param @untilAttach@, which if true, will only retrive messages up to the moment that the channel was attached. This bound is specified by passing the querystring param @fromSerial@ with the serial number assigned to the channel in the @ATTACHED@ @ProtocolMessage@. If the @untilAttach@ param is specified when the channel is not attached, it will result in an error ++** @(RTP12b)@ Additionally supports the param @untilAttach@, which if true, will only retrieve messages prior to the moment that the channel was attached or emitted an @UPDATE@ indicating loss of continuity. This bound is specified by passing the querystring param @fromSerial@ with the @Channel#properties.attachSerial@ assigned to the channel in the @ATTACHED@ @ProtocolMessage@ (see "RTL15a":#RTL15a). If the @untilAttach@ param is specified when the channel is not attached, it will result in an error + ** @(RTP12c)@ Returns a @PaginatedResult@ page containing the first page of messages in the @PaginatedResult#items@ attribute returned from the history request + ** @(RTP12d)@ A test should exist that registers presence with a few clients, and upon confirmation of entering the channel for all clients, a presence history request should be made using another client to ensure all presence events are available +-* @(RTP13)@ @Presence#syncComplete@ returns true if the initial @SYNC@ operation has completed for the members present on the channel ++* @(RTP13)@ @Presence#syncComplete@ attribute is @true@ if the initial @SYNC@ operation has completed for the members present on the channel + * @(RTP14)@ @Presence#enterClient@ function: + ** @(RTP14a)@ Enters into presence on a channel on behalf of another @clientId@. This allows a single client with suitable permissions to register presence on behalf of any number of clients using a single connection + ** @(RTP14b)@ Optionally a callback can be provided that is called for both success or failure to enter +@@ -511,7 +576,7 @@ h3(#realtime-presence). Presence + ** @(RTP15b)@ Tests should use @enterClient@, @updateClient@ and @leaveClient@ for many members from one @Realtime@ client and check that the operations are reflected in the presence map and the expected events are emitted on a separate client + ** @(RTP15c)@ Tests should also ensure that using these methods has no side effects on a client that has entered normally using @Presence#enter@ + ** @(RTP15d)@ A callback can be provided that will be called upon success or failure +-** @(RTP15e)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in or moves to the @DETACHED@ or @FAILED@ state before the operation succeeds, it will result in an error ++** @(RTP15e)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in or enters the @DETACHED@ or @FAILED@ state before the operation succeeds, it will result in an error + ** @(RTP15f)@ If the client is identified and has a valid @clientId@, and the @clientId@ argument does not match the client's @clientId@, then it should indicate an error. The connection and channel remain available for further operations + + h3(#eventemitter). EventEmitter mixin / interface +@@ -519,7 +584,7 @@ h3(#eventemitter). EventEmitter mixin / interface + * @(RTE1)@ @EventEmitter@ is a generic interface for event registration and delivery used in a number of the types in the Realtime client library. For example, the @Connection@ object emits events for connection state using the @EventEmitter@ pattern + * @(RTE2)@ Where objects provide @subscribe@ or @unsubscribe@ methods, they should follow the specification for the @EventEmitter#on@ and @EventEmitter#off@ methods respectively + * @(RTE3)@ @EventEmitter#on@ registers the provided listener for either all events when no @event@ argument is provided, or for only a single named event when an @event@ argument is provided. If @on@ is called more than once with the same listener and @event@, the listener is added multiple times to its listener registry. Therefore, as an example, assuming the same listener is registered twice using @on@, and an event is emitted once, the listener would be invoked twice +-* @(RTE4)@ @EventEmitter#once@ registers the provided listener for either the first event that is emitted when no @event@ argument is provided, or for only the first occurence of a single named event when an @event@ argument is provided. If @once@ is called more than once with the same listener, the listener is added multiple times to its listener registry. Therefore, as an example, assuming the same listener is registered twice using @once@, and an event is emitted once, the listener would be invoked twice. However, all subsequent events emitted would not invoke the listener as @once@ ensures that each registration is only invoked once ++* @(RTE4)@ @EventEmitter#once@ registers the provided listener for either the first event that is emitted when no @event@ argument is provided, or for only the first occurrence of a single named event when an @event@ argument is provided. If @once@ is called more than once with the same listener, the listener is added multiple times to its listener registry. Therefore, as an example, assuming the same listener is registered twice using @once@, and an event is emitted once, the listener would be invoked twice. However, all subsequent events emitted would not invoke the listener as @once@ ensures that each registration is only invoked once + * @(RTE5)@ @EventEmitter#off@ deregisters a listener. If called with a specific event and a listener, it removes all registrations that match both the given listener and the given event; if called only with a listener, it removes all registrations matching the given listener, regardless of whether they are associated with an event or not; if called with no arguments, it removes all registrations, for all events and listeners + * @(RTE6)@ @EventEmitter#emit@ emits an event, calling registered listeners with the given event name and any other given arguments. If an exception is raised in any of the listeners, the exception is caught by the @EventEmitter@ and the exception is logged to the Ably logger. Tests must exist to ensure exceptions raised in client code do not propagate and inhibit other event processing within the client library + +@@ -706,6 +771,7 @@ h3(#channel-states-operations). @RealtimeChannel.state@ effects on channel opera + Initialized + Attaching + Attached ++ Suspended + Detaching + Detached + Failed +@@ -720,6 +786,8 @@ h3(#channel-states-operations). @RealtimeChannel.state@ effects on channel opera + "RTL4h":#RTL4h + + "RTL4a":#RTL4a ++ ++ "RTL4c":#RTL4c + + "RTL4h":#RTL4h + +@@ -738,6 +806,8 @@ h3(#channel-states-operations). @RealtimeChannel.state@ effects on channel opera + "RTL5i":#RTL5i + + "RTL5d":#RTL5d ++ ++ "RTL5j":#RTL5j + + "RTL5i":#RTL5i + +@@ -756,6 +826,8 @@ h3(#channel-states-operations). @RealtimeChannel.state@ effects on channel opera + "RTL6c2":#RTL6c2 + + "RTL6c1":#RTL6c1 ++ ++ "RTL6c4":#RTL6c4 + + "RTL6c4":#RTL6c4 + +@@ -774,6 +846,8 @@ h3(#channel-states-operations). @RealtimeChannel.state@ effects on channel opera + "RTP16b":#RTP16b + + "RTP16a":#RTP16a ++ ++ "RTP16c":#RTP16c + + "RTP16c":#RTP16c + +@@ -793,45 +867,49 @@ h4. Message + + * @(TM1)@ A @Message@ represents an individual message to be sent or received via the Ably Realtime service. See the "Ruby Message documentation":http://www.rubydoc.info/gems/ably/Ably/Models/Message, but bear in mind the attributes following underscore naming in Ruby + * @(TM2)@ Attributes available in a @Message@, see the "Ruby Message documentation":http://www.rubydoc.info/gems/ably/Ably/Models/Message for an explanation of each attribute: +-** @(TM2a)@ @id@ string - unique ID for this message ++** @(TM2a)@ @id@ string - unique ID for this message. If a message received from Ably does not contain an @id@, it should be set to @protocolMsgId:index@, where @protocolMsgId@ is the id of the @ProtocolMessage@ encapsulating it, and @index@ is the index of the message inside the @messages@ array of the @ProtocolMessage@ + ** @(TM2b)@ @clientId@ string +-** @(TM2c)@ @connectionId@ string ++** @(TM2c)@ @connectionId@ string. If a message received from Ably does not contain a @connectionId@, it should be set to the @connectionId@ of the encapsulating @ProtocolMessage@ ++** @(TM2h)@ @connectionKey@ string (note this is only ever populated by a publishing client when "publishing on behalf of another client":/rest/channels-messages#publish-on-behalf, the @connectionKey@ will never be populated for messages received. A simple test for this attribute over REST is to populate this with an invalid @connectionKey@ when publishing and expecting a suitable error) + ** @(TM2g)@ @name@ string + ** @(TM2d)@ @data@ string, buffer or JSON-encodable object or array + ** @(TM2e)@ @encoding@ string +-** @(TM2f)@ @timestamp@ time in milliseconds since epoch ++** @(TM2i)@ @extras@ JSON-encodable object, used to contain any arbitrary key value pairs which may also contain other primitive JSON types, JSON-encodable objects or JSON-encodable arrays. The extras field is provided to contain message metadata and/or ancillary payloads in support of specific functionality, e.g. push. Each of these supported extensions is documented separately; for 1.0 the only supported extension is @push@, via the @extras.push@ member. The processing of any other members is undefined ++** @(TM2f)@ @timestamp@ time in milliseconds since epoch. If a message received from Ably does not contain a @timestamp@, it should be set to the @timestamp@ of the encapsulating @ProtocolMessage@ ++* @(TM3)@ @fromEncoded@ and @fromEncodedArray@ are alternative constructors that take an (already deserialized) @Message@-like object (or array of such objects), and optionally a @channelOptions@, and return a @Message@ (or array of such @Messages@) that's decoded and decrypted as specified in @RSL6@, using the cipher in the @channelOptions@ if the message is encrypted, with any residual transforms (ones that the library cannot decode or decrypt) left in the @encoding@ property per @RSL6b@. This is intended for users receiving messages other than from a REST or Realtime channel (for example, from a queue), to avoid them having to parse the @encoding@ string themselves. + + h4. PresenceMessage + + * @(TP1)@ A @PresenceMessage@ represents an individual presence message to be sent or received via the Ably Realtime service. See the "Ruby PresenceMessage documentation":http://www.rubydoc.info/gems/ably/Ably/Models/PresenceMessage, but bear in mind the attributes following underscore naming in Ruby + * @(TP2)@ @PresenceMessage@ @Action@ enum has the following values in order from zero: @ABSENT@, @PRESENT@, @ENTER@, @LEAVE@, @UPDATE@ + * @(TP3)@ Attributes available in a @PresenceMessage@, see the "Ruby PresenceMessage documentation":http://www.rubydoc.info/gems/ably/Ably/Models/PresenceMessage for an explanation of each attribute: +-** @(TP3a)@ @id@ string - unique ID for this message ++** @(TP3a)@ @id@ string - unique ID for this message. If a presence message received from Ably does not contain an @id@, it should be set to @protocolMsgId:index@, where @protocolMsgId@ is the id of the @ProtocolMessage@ encapsulating it, and @index@ is the index of the message inside the @presence@ array of the @ProtocolMessage@ + ** @(TP3b)@ @action@ enum + ** @(TP3c)@ @clientId@ string +-** @(TP3d)@ @connectionId@ string ++** @(TP3d)@ @connectionId@ string. If a presence message received from Ably does not contain a @connectionId@, it should be set to the @connectionId@ of the encapsulating @ProtocolMessage@ + ** @(TP3e)@ @data@ string, buffer or JSON-encodable object or array + ** @(TP3f)@ @encoding@ string +-** @(TP3g)@ @timestamp@ time in milliseconds since epoch ++** @(TP3g)@ @timestamp@ time in milliseconds since epoch. If a presence message received from Ably does not contain a @timestamp@, it should be set to the @timestamp@ of the encapsulating @ProtocolMessage@ + ** @(TP3h)@ @memberKey@ string function that combines the @connectionId@ and @clientId@ ensuring multiple connected clients with the same clientId are uniquely identifiable ++* @(TP4)@ @fromEncoded@ and @fromEncodedArray@ are alternative constructors that take an (already deserialized) @PresenceMessage@-like object (or array of such objects), and optionally a @channelOptions@, and return a @PresenceMessage@ (or array of such @PresenceMessages@) that's decoded and decrypted as specified in @RSL6@, using the cipher in the @channelOptions@ if the message is encrypted, with any residual transforms (ones that the library cannot decode or decrypt) left in the @encoding@ property per @RSL6b@. This is intended for users receiving messages other than from a REST or Realtime channel (for example, from a queue), to avoid them having to parse the @encoding@ string themselves. + + h4. ProtocolMessage + + * @(TR1)@ A @ProtocolMessage@ represents the type used to send and receive messages over the Realtime protocol. A ProtocolMessage always relates either to the connection or to a single channel only, but can contain multiple individual Messages or PresenceMessages. See the "Ruby ProtocolMessage documentation":http://www.rubydoc.info/gems/ably/Ably/Models/ProtocolMessage, but bear in mind the attributes following underscore naming in Ruby +-* @(TR2)@ @ProtocolMessage@ @Action@ enum has the following values in order from zero: @HEARTBEAT@, @ACK@, @NACK@, @CONNECT@, @CONNECTED@, @DISCONNECT@, @DISCONNECTED@, @CLOSE@, @CLOSED@, @ERROR@, @ATTACH@, @ATTACHED@, @DETACH@, @DETACHED@, @PRESENCE@, @MESSAGE@, @SYNC@ +-* @(TR3)@ @ProtocolMessage@ @Flag@ enum has the following values in order from zero: @HAS_PRESENCE@, @HAS_BACKLOG@ ++* @(TR2)@ @ProtocolMessage@ @Action@ enum has the following values in order from zero: @HEARTBEAT@, @ACK@, @NACK@, @CONNECT@, @CONNECTED@, @DISCONNECT@, @DISCONNECTED@, @CLOSE@, @CLOSED@, @ERROR@, @ATTACH@, @ATTACHED@, @DETACH@, @DETACHED@, @PRESENCE@, @MESSAGE@, @SYNC@, @AUTH@ ++* @(TR3)@ @ProtocolMessage@ @Flag@ enum has the following values in order from zero: @HAS_PRESENCE@, @HAS_BACKLOG@ and @RESUMED@ + * @(TR4)@ Attributes available in a @ProtocolMessage@, see the "Ruby ProtocolMessage documentation":http://www.rubydoc.info/gems/ably/Ably/Models/ProtocolMessage for an explanation of each attribute: + ** @(TR4a)@ @action@ enum +-** @(TR4n)@ @id@ string ++** @(TR4n)@ @id@ string, which will generally be of the form @connectionId:msgSerial@ ++** @(TR4p)@ @auth@ AuthDetails object used for auth, see "RTC8":#RTC8 + ** @(TR4b)@ @channel@ string + ** @(TR4c)@ @channelSerial@ string + ** @(TR4d)@ @connectionId@ string +-** @(TR4e)@ @connectionKey@ string. Note that this field is soon to be deprecated; when @ConnectionDetails#connectionKey@ is present, it should be considered the definitive @connectionKey@ for the current connection + ** @(TR4f)@ @connectionSerial@ long + ** @(TR4o)@ @connectionDetails@ @ConnectionDetails@ object - provides details on the constraints or defaults for the connection such as max message size, client ID or connection state TTL + ** @(TR4g)@ @count@ integer + ** @(TR4h)@ @error@ @ErrorInfo@ object +-** @(TR4i)@ @flags@ integer ++** @(TR4i)@ @flags@ integer. Contains one or more of the following bit flags: @HAS_PRESENCE: 1@, @HAS_BACKLOG: 2@, @RESUMED: 4@ + ** @(TR4j)@ @msgSerial@ long + ** @(TR4k)@ @messages@ Array of @Message@ objects + ** @(TR4l)@ @presence@ Array of @PresenceMessage@ objects +@@ -847,6 +925,17 @@ h4. PaginatedResult + * @(TG6)@ @PaginatedResult#hasNext@ function returns @true@ if there are further pages + * @(TG7)@ @PaginatedResult#isLast@ function returns @true@ if this page is the last page i.e. @!hasNext@ + ++h4. HttpPaginatedResponse // RSC19b ++ ++* @(HP1)@ A @HttpPaginatedResponse@ is a type that represents the response from an HTTP request containing an empty or JSON-encodable object response. "Paginated queries":/rest-api/#pagination are supported ++* @(HP2)@ @HttpPaginatedResponse@ inherits from @PaginatedResult@ and overrides @next@ and @first@ so that a new @HttpPaginatedResponse@ is returned ++* @(HP3)@ @items@ attribute is overriden so that an array of @JsonObject@ objects are returned if the response is a JSON array. If the response is a single JSON object then @items@ returns an array with one @JsonObject@. If the response is empty, then @items@ returns an empty array. ++* @(HP4)@ @statusCode@ is an integer attribute with the HTTP status code for the response ++* @(HP5)@ @success@ is a boolean attribute which is @true@ when the HTTP status code indicates success i.e. @200 <= statusCode < 300@ ++* @(HP6)@ @errorCode@ is an integer attribute populated with the error code if the @X-Ably-Errorcode@ HTTP header is sent in the response ++* @(HP7)@ @errorMessage@ is a string attribute populated with the error code if the @X-Ably-Errormessage@ HTTP header is sent in the response ++* @(HP8)@ @headers@ is an Array of key value pairs for each response header ++ + h4. TokenRequest + + * @(TE1)@ @TokenRequest@ is a type containing the token request details sent to the "REST requestToken endpoint":/rest-api/#request-token +@@ -854,6 +943,7 @@ h4. TokenRequest + * @(TE3)@ @capability@ is a string attribute containing capabilities JSON stringified + * @(TE5)@ @timestamp@ long - The timestamp (in milliseconds since the epoch) of this request. Timestamps, in conjunction with the @nonce@, are used to prevent requests from being replayed + * @(TE4)@ @ttl@ attribute represents time to live (expiry) of this token in milliseconds ++* @(TE6)@ @TokenRequest::fromJson@ static factory method that accepts either a @JsonObject@ or a string (which should be parsed as a JSON string), and returns a new @TokenRequest@. Statically typed languages (that expect the @authCallback@ to result in a typed @TokenRequest@ object, rather than, say, a hashmap) must implement this; others may at their discretion. + + h4. TokenDetails + +@@ -863,11 +953,17 @@ h4. TokenDetails + * @(TD4)@ @TokenDetails#issued@ attribute contains the time the token was issued in milliseconds. Where idiomatic in the language, this can be a Date/Time object + * @(TD5)@ @TokenDetails#capability@ attribute contains the capability JSON stringified + * @(TD6)@ @TokenDetails#clientId@ attribute contains the @clientId@ assigned to the token. If @clientId@ is @null@ or omitted, then the token is prohibited from assuming a @clientId@ in any operations, however if @clientId@ is a wildcard string @'*'@, then the token is permitted to assume any @clientId@. Any other string value for @clientId@ implies that the @clientId@ is both enforced and assumed for all operations for this token ++* @(TD7)@ @TokenDetails::fromJson@ static factory method that accepts either a @JsonObject@ or a string (which should be parsed as a JSON string), and returns a new @TokenDetails@. Statically typed languages (that expect the @authCallback@ to result in a typed @TokenDetails@ object, rather than, say, a hashmap) must implement this; others may at their discretion. ++ ++h4. AuthDetails ++ ++* @(AD1)@ @AuthDetails@ is a type used with an @AUTH@ protocol messages to send authentication details ++* @(AD2)@ @AuthDetails#accessToken@ attribute contains the token string + + h4. Stats + + * @(TS1)@ @Stats@ is a type encapsulating a statistics datapoint retrieved from the "REST stats endpoint":/rest-api/#stats. See "example statistics in JSON format":/general/statistics/ +-* @(TS2)@ All stats values default to zero when no underlying JSON value exists. We send sparse JSON to stats requests omitting fields where the value is zero to reduce bandwidth and optimise JSON parsing, however the API exposed to developers ensures that all properties of the @Stats@ object such as @stats.all.messages.count@ will always return an @Integer@ value i.e. all attributes are non-nullable ++* @(TS2)@ All stats values default to zero when no underlying JSON value exists. We send sparse JSON to stats requests omitting fields where the value is zero to reduce bandwidth and optimize JSON parsing, however the API exposed to developers ensures that all properties of the @Stats@ object such as @stats.all.messages.count@ will always return an @Integer@ value i.e. all attributes are non-nullable + * @(TS3)@ See the "Ruby Stats type documentation":http://www.rubydoc.info/gems/ably/Ably/Models/Stats for a list of attributes and their types for the @Stats@ object + * @(TS4)@ @Stats.ConnectionTypes@ - see the "Ruby ConnectionTypes documentation":http://www.rubydoc.info/gems/ably/Ably/Models/Stats/ConnectionTypes + * @(TS5)@ @Stats.MessageCount@ - see the "Ruby MessageCount documentation":http://www.rubydoc.info/gems/ably/Ably/Models/Stats/MessageCount +@@ -886,8 +982,16 @@ h4. ConnectionStateChange + + * @(TA1)@ Whenever the connection state changes, a @ConnectionStateChange@ object is emitted on the @Connection@ object + * @(TA2)@ The @ConnectionStateChange@ object contains the current state in attribute @current@, the previous state in attribute @previous@, and when the client is not connected and a connection attempt will be made automatically by the library, the amount of time in milliseconds until the next retry in the attribute @retryIn@ ++* @(TA5)@ The @ConnectionStateChange@ object contains the @event@ that generated the connection state change + * @(TA3)@ If the connection state change includes error information, then the @reason@ attribute will contain an @ErrorInfo@ object describing the reason for the error +-* @(TA4)@ See the "Java library implementation":https://github.com/ably/ably-java/blob/245a3f20a6dce0d34413ddfed19c5da8ea647422/src/io/ably/realtime/ConnectionStateListener.java#L15-L20 of this object ++ ++h4. ChannelStateChange ++ ++* @(TH1)@ Whenever the channel state changes, a @ChannelStateChange@ object is emitted on the @Channel@ object ++* @(TH2)@ The @ChannelStateChange@ object contains the current state in attribute @current@, the previous state in attribute @previous@ ++* @(TH5)@ The @ConnectionStateChange@ object contains the @event@ that generated the channel state change ++* @(TH3)@ If the channel state change includes error information, then the @reason@ attribute will contain an @ErrorInfo@ object describing the reason for the error ++* @(TH4)@ The @ChannelStateChange@ object contains an attribute @resumed@ which in combination with an @ATTACHED@ state, indicates whether the channel attach successfully resumed its state following the connection being resumed or recovered. If @resumed@ is true, then the attribute indicates that the attach within Ably successfully recovered the state for the channel, and as such there is no loss of message continuity. In all other cases, @resumed@ is false, and may be accompanied with a "channel state change error reason":#TH3 + + h4. Capability - *API not defined yet* + * @(TC1)@ This type represents a capability for a key or token +@@ -898,17 +1002,23 @@ h4. ConnectionDetails + * @(CD1)@ Connection details are optionally passed to the client library in the @CONNECTED@ @ProtocolMessage#connectionDetails@ attribute to inform the client about any constraints it should adhere to, and provide additional metadata about the connection. For example, if a request is made to publish a message that exceeds the @maxMessageSize@, the client library can reject the message immediately, without communicating with the Ably service + * @(CD2)@ Attributes available in @ConnectionDetails@: + ** @(CD2a)@ @clientId@ contains the client ID assigned to the token. If @clientId@ is @null@ or omitted, then the client is prohibited from assuming a @clientId@ in any operations, however if @clientId@ is a wildcard string @'*'@, then the client is permitted to assume any @clientId@. Any other string value for @clientId@ implies that the @clientId@ is both enforced and assumed for all operations from this client +-** @(CD2b)@ @connectionKey@ is the connection secret key string that is used to resume a connection and its state. When present, this @connectionKey@ should be considered the definitive @connectionKey@ for the current connection and the soon to be deprecated @ProtocolMessage#connectionKey@ should be ignored ++** @(CD2b)@ @connectionKey@ is the connection secret key string that is used to resume a connection and its state. + ** @(CD2c)@ @maxMessageSize@ is the maximum individual message size in bytes + ** @(CD2d)@ @maxFrameSize@ is the maximum size for a single frame of data sent to Ably. This restriction applies to a @ProtocolMessage@ sent over a realtime connection, or the total body size for a REST request + ** @(CD2e)@ @maxInboundRate@ is the maximum allowable number of requests per second from a client or Ably. In the case of a realtime connection, this restriction applies to the number of @ProtocolMessage@ objects sent, whereas in the case of REST, it is the total number of REST requests per second + ** @(CD2f)@ @connectionStateTtl@ is the duration that Ably will persist the connection state when a Realtime client is abruptly disconnected + ** @(CD2g)@ @serverId@ string is a unique identifier for the front-end server that the client has connected to. This server ID is only used for the purposes of debugging ++** @(CD2h)@ @maxIdleInterval@ is the maximum length of time in milliseconds that the server will allow no activity to occur in the server->client direction. After such a period of inactivity, the server will send a @HEARTBEAT@ or transport-level ping to the client. If the value is 0, the server will allow arbitrarily-long levels of inactivity. ++ ++h4. ChannelProperties ++* @(CP1)@ properties of a channel and its state ++* @(CP2)@ The attributes of @ChannelProperties@ consist of: ++** @(CP2a)@ @attachSerial@ string - contains the last @channelSerial@ received in an @ATTACHED@ @ProtocolMesage@ for the channel, see "RTL15a":#RTL15a + + h3(#options). Option types + + h4. ClientOptions +-* @(TO1)@ Ably library options used when instancing a REST or Realtime client library, see "Java ClientOptions":https://github.com/ably/ably-java/blob/master/src/io/ably/types/ClientOptions.java which extends "Java AuthOptions":https://github.com/ably/ably-java/blob/0e9d961a02f4b87a59a45fe59e23a5553590102d/src/io/ably/rest/Auth.java#L44-L129 as a reference ++* @(TO1)@ Ably library options used when instancing a REST or Realtime client library + * @(TO2)@ Note: @ClientOptions@ does not currently define a default for max message size or request size. This will be added in the future to ensure that REST requests does not exceed the limits before the request is made to the server. In the case of realtime, the connection constraints will be sent to the client in the initial @CONNECTED@ @ProtocolMessage@ + * @(TO3)@ The attributes of @ClientOptions@ consist of: + ** @(TO3a)@ @clientId@ string - the id of the client represented by this instance +@@ -936,26 +1046,29 @@ h4. ClientOptions + *** @(TO3k1)@ @environment@ string - for development environments only; allows a non-default Ably environment to be used such as @sandbox@ + *** @(TO3k2)@ @restHost@ string - for development environments only; allows a non-default Ably REST host to be specified. It is never valid to provide both a @restHost@ and @environment@ value + *** @(TO3k3)@ @realtimeHost@ string - for development environments only; allows a non-default Ably Realtime host to be specified. It is never valid to provide both a @realtimeHost@ and @environment@ value ++*** @(TO3k6)@ @fallbackHosts@ string array - optionally allows one or more fallback hosts to be used instead of the default fallback hosts. If an empty array is specified, then fallback host functionality is disabled ++*** @(TO3k7)@ @fallbackHostsUseDefault@ boolean - optionally allows the default fallback hosts @[a-e].ably-realtime.com@ to be used when @environment@ is not production or a custom realtime or REST host endpoint is being used. It is never valid to configure @fallbackHost@ and set @fallbackHostsUseDefault@ to @true@ + *** @(TO3k4)@ @port@ integer - for development environments only; allows a non-default Ably non-TLS port to be specified + *** @(TO3k5)@ @tlsPort@ integer - for development environments only; allows a non-default Ably TLS port to be specified +-** @(TO3l)@ The follow attributes, if set, are used to change the default behaviour of the libary: ++** @(TO3l)@ The follow attributes, if set, are used to change the default behavior of the library: + *** @(TO3l1)@ @disconnectedRetryTimeout@ integer - default 15,000 (15s). When the connection enters the @DISCONNECTED@ state, after this delay in milliseconds, if the state is still @DISCONNECTED@, the client library will attempt to reconnect automatically + *** @(TO3l2)@ @suspendedRetryTimeout@ integer - default 30,000 (30s). When the connection enters the @SUSPENDED@ state, after this delay in milliseconds, if the state is still @SUSPENDED@, the client library will attempt to reconnect automatically ++*** @(TO3l7)@ @channelRetryTimeout@ integer - default 15,000 (15s). When a channel becomes @SUSPENDED@ following a server initiated @DETACHED@, after this delay in milliseconds, if the channel is still @SUSPENDED@ and the connection is @CONNECTED@, the client library will attempt to re-attach the channel automatically + *** @(TO3l3)@ @httpOpenTimeout@ integer - default 4,000 (4s). Timeout for opening the connection, available in the client library if supported by the transport + *** @(TO3l4)@ @httpRequestTimeout@ integer - default 15,000 (15s). Timeout for any single HTTP request and response + *** @(TO3l5)@ @httpMaxRetryCount@ integer - default 3. Max number of fallback hosts to use as a fallback when an HTTP request to the primary host is unreachable or indicates that it is unserviceable + *** @(TO3l6)@ @httpMaxRetryDuration@ integer - default 10,000 (10s). Max elapsed time in which fallback host retries for HTTP requests will be attempted i.e. if the first default host attempt takes 5s, and then the subsequent fallback retry attempt takes 7s, no further fallback host attempts will be made as the total elapsed time of 12s exceeds the default 10s limit + + h4(#token-params). TokenParams +-* @(TK1)@ A class providing parameters of a token request. These params are used when invoking @Auth#authorise@, @Auth#requestToken@ and @Auth#createTokenRequest@ ++* @(TK1)@ A class providing parameters of a token request. These params are used when invoking @Auth#authorize@, @Auth#requestToken@ and @Auth#createTokenRequest@ + * @(TK2)@ The attributes of @TokenParams@ consist of: +-* @(TK2a)@ @ttl@ long - Requested time to live for the token in milliseconds. When omitted, the REST API default of 60 minutes is applied by Ably +-* @(TK2b)@ @capability@ string - Capability requirements JSON stringified for the token. When omitted, the REST API default to allow all operations is applied by Ably, with the string value @{"*":["*"]}@ +-* @(TK2c)@ @clientId@ string - A @clientId@ string to associate with this token. If @clientId@ is @null@ or omitted, then the token is prohibited from assuming a @clientId@ in any operations, however if @clientId@ is a wildcard string @'*'@, then the token is permitted to assume any @clientId@. Any other string value for @clientId@ implies that the @clientId@ is both enforced and assumed for all operations for this token +-* @(TK2d)@ @timestamp@ long - The timestamp (in milliseconds since the epoch) of this request. Timestamps, in conjunction with the @nonce@, are used to prevent requests from being replayed. @timestamp@ is a "one-time" value, and is valid in a request, but is not validly a member of any default token params such as @ClientOptions#defaultTokenParams@ ++** @(TK2a)@ @ttl@ long - Requested time to live for the token in milliseconds. When omitted, Ably will default to a TTL of 60 minutes ++** @(TK2b)@ @capability@ string - Capability requirements JSON stringified for the token. When omitted, Ably will default to the capabilities of the underlying key ++** @(TK2c)@ @clientId@ string - A @clientId@ string to associate with this token. If @clientId@ is @null@ or omitted, then the token is prohibited from assuming a @clientId@ in any operations, however if @clientId@ is a wildcard string @'*'@, then the token is permitted to assume any @clientId@. Any other string value for @clientId@ implies that the @clientId@ is both enforced and assumed for all operations for this token ++** @(TK2d)@ @timestamp@ long - The timestamp (in milliseconds since the epoch) of this request. Timestamps, in conjunction with the @nonce@, are used to prevent requests from being replayed. @timestamp@ is a "one-time" value, and is valid in a request, but is not validly a member of any default token params such as @ClientOptions#defaultTokenParams@ + + h4. AuthOptions +-* @(AO1)@ A class providing configurable authentication options used when authenticating or issuing tokens explicitly. These options are used when invoking @Auth#authorise@, @Auth#requestToken@ and @Auth#createTokenRequest@ ++* @(AO1)@ A class providing configurable authentication options used when authenticating or issuing tokens explicitly. These options are used when invoking @Auth#authorize@, @Auth#requestToken@, @Auth#createTokenRequest@ and @Auth#authorize@ + * @(AO2)@ The attributes of @AuthOptions@ consist of: + ** @(AO2a)@ @key@ string - Full Ably key string, as obtained from dashboard, used when signing token requests locally + ** @(AO2b)@ @authCallback@ - A callback to call to obtain a signed @TokenRequest@, @TokenDetails@ or a token string. This enables a client to obtain token requests or tokens from another entity, so tokens can be renewed without the client requiring a key +@@ -964,10 +1077,9 @@ h4. AuthOptions + ** @(AO2e)@ @authHeaders@ - Headers to be included in any request made by the library to the @authUrl@ + ** @(AO2f)@ @authParams@ - Additional params to be included in any request made by the library to the @authUrl@, either as query params in the case of @GET@, or form-encoded in the body in the case of @POST@ + ** @(AO2g)@ @queryTime@ - If true, the library will query the Ably system for the current time instead of relying on a locally-available time of day +-** @(AO2h)@ @force@ - when true, indicates that a new token should be requested + + h4. ChannelOptions +-* @(TB1)@ options provided when instancing a channel, see "Java ChannelOptions":https://github.com/ably/ably-java/blob/master/src/io/ably/types/ChannelOptions.java as a reference ++* @(TB1)@ options provided when instancing a channel + * @(TB2)@ The attributes of @ChannelOptions@ consist of: + ** @(TB2b)@ @cipher@, which is either: + *** @(TB2b1)@ A @CipherParams@ instance, or +@@ -975,7 +1087,7 @@ h4. ChannelOptions + * @(TB3)@ The client lib may optionally provide an alternative constructor @withCipherKey@ for ChannelOptions that takes a @key@ only. (This must be differentiated from the normal constructor such that it is clear that the value being passed in is a key). (This is intended for languages where requiring a hash map is unidiomatic) + + h4. CipherParams +-* @(TZ1)@ params to configure encryption for a channel, see "Java CipherParams class":https://github.com/ably/ably-java/blob/8a151b4edfa228ddef806fa10d2f9ce2be1ac09c/lib/src/main/java/io/ably/lib/util/Crypto.java as a reference ++* @(TZ1)@ params to configure encryption for a channel + * @(TZ2)@ The attributes of @CipherParams@ consist of anything necessary to implement the supported algorithms, in addition to the following standardised attributes: + ** @(TZ2a)@ @algorithm@ string - Default is @AES@. Optionally specify the algorithm to use for encryption, currently only @AES@ is supported + ** @(TZ2b)@ @keyLength@ integer - the length in bits of the @key@ +@@ -987,7 +1099,7 @@ h3(#defaults). Client Library defaults + The following default values are configured for the client library: + + * @(DF1)@ Realtime defaults: +-** @(DF1a)@ @connectionStateTtl@ integer - default 60s. The duration that Ably will persist the connection state when a Realtime client is abruptly disconnected. When the client is in the @DISCONNECTED@ state, once this TTL has passed, the client should change the state to the @SUSPENDED@ state signifying that the state is now lost i.e. channels need to be re-attached manually. Note that this default is overriden by @connectionStateTtl@, if specified in the @ConnectionDetails@ of the @CONNECTED@ @ProtocolMessage@ ++** @(DF1a)@ @connectionStateTtl@ integer - default 60s. The duration that Ably will persist the connection state when a Realtime client is abruptly disconnected. When the client is in the @DISCONNECTED@ state, once this TTL has passed, the client should transition the state to the @SUSPENDED@ state signifying that the state is now lost i.e. channels need to be re-attached manually. Note that this default is overriden by @connectionStateTtl@, if specified in the @ConnectionDetails@ of the @CONNECTED@ @ProtocolMessage@ + ** @(DF1b)@ @realtimeRequestTimeout@ - default 10s. When a realtime client library is establishing a connection with Ably, or sending a @HEARTBEAT@, @CONNECT@, @ATTACH@, @DETACH@ or @CLOSE@ @ProtocolMessage@ to Ably, this is the amount of time that the client library will wait before considering that request as failed and triggering a suitable failure condition + + h2(#idl). Interface Definition +@@ -1016,6 +1128,7 @@ class Rest: + constructor(ClientOptions) // RSC1 + auth: Auth // RSC5 + channels: Channels // RSN1 ++ request(String method, String path, Hash params?, JsonObject | JsonArray body?, Hash headers?) => io HttpPaginatedResponse // RSC19 + stats( + start: Time, // RSC6b1 + end: Time api-default now(), // RSC6b1 +@@ -1033,6 +1146,7 @@ class Realtime: + channels: Channels // RTC3, RTS1 + clientId: String? // proxy for RSA7 + connection: Connection // RTC2 ++ request(String method, String path, Hash params?, JsonObject | JsonArray body?, Hash headers?) => io HttpPaginatedResponse // RTC9 + stats: // Same as Rest.stats, RTC5a + close() // proxy for RTN12 + connect() // proxy for RTN11 +@@ -1051,6 +1165,7 @@ class ClientOptions: + queueMessages: Bool default true // RTP16b, TO3g + restHost: String default "rest.ably.io" // RSC12, TO3k2 + realtimeHost: String default "realtime.ably.io" // RTC1d, TO3k3 ++ fallbackHosts: String[] default nil // RSC15b, RSC15a, TO3k6 + recover: String? // RTC1c, TO3i + tls: Bool default true // RSC18, TO3d + tlsPort: Int default 443 // TO3k5 +@@ -1058,18 +1173,18 @@ class ClientOptions: + // configurable retry and failure defaults + disconnectedRetryTimeout: Duration default 15s // TO311 + suspendedRetryTimeout: Duration default 30s // RTN14d, TO312 ++ channelRetryTimeout: Duration default 15s // RTL13b, TO3l7 + httpOpenTimeout: Duration default 4s // TO313 + httpRequestTimeout: Duration default 15s // TO314 + httpMaxRetryCount: Int default 3 // TO315 + httpMaxRetryDuration: Duration default 10s // TO315 + + class AuthOptions: // RSA8e +- authCallback: (String | TokenDetails | TokenRequest) ->? // RSC14c, RSA4, TO3j5, AO2b ++ authCallback: (() -> io (String | TokenDetails | TokenRequest))? // RSC14c, RSA4, TO3j5, AO2b + authHeaders: [(String, String)]? // RSA8c3, TO3j8, AO2e + authMethod: .GET | .POST default .GET // RSA8c, TO3j7, AO2d + authParams: [String: [String]]? // RSA8c3, RSA8c1, TO3j9, AO2f + authUrl: String? // RSC14c, RSA4, RSA8c, TO3j6, AO2c +- force: Bool default false // RSA10d, AO2h + key: String? // RSC14a, RSA14, TO3j1, AO2a + queryTime: Bool default false // RSA9d, TO3j10, AO2a + token: String? | TokenDetails? // RSC14c, RSA4, TO3j2 +@@ -1085,11 +1200,12 @@ class TokenParams: // RSAA8e + + class Auth: + clientId: String? // RSA7, RSC17, RSA12 +- authorise(TokenParams?, AuthOptions?) => io TokenDetails // RSA10 ++ authorize(TokenParams?, AuthOptions?) => io TokenDetails // RSA10 + createTokenRequest(TokenParams?, AuthOptions?) => io TokenRequest // RSA9 + requestToken(TokenParams?, AuthOptions?) => io TokenDetails // RSA8e + + class TokenDetails: ++ +fromJson(String | JsonObject) -> TokenDetails// TD7 + capability: String // TD5 + clientId: String? // TD6 + expires: Time // TD3 +@@ -1097,6 +1213,7 @@ class TokenDetails: + token: String // TD2 + + class TokenRequest: ++ +fromJson(String | JsonObject) -> TokenRequest // TE6 + capability: String // TE3 + clientId: String? // TE2 + keyName: String // TE2 +@@ -1122,14 +1239,14 @@ class RestChannel: + limit: int api-default 100 // RSL2b3 + ) => io PaginatedResult // RSL2a + publish([Message]) => io // RSL1 +- publish(name: String?, data: Data?) => io // RSL1 +- publish(name: String?, data: Data?, clientId: String) => io // RSL1h ++ publish(name: String?, data: Data?, clientId?: String, extras?: JsonObject) => io // RSL1, RSL1h + + class RealtimeChannel: +- embeds EventEmitter // RTL2 ++ embeds EventEmitter // RTL2a, RTL2d, RTL2e + errorReason: ErrorInfo? // RTL4e + state: ChannelState // RTL2b + presence: RealtimePresence // RTL9 ++ properties: ChannelProperties // CP1, RTL15 + attach() => io // RTL4d + detach() => io // RTL5e + history( +@@ -1140,8 +1257,7 @@ class RealtimeChannel: + untilAttach: Bool default false // RTL10b + ) => io PaginatedResult // RSL2a + publish([Message]) => io // RTL6i +- publish(name: String?, data: Data?) => io // RTL6i +- publish(name: String?, data: Data?, clientId: String) => io // RTL6h ++ publish(name: String?, data: Data?, clientId?: String, extras?: JsonObject) => io // RTL6i, RTL6h + subscribe((Message) ->) => io // RTL7a + subscribe(String, (Message) ->) => io // RTL7b + unsubscribe() // RTL8a, RTE5 +@@ -1154,11 +1270,19 @@ enum ChannelState: + ATTACHED + DETACHING + DETACHED ++ SUSPENDED + FAILED + + enum ChannelEvent: + embeds ChannelState +- ERROR // RTL2c ++ UPDATE // RTL2g ++ ++class ChannelStateChange: ++ current: ChannelState // RTL2a, RTL2b ++ event: ChannelEvent // TH5 ++ previous: ChannelState // RTL2a, RTL2b ++ reason: ErrorInfo? // RTL2e, TH3 ++ resumed: Boolean // RTL2f, TH4 + + class ChannelOptions: + +withCipherKey(key: Binary | String)? -> ChannelOptions // TB3 +@@ -1229,19 +1353,25 @@ class ConnectionDetails: + maxInboundRate: Int // CD2e + maxMessageSize: Int // CD2c + serverId: String // CD2g ++ maxIdleInterval: Duration // CD2h + + class Message: + constructor(name: String?, data: Data?) // TM2 + constructor(name: String?, data: Data?, clientId: String?) // TM2 ++ +fromEncoded(JsonObject, ChannelOptions?) -> Message // TM3 ++ +fromEncodedArray(JsonArray, ChannelOptions?) -> [Message] // TM3 + clientId: String? // RSL1g1, TM2b + connectionId: String? // TM2c + data: Data? // TM2d + encoding: String? // TM2e ++ extras: JsonObject? // TM2i + id: String // TM2a + name: String? // TM2g + timestamp: Time // TM2f + + class PresenceMessage ++ +fromEncoded(JsonObject, ChannelOptions?) -> PresenceMessage // TP4 ++ +fromEncodedArray(JsonArray, ChannelOptions?) -> [PresenceMessage] // TP4 + action: PresenceAction // TP3b + clientId: String // TP3c + connectionId: String // TP3d +@@ -1253,15 +1383,15 @@ class PresenceMessage + + class ProtocolMessage: + action: ProtocolMessageAction // TR2, TR4a ++ auth: AuthDetails? // + channel: String? // TR4b + channelSerial: String? // TR4c + connectionDetails: ConnectionDetails? // RSA7b3, RTN19, TR4o + connectionId: String? // RTN15c1, TR4d +- connectionKey: String? // TR4e + connectionSerial: Int? // RTN10c, TR4f + count: Int? // TR4g + error: ErrorInfo? // RTN15c2, TR4h +- flags: .HAS_PRESENCE & .HAS_BACKLOG ? // RTP1, TR3, TR4i ++ flags: .HAS_PRESENCE & .HAS_BACKLOG & .RESUMED ? // RTP1, TR3, TR4i, RTL2f + id: String? // TR4b + messages: [Message]? // TR4k + msgSerial: Int? // RTN7b, TR4j +@@ -1286,9 +1416,13 @@ enum ProtocolMessageAction: + PRESENCE // TR2 + MESSAGE // TR2 + SYNC // TR2 ++ AUTH // TR2 ++ ++class AuthDetails: // RTC8 ++ accessToken: String // AD2 + + class Connection: +- embeds EventEmitter // RTN4a, RTN4e ++ embeds EventEmitter // RTN4a, RTN4e, RTN4g + errorReason: ErrorInfo? // RTN14a + id: String? // RTN8 + key: String? // RTN9 +@@ -1309,8 +1443,13 @@ enum ConnectionState: + CLOSED + FAILED + ++enum ConnectionEvent: ++ embeds ConnectionState ++ UPDATE // RTN4h ++ + class ConnectionStateChange: + current: ConnectionState // TA2 ++ event: ConnectionEvent // TA5 + previous: ConnectionState // TA2 + reason: ErrorInfo? // RTN4f, TA3 + retryIn: Duration? // RTN14d, TA2 +@@ -1355,4 +1494,19 @@ class PaginatedResult: + hasNext() -> Bool // TG6 + isLast() -> Bool // TG7 + next() => io PaginatedResult? // TG4 ++ ++class HttpPaginatedResponse // RSC19b ++ embeds PaginatedResult ++ items: [JsonObject] // HP3 ++ statusCode: Int // HP4 ++ success: Bool // HP5 ++ errorCode: Int // HP6 ++ errorMessage: String // HP7 ++ headers: Hash // HP8 + ``` ++ ++h2(#old-specs). Old specs ++ ++Use the version navigation to view older versions. References to diffs for each version are maintained below: ++ ++* v0.8 deprecated in Jan 2017. "View 0.8 → 1.0 changes":https://github.com/ably/docs/blob/source/content/client-lib-development-guide/versions/features-0-8__1-0.diff From 70b0ada8f3ca06fce0a94bfec31102182c0950cf Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Mon, 23 Jan 2017 14:06:58 +0000 Subject: [PATCH 06/19] spec: Listener issue for Presence was not fixed See https://github.com/ably/docs/commit/66dad2c0bd609d315157a34ae4a00c3c3c9ffae4 --- content/client-lib-development-guide/features.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-lib-development-guide/features.textile b/content/client-lib-development-guide/features.textile index 3c723999da..3e9c5500f5 100644 --- a/content/client-lib-development-guide/features.textile +++ b/content/client-lib-development-guide/features.textile @@ -526,7 +526,7 @@ h3(#realtime-presence). Presence * @(RTP6)@ @Presence#subscribe@ function: ** @(RTP6a)@ Subscribe with no arguments subscribes a listener to all presence messages ** @(RTP6b)@ Subscribe with a single action argument - such as @ENTER@, @LEAVE@, @UPDATE@ or @PRESENT@ - subscribes a listener to receive only presence messages with that action -** @(RTP6c)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. However, if the channel is in or enters the @FAILED@ state before the operation succeeds, it will result in the listener not being registered and an error being indicated, typically to the optional callback where the language permits +** @(RTP6c)@ Implicitly attaches the @Channel@ if the channel is in the @INITIALIZED@ state. The optional callback, if provided, is called according to "@RTL4d@":#RTL4d based on the implicit attach operation. The listener will always be registered regardless of the implicit attach result * @(RTP7)@ @Presence#unsubscribe@ function: ** @(RTP7a)@ Unsubscribe with no arguments unsubscribes the listener if previously subscribed with an action-specific subscription ** @(RTP7b)@ Unsubscribe with a single action argument unsubscribes the provided listener to all presence messages for that action From df664af33e5f6f7b3c1c0c229a173cbc3b6f553c Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Mon, 23 Jan 2017 15:42:32 +0000 Subject: [PATCH 07/19] spec: Indentation fix --- content/client-lib-development-guide/features.textile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-lib-development-guide/features.textile b/content/client-lib-development-guide/features.textile index 3e9c5500f5..4077f1586b 100644 --- a/content/client-lib-development-guide/features.textile +++ b/content/client-lib-development-guide/features.textile @@ -507,7 +507,7 @@ h3(#realtime-presence). Presence ** @(RTP18b)@ The the sync operation for that sequence identifier has completed once the cursor is empty; that is, when the @channelSerial@ looks like @:@ ** @(RTP18c)@ a @SYNC@ may also be sent with no @channelSerial@ attribute. In this case, the sync data is entirely contained within that @ProtocolMessage@ * @(RTP19)@ If the @PresenceMap@ has existing members when a @SYNC@ is started, the client library must ensure that members no longer present on the channel are removed from the local @PresenceMap@ once the sync is complete. In order to do this, the client library must keep track of any members that have not been added or updated in the @PresenceMap@ during the sync process. Note that a member can be added or updated when received in a @SYNC@ message or when received in a @PRESENCE@ message during the sync process. Once the sync is complete, the members in the @PresenceMap@ that have not been added or updated should be removed from the @PresenceMap@ and a @LEAVE@ event should be published for each. The @PresenceMessage@ published should contain the original attributes of the presence member with the @action@ set to @LEAVE@, @PresenceMessage#id@ set to @null@, and the @timestamp@ set to the current time. This behavior should be tested as follows: @ENTER@ presence on a channel, wait for @SYNC@ to complete, inject a member directly into the local @PresenceMap@ so that it only exists locally and not on the server, send a @SYNC@ message with the @channel@ attribute populated with the current channel which will trigger a server initiated @SYNC@. A @LEAVE@ event should then be published for the injected member, and checking the @PresenceMap@ should reveal that the member was removed and the valid member entered for this connection is still present -* @(RTP19a)@ If the @PresenceMap@ has existing members when an @ATTACHED@ message is received without a @HAS_PRESENCE@ flag, the client library should emit a @LEAVE@ event for each existing member, and the @PresenceMessage@ published should contain the original attributes of the presence member with the @action@ set to @LEAVE@, @PresenceMessage#id@ set to @null@, and the @timestamp@ set to the current time. Once complete, all members in the @PresenceMap@ should be removed as there are no members present on the channel +** @(RTP19a)@ If the @PresenceMap@ has existing members when an @ATTACHED@ message is received without a @HAS_PRESENCE@ flag, the client library should emit a @LEAVE@ event for each existing member, and the @PresenceMessage@ published should contain the original attributes of the presence member with the @action@ set to @LEAVE@, @PresenceMessage#id@ set to @null@, and the @timestamp@ set to the current time. Once complete, all members in the @PresenceMap@ should be removed as there are no members present on the channel * @(RTP17)@ The Presence object is also responsible for keeping a separate copy of an object logically equivalent to the @PresenceMap@ containing only members that match the current @connectionId@. Any @ENTER@, @PRESENT@, @UPDATE@ or @LEAVE@ event that matches the current @connectionId@ should be applied to this object in the same way it is done for the @PresenceMap@. This object should be private and is used to maintain a list of members that need to be automatically re-entered by the @Presence@ object when a @Channel@ becomes @ATTACHED@ with some or all continuity lost. ** @(RTP17a)@ All members belonging to the current connection are published as a @PresenceMessage@ on the @Channel@ by the server irrespective of whether the client has permission to subscribe or the @Channel@ is configured to publish presence events. A test should exist that attaches to a @Channel@ with a @presence@ capability and without a @subscribe@ capability. It should then enter the @Channel@ and ensure that the member entered from the current connection is present in the internal and public presence set available via "@Presence#get@":#RTP11 * @(RTP4)@ Ensure a test exists that enters 250 members using @Presence#enterClient@ on a single connection, and checks for @PRESENT@ events to be emitted on another connection for each member, and once sync is complete, all 250 members should be present in a @Presence#get@ request From 144f84083db821b109bb90640dc4ba80c16c0416 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Tue, 14 Feb 2017 17:56:43 +0000 Subject: [PATCH 08/19] Fix broken spec ref --- content/client-lib-development-guide/features.textile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/client-lib-development-guide/features.textile b/content/client-lib-development-guide/features.textile index 4077f1586b..2e09725948 100644 --- a/content/client-lib-development-guide/features.textile +++ b/content/client-lib-development-guide/features.textile @@ -70,7 +70,7 @@ h3(#restclient). RestClient ** @(RSC8a)@ "MessagePack":http://msgpack.org/ binary protocol (this is the default for environments having a suitable level or support for binary data) ** @(RSC8b)@ JSON text protocol (used when @useBinaryProtocol@ option is false) * @(RSC9)@ Uses @Auth@ to establish what authentication scheme to use, how to authenticate, and automatic issuing of tokens when necessary -* @(RSC10)@ If a REST request responds with a token error (401 HTTP status code and an Ably error value @40140 <= code < 40150@), then the Auth class is responsible for reissuing a token and the request should be reattempted, see "RSC14c":#RSC14c and "RSC14d":#RSC14d +* @(RSC10)@ If a REST request responds with a token error (401 HTTP status code and an Ably error value @40140 <= code < 40150@), then the Auth class is responsible for reissuing a token and the request should be reattempted, see "RSA4a":#RSA4a and "RSA4b":#RSA4b * @(RSC11)@ Requests are sent to the default endpoint @rest.ably.io@. However, if the @restHost@ option is set, the client will send requests to the specified host. If @environment@ option is configured and is not "production", the environment name is prefixed to the default host endpoint and the @restHost@ is set accordingly. For example, if the @environment@ is set to sandbox, then the @restHost@ endpoint will become @sandbox-rest.ably.io@. See "TO3k2":#TO3k2 for constraints. * @(RSC12)@ REST endpoint host is configurable in the Client constructor with the option @restHost@ * @(RSC13)@ The client library must use the connection and request timeouts specified in the @ClientOptions@, falling back to the defaults described in @ClientOptions@ below @@ -1180,15 +1180,15 @@ class ClientOptions: httpMaxRetryDuration: Duration default 10s // TO315 class AuthOptions: // RSA8e - authCallback: (() -> io (String | TokenDetails | TokenRequest))? // RSC14c, RSA4, TO3j5, AO2b + authCallback: (() -> io (String | TokenDetails | TokenRequest))? // RSA4a, RSA4, TO3j5, AO2b authHeaders: [(String, String)]? // RSA8c3, TO3j8, AO2e authMethod: .GET | .POST default .GET // RSA8c, TO3j7, AO2d authParams: [String: [String]]? // RSA8c3, RSA8c1, TO3j9, AO2f - authUrl: String? // RSC14c, RSA4, RSA8c, TO3j6, AO2c + authUrl: String? // RSA4a, RSA4, RSA8c, TO3j6, AO2c key: String? // RSC14a, RSA14, TO3j1, AO2a queryTime: Bool default false // RSA9d, TO3j10, AO2a - token: String? | TokenDetails? // RSC14c, RSA4, TO3j2 - tokenDetails: TokenDetails? // RSC14c, RSA4, TO3j3 + token: String? | TokenDetails? // RSA4a, RSA4, TO3j2 + tokenDetails: TokenDetails? // RSA4a, RSA4, TO3j3 useTokenAuth: Bool? // RSA4, RSA14, TO3j4 class TokenParams: // RSAA8e From d95832691a9a91be3ac6ec0cf7afbe1d23454ca4 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Thu, 16 Feb 2017 12:05:38 +0000 Subject: [PATCH 09/19] spec: Clarify how ID is constructed for Realtime messages --- content/client-lib-development-guide/features.textile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/client-lib-development-guide/features.textile b/content/client-lib-development-guide/features.textile index 2e09725948..c25bfe1704 100644 --- a/content/client-lib-development-guide/features.textile +++ b/content/client-lib-development-guide/features.textile @@ -867,7 +867,7 @@ h4. Message * @(TM1)@ A @Message@ represents an individual message to be sent or received via the Ably Realtime service. See the "Ruby Message documentation":http://www.rubydoc.info/gems/ably/Ably/Models/Message, but bear in mind the attributes following underscore naming in Ruby * @(TM2)@ Attributes available in a @Message@, see the "Ruby Message documentation":http://www.rubydoc.info/gems/ably/Ably/Models/Message for an explanation of each attribute: -** @(TM2a)@ @id@ string - unique ID for this message. If a message received from Ably does not contain an @id@, it should be set to @protocolMsgId:index@, where @protocolMsgId@ is the id of the @ProtocolMessage@ encapsulating it, and @index@ is the index of the message inside the @messages@ array of the @ProtocolMessage@ +** @(TM2a)@ @id@ string - unique ID for this message. This attribute is always populated for messages received over REST. For messages received over Realtime, if the message does not contain an @id@, it should be set to @protocolMsgId:index@, where @protocolMsgId@ is the id of the @ProtocolMessage@ encapsulating it, and @index@ is the index of the message inside the @messages@ array of the @ProtocolMessage@ ** @(TM2b)@ @clientId@ string ** @(TM2c)@ @connectionId@ string. If a message received from Ably does not contain a @connectionId@, it should be set to the @connectionId@ of the encapsulating @ProtocolMessage@ ** @(TM2h)@ @connectionKey@ string (note this is only ever populated by a publishing client when "publishing on behalf of another client":/rest/channels-messages#publish-on-behalf, the @connectionKey@ will never be populated for messages received. A simple test for this attribute over REST is to populate this with an invalid @connectionKey@ when publishing and expecting a suitable error) @@ -883,7 +883,7 @@ h4. PresenceMessage * @(TP1)@ A @PresenceMessage@ represents an individual presence message to be sent or received via the Ably Realtime service. See the "Ruby PresenceMessage documentation":http://www.rubydoc.info/gems/ably/Ably/Models/PresenceMessage, but bear in mind the attributes following underscore naming in Ruby * @(TP2)@ @PresenceMessage@ @Action@ enum has the following values in order from zero: @ABSENT@, @PRESENT@, @ENTER@, @LEAVE@, @UPDATE@ * @(TP3)@ Attributes available in a @PresenceMessage@, see the "Ruby PresenceMessage documentation":http://www.rubydoc.info/gems/ably/Ably/Models/PresenceMessage for an explanation of each attribute: -** @(TP3a)@ @id@ string - unique ID for this message. If a presence message received from Ably does not contain an @id@, it should be set to @protocolMsgId:index@, where @protocolMsgId@ is the id of the @ProtocolMessage@ encapsulating it, and @index@ is the index of the message inside the @presence@ array of the @ProtocolMessage@ +** @(TP3a)@ @id@ string - unique ID for this presence message. This attribute is always populated for presence messages received over REST. For presence messages received over Realtime, if the presence message does not contain an @id@, it should be set to @protocolMsgId:index@, where @protocolMsgId@ is the id of the @ProtocolMessage@ encapsulating it, and @index@ is the index of the presence message inside the @presence@ array of the @ProtocolMessage@ ** @(TP3b)@ @action@ enum ** @(TP3c)@ @clientId@ string ** @(TP3d)@ @connectionId@ string. If a presence message received from Ably does not contain a @connectionId@, it should be set to the @connectionId@ of the encapsulating @ProtocolMessage@ From 5d87c9b5a9bc3aad5d230e7134609c27ada6fa3e Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 22 Feb 2017 17:30:30 +0000 Subject: [PATCH 10/19] spec: Fix mismatch of HTTP retry and request timeouts Fixes https://github.com/ably/docs/issues/274 --- content/client-lib-development-guide/features.textile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/client-lib-development-guide/features.textile b/content/client-lib-development-guide/features.textile index c25bfe1704..fa3c732723 100644 --- a/content/client-lib-development-guide/features.textile +++ b/content/client-lib-development-guide/features.textile @@ -1055,9 +1055,9 @@ h4. ClientOptions *** @(TO3l2)@ @suspendedRetryTimeout@ integer - default 30,000 (30s). When the connection enters the @SUSPENDED@ state, after this delay in milliseconds, if the state is still @SUSPENDED@, the client library will attempt to reconnect automatically *** @(TO3l7)@ @channelRetryTimeout@ integer - default 15,000 (15s). When a channel becomes @SUSPENDED@ following a server initiated @DETACHED@, after this delay in milliseconds, if the channel is still @SUSPENDED@ and the connection is @CONNECTED@, the client library will attempt to re-attach the channel automatically *** @(TO3l3)@ @httpOpenTimeout@ integer - default 4,000 (4s). Timeout for opening the connection, available in the client library if supported by the transport -*** @(TO3l4)@ @httpRequestTimeout@ integer - default 15,000 (15s). Timeout for any single HTTP request and response +*** @(TO3l4)@ @httpRequestTimeout@ integer - default 10,000 (10s). Timeout for any single HTTP request and response *** @(TO3l5)@ @httpMaxRetryCount@ integer - default 3. Max number of fallback hosts to use as a fallback when an HTTP request to the primary host is unreachable or indicates that it is unserviceable -*** @(TO3l6)@ @httpMaxRetryDuration@ integer - default 10,000 (10s). Max elapsed time in which fallback host retries for HTTP requests will be attempted i.e. if the first default host attempt takes 5s, and then the subsequent fallback retry attempt takes 7s, no further fallback host attempts will be made as the total elapsed time of 12s exceeds the default 10s limit +*** @(TO3l6)@ @httpMaxRetryDuration@ integer - default 15,000 (15s). Max elapsed time in which fallback host retries for HTTP requests will be attempted i.e. if the first default host attempt takes 7s, and then the subsequent fallback retry attempt takes 10s, no further fallback host attempts will be made as the total elapsed time of 17s exceeds the default 15s limit h4(#token-params). TokenParams * @(TK1)@ A class providing parameters of a token request. These params are used when invoking @Auth#authorize@, @Auth#requestToken@ and @Auth#createTokenRequest@ @@ -1175,9 +1175,9 @@ class ClientOptions: suspendedRetryTimeout: Duration default 30s // RTN14d, TO312 channelRetryTimeout: Duration default 15s // RTL13b, TO3l7 httpOpenTimeout: Duration default 4s // TO313 - httpRequestTimeout: Duration default 15s // TO314 + httpRequestTimeout: Duration default 10s // TO314 httpMaxRetryCount: Int default 3 // TO315 - httpMaxRetryDuration: Duration default 10s // TO315 + httpMaxRetryDuration: Duration default 15s // TO315 class AuthOptions: // RSA8e authCallback: (() -> io (String | TokenDetails | TokenRequest))? // RSA4a, RSA4, TO3j5, AO2b From b3daed9873990c807e16c84ebe9e4beed21de04d Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Tue, 7 Mar 2017 21:14:44 +0000 Subject: [PATCH 11/19] api: Ensure queue docs make it clear envelopes contain only one message per envelope Fixes https://github.com/ably/docs/issues/278 --- content/general/queues.textile | 25 +++++++++++++++---- .../queue-amqp-neutrino-profanity.textile | 5 ++++ .../queue-amqp-wolfram-alpha.textile | 6 ++++- .../queue-stomp-neutrino-profanity.textile | 6 +++++ 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/content/general/queues.textile b/content/general/queues.textile index 52dfa2e451..8a893fce16 100644 --- a/content/general/queues.textile +++ b/content/general/queues.textile @@ -112,7 +112,7 @@ bc[sh]. amqp-consume --queue-name [Name] \ --host [Server endpoint host] --port [Server endpoint port] \ --ssl --vhost shared --creds [your API key] -Whenever a message is published to the queue you are subscribing to, the amqp-consume tool will output the message details such as: +Whenever a message is published to the queue you are subscribing to, the @amqp-consume@ tool will output the message details such as: ```[sh] Message received @@ -130,13 +130,18 @@ Data: { "messageId":"vjzxPR-XK3:3", "messages":[ { - "id":"vjzxPR-XK3:3:0","name":"event","connectionId":"vjzxPR-XK3", - "timestamp":1485914937909,"data":"payload" + "id":"vjzxPR-XK3:3:0", + "name":"event", + "connectionId":"vjzxPR-XK3", + "timestamp":1485914937909, + "data":"payload" } ] } ``` +_Please note that the @messages@ attribute is an @Array@ so that future envelope options may allow messages to be bundled into a single envelope ("WebHooks":/general/webhooks currently bundle messages). However, with the current queue rule design, an envelope will only ever contain one message._ + h3. Consuming messages from queues Consuming messages from Ably Reactor Message Queues is mostly the same as consuming from any other queue supporting AMQP or STOMP protocols. However, there a few tips below to avoid common pitfalls. @@ -176,6 +181,11 @@ amqp.connect(url, (err, conn) => { /* Wait for messages published to the Ably Reactor queue */ ch.consume('UATwBQ:example-queue', (item) => { let decodedEnvelope = JSON.parse(item.content) + + /* The envelope messages attribute will only contain one message. However, + in future versions, we may allow optional bundling of messages into a + single queue message and as such this attribute is an Array to support + that in future */ let messages = Ably.Realtime.Message.fromEncodedArray(decodedEnvelope.messages) messages.forEach((message) => { actionMessage(message) @@ -245,6 +255,11 @@ Stompit.connect(connectOptions, (error, client) => { if (err) { return handleError(err) } let decodedEnvelope = JSON.parse(item.content) + + /* The envelope messages attribute will only contain one message. However, + in future versions, we may allow optional bundling of messages into a + single queue message and as such this attribute is an Array to support + that in future */ let messages = Ably.Realtime.Message.fromEncodedArray(decodedEnvelope.messages) messages.forEach((message) => { actionMessage(message) @@ -299,7 +314,7 @@ h5. Enveloped message example } ``` -Please note that the @messages@ attribute is an array of messages so that future envelope options may allow messages to be bundled into a single envelope (like "WebHooks":/general/webhooks). However, with the current queue rule design, an envelope will only ever contain one message. +_Please note that the @messages@ attribute is an @Array@ so that future envelope options may allow messages to be bundled into a single envelope ("WebHooks":/general/webhooks currently bundle messages). However, with the current queue rule design, an envelope will only ever contain one message._ h5. Non-enveloped message example @@ -348,7 +363,7 @@ h5. Enveloped presence message example } ``` -Please note that the @presence@ attribute is an array of presence messages so that infuture envelope options may allow presence messages to be bundled into a single envelope (like "WebHooks":/general/webhooks). However, with the current queue rule design, an envelope will only ever contain one presence message. +_Please note that the @presence@ attribute is an @Array@ so that future envelope options may allow presence messages to be bundled into a single envelope ("WebHooks":/general/webhooks currently bundle messages). However, with the current queue rule design, an envelope will only ever contain one presence message._ h5. Non-enveloped presence message example diff --git a/content/tutorials/queue-amqp-neutrino-profanity.textile b/content/tutorials/queue-amqp-neutrino-profanity.textile index ae89e672f0..b4c4d17f9e 100644 --- a/content/tutorials/queue-amqp-neutrino-profanity.textile +++ b/content/tutorials/queue-amqp-neutrino-profanity.textile @@ -274,6 +274,10 @@ Now create a "@worker.js@ file":https://github.com/ably/tutorials/blob/48c3f21b8 ch.consume(queue, (item) => { const decodedEnvelope = JSON.parse(item.content); + /* Use the Ably library to decode the message. + The envelope messages attribute will only contain one message. However, in future versions, + we may allow optional bundling of messages into a single queue message and as such this + attribute is an Array to support that in future */ const messages = Ably.Realtime.Message.fromEncodedArray(decodedEnvelope.messages); messages.forEach(function(message) { filteredChannel.publish('text', 'Placeholder until Neutrino connected', (err) => { @@ -304,6 +308,7 @@ Note that the: * The queue endpoint is constructed from the endpoint and @vhost@ visible for each queue in the queue tab of your dashboard (see above) * The queue name argument @neutrino@ passed to @worker.start@ is in fact appended to the @appId@ in the @start@ function. All fully qualified queue names follow the format @appId:queueName@ as you will see in your queue tab +* Whilst the code above can handle multiple messages per envelope, we currently only support one message per envelope. The envelope @messages@ attribute is an @Array@ so that in future we could optionally support message bundling "See this complete step in Github":https://github.com/ably/tutorials/commit/48c3f21b821304ebef190b84355161e5736309cc diff --git a/content/tutorials/queue-amqp-wolfram-alpha.textile b/content/tutorials/queue-amqp-wolfram-alpha.textile index b62f7dbcf1..2d66a886f3 100644 --- a/content/tutorials/queue-amqp-wolfram-alpha.textile +++ b/content/tutorials/queue-amqp-wolfram-alpha.textile @@ -276,7 +276,10 @@ Now create a "@worker.js@ file":https://github.com/ably/tutorials/blob/772c7502c /* Parse the JSON envelope */ const decodedEnvelope = JSON.parse(item.content); - /* Use the Ably library to decode the message */ + /* Use the Ably library to decode the message. + The envelope messages attribute will only contain one message. However, in future versions, + we may allow optional bundling of messages into a single queue message and as such this + attribute is an Array to support that in future */ const messages = Ably.Realtime.Message.fromEncodedArray(decodedEnvelope.messages); messages.forEach((message) => { answersChannel.publish('answer', 'Placeholder until Wolfram connected', (err) => { @@ -307,6 +310,7 @@ Note that the: * The queue endpoint is constructed from the endpoint and @vhost@ visible for each queue in the queue tab of your dashboard (see above) * The queue name argument @wolfram@ passed to @worker.start@ is in fact appended to the @appId@ in the @start@ function. All fully qualified queue names follow the format @appId:queueName@ as you will see in your queue tab +* Whilst the code above can handle multiple messages per envelope, we currently only support one message per envelope. The envelope @messages@ attribute is an @Array@ so that in future we could optionally support message bundling "See this complete step in Github":https://github.com/ably/tutorials/commit/772c7502c4f0f105a1ebfff0cdb897f2b6b217ac diff --git a/content/tutorials/queue-stomp-neutrino-profanity.textile b/content/tutorials/queue-stomp-neutrino-profanity.textile index fe3195ddd0..7a2e9f0475 100644 --- a/content/tutorials/queue-stomp-neutrino-profanity.textile +++ b/content/tutorials/queue-stomp-neutrino-profanity.textile @@ -293,6 +293,11 @@ Now create a "@worker.js@ file":https://github.com/ably/tutorials/blob/2f44b7153 } const decodedEnvelope = JSON.parse(body); + + /* Use the Ably library to decode the message. + The envelope messages attribute will only contain one message. However, in future versions, + we may allow optional bundling of messages into a single queue message and as such this + attribute is an Array to support that in future */ const messages = Ably.Realtime.Message.fromEncodedArray(decodedEnvelope.messages); messages.forEach(function(message) { console.log('worker:', 'Received text', message.data, ' - about to ask Neutrino to filter bad words (WHEN IMPLEMENTED)'); @@ -319,6 +324,7 @@ Note that the: * The port is always 61614 for STOMP over TLS * The @vhost@ attribute is required and can be found in the queue tab for each queue * The queue name argument @neutrino@ passed to @worker.start@ is in fact appended to the @appId@ in the @start@ function. All fully qualified queue names follow the format @appId:queueName@ as you will see in your queue tab +* Whilst the code above can handle multiple messages per envelope, we currently only support one message per envelope. The envelope @messages@ attribute is an @Array@ so that in future we could optionally support message bundling "See this complete step in Github":https://github.com/ably/tutorials/commit/2f44b7153d3bf463e2cd5ac9ed702e303238d51c From 5ef3efef77f5c5524789df6a2377d9f8a75d8261 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 8 Mar 2017 00:56:04 +0000 Subject: [PATCH 12/19] tutorials: Use 1.* JS --- content/tutorials/queue-amqp-neutrino-profanity.textile | 8 ++++---- content/tutorials/queue-amqp-wolfram-alpha.textile | 8 ++++---- content/tutorials/queue-stomp-neutrino-profanity.textile | 8 ++++---- content/tutorials/webhook-chuck-norris.textile | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/content/tutorials/queue-amqp-neutrino-profanity.textile b/content/tutorials/queue-amqp-neutrino-profanity.textile index b4c4d17f9e..648b134c14 100644 --- a/content/tutorials/queue-amqp-neutrino-profanity.textile +++ b/content/tutorials/queue-amqp-neutrino-profanity.textile @@ -70,7 +70,7 @@ First we'll add the @express@ NPM module and create a @package.json@: "start": "node ./server.js" }, "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "express": "~4.0" } } @@ -140,7 +140,7 @@ First add the Ably client library loader from our CDN to the HTML file "@public/ ```[html] - + ``` @@ -233,7 +233,7 @@ We're now ready to start consuming messages from the queue. There are "plenty of ```[json] "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "amqplib": "^0.4", "express": ">=4.14.0" } @@ -338,7 +338,7 @@ Now that you have an API key you can use to communicate with the Neutrino API, y ```[json] "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "amqplib": "^0.4", "express": ">=4.14.0", "request": ">=2.79.0" diff --git a/content/tutorials/queue-amqp-wolfram-alpha.textile b/content/tutorials/queue-amqp-wolfram-alpha.textile index 2d66a886f3..bc82e2684a 100644 --- a/content/tutorials/queue-amqp-wolfram-alpha.textile +++ b/content/tutorials/queue-amqp-wolfram-alpha.textile @@ -70,7 +70,7 @@ First we'll add the @express@ NPM module and create a @package.json@: "start": "node ./server.js" }, "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "express": "~4.0" } } @@ -140,7 +140,7 @@ First add the Ably client library loader from our CDN to the HTML file "@public/ ```[html] - + ``` @@ -234,7 +234,7 @@ We're now ready to start consuming messages from the queue. There are "plenty of ```[json] "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "amqplib": "^0.4", "express": ">=4.14.0" } @@ -340,7 +340,7 @@ Now that you have an AppID you can use to communicate with the Wolfram Alpha API ```[json] "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "amqplib": "^0.4", "express": ">=4.14.0", "request": ">=2.79.0" diff --git a/content/tutorials/queue-stomp-neutrino-profanity.textile b/content/tutorials/queue-stomp-neutrino-profanity.textile index 7a2e9f0475..99d5359e42 100644 --- a/content/tutorials/queue-stomp-neutrino-profanity.textile +++ b/content/tutorials/queue-stomp-neutrino-profanity.textile @@ -70,7 +70,7 @@ First we'll add the @express@ NPM module and create a @package.json@: "start": "node ./server.js" }, "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "express": "~4.0" } } @@ -140,7 +140,7 @@ First add the Ably client library loader from our CDN to the HTML file "@public/ ```[html] - + ``` @@ -233,7 +233,7 @@ We're now ready to start consuming messages from the queue. There are "plenty of ```[json] "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "amqplib": "^0.4", "express": ">=4.14.0" } @@ -354,7 +354,7 @@ Now that you have an API key you can use to communicate with the Neutrino API, y ```[json] "dependencies": { - "ably": ">=0.9.0-beta", + "ably": "~1.0", "express": ">=4.14.0", "request": ">=2.79.0", "stompit": "^0.24" diff --git a/content/tutorials/webhook-chuck-norris.textile b/content/tutorials/webhook-chuck-norris.textile index 39da2c2af8..5020d48ff4 100644 --- a/content/tutorials/webhook-chuck-norris.textile +++ b/content/tutorials/webhook-chuck-norris.textile @@ -109,7 +109,7 @@ To start using Ably within your Rails server, you first need to install the Ably Add the following to your "@Gemfile@":https://github.com/ably/tutorials/blob/2197a076f89a0103f85df9393c46192964c5772b/Gemfile ```[ruby] - gem 'ably-rest', '~>0.9' + gem 'ably-rest', '~>1.0' ``` Then run the following command to install the required gems: @@ -180,7 +180,7 @@ First we need to ensure the Ably client library is loaded from our CDN. Add this ```[html] - + ``` From ebc38559c682117b021c383d1176f89eb3fa9ef1 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 8 Mar 2017 00:57:15 +0000 Subject: [PATCH 13/19] api: Fix incorrect old reference to non-specific version from CDN --- content/code/reactor/webhook-hmac-sha-256.code | 2 +- data/jsbins.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/code/reactor/webhook-hmac-sha-256.code b/content/code/reactor/webhook-hmac-sha-256.code index c17feb10e8..04eccbf278 100644 --- a/content/code/reactor/webhook-hmac-sha-256.code +++ b/content/code/reactor/webhook-hmac-sha-256.code @@ -26,7 +26,7 @@ $('#check-hmac-btn').on('click', function() { - +

Ably realtime WebHook HMAC validation example

diff --git a/data/jsbins.yaml b/data/jsbins.yaml index c75ad82d1a..a7b52efa6c 100644 --- a/data/jsbins.yaml +++ b/data/jsbins.yaml @@ -1,7 +1,6 @@ --- jsbin_hash: jQncq6OcBR6KCAsxnz3q5mit6m4=: uyuyap - pw5duE254r4vCBZRry9w8oUD4A4=: etazid crxhojzcwnL63vjgYuQNm0yYcqk=: avaper rf/oVbwi8uhndGbToJqYKG1sOIA=: onefuy HAlskL/HxlVrp85zn77PHOGKuz0=: upedip @@ -35,6 +34,7 @@ jsbin_hash: tFdUSLgmUuF6+xdeyztpD2RR6PI=: iburuq 3auIhOVQgxbiToyS78PwEpQ0caQ=: okipoh YuO2+EE7oigITwEqrbpZKS6sa38=: edalaf + x5ErWXOdxO5EL39sLQ99iZpkdKc=: ugisup jsbin_id: adapters/pusher-pub-sub: jQncq6OcBR6KCAsxnz3q5mit6m4= adapters/pubnub-pub-sub: YuO2+EE7oigITwEqrbpZKS6sa38= @@ -46,7 +46,7 @@ jsbin_id: client-lib-development-guide/example: EjhhGNY3f3dw55pyTen7hGEhUow= quick-start-guide/connect: d6fvP62mwfb3LX3MOzxPRwODVBU= quick-start-guide/send-message: bYp5xl1rMqBWZ/WK9Kx6+CxZ828= - reactor/webhook-hmac-sha-256: pw5duE254r4vCBZRry9w8oUD4A4= + reactor/webhook-hmac-sha-256: x5ErWXOdxO5EL39sLQ99iZpkdKc= realtime/auth-client-id: hNVfELEBYK20P4mzjqNcGsIzSHQ= realtime/auth-token-callback: viiNiyWEjefdf6NvWwEz4sleQ5w= realtime/channel-encrypted: 6Ovum/7TCpAi1/NnWL+XsaQtqzA= From a13ca5bf18bdfc4c446a916e142845b9755bb11b Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 8 Mar 2017 01:00:28 +0000 Subject: [PATCH 14/19] api: Fix LogLevel in .NET docs Fixes https://github.com/ably/docs/issues/244 --- content/types/_client_options.textile | 2 +- content/types/versions/v0.8/_client_options.textile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/types/_client_options.textile b/content/types/_client_options.textile index 15f6f3da43..0f8b4316f4 100644 --- a/content/types/_client_options.textile +++ b/content/types/_client_options.textile @@ -56,7 +56,7 @@ blang[java]. blang[csharp]. To set the log level and custom logger sink when using the .Net library, configure the static @IO.Ably.Logger@ class. - - LogLevel := _@Error@_ This is an enum controlling the verbosity of the output from Debug (maximum) to 2 (errors only). A special value of None will silence all logging. Note that the @LogLevel@ is a static variable in the library and will thus not act independently between library instances.
__Type: @Enum@__ + - LogLevel := _@Error@_ This is an enum controlling the verbosity of the output from @Debug@ (maximum) to @Error@ (errors only). A special value of @None@ will silence all logging. Note that the @LogLevel@ is a static variable in the library and will thus not act independently between library instances.
__Type: @Enum@__ - LoggerSink := _@IO.Ably.DefaultLoggerSink@_ The default ILoggerSink outputs messages to the debug console. This property allows the user to pipe the log messages to their own logging infrastructure. diff --git a/content/types/versions/v0.8/_client_options.textile b/content/types/versions/v0.8/_client_options.textile index a0ac085685..c86f9ff05c 100644 --- a/content/types/versions/v0.8/_client_options.textile +++ b/content/types/versions/v0.8/_client_options.textile @@ -56,7 +56,7 @@ blang[java]. blang[csharp]. To set the log level and custom logger sink when using the .Net library, configure the static @IO.Ably.Logger@ class. - - LogLevel := _@Error@_ This is an enum controlling the verbosity of the output from Debug (maximum) to 2 (errors only). A special value of None will silence all logging. Note that the @LogLevel@ is a static variable in the library and will thus not act independently between library instances.
__Type: @Enum@__ + - LogLevel := _@Error@_ This is an enum controlling the verbosity of the output from @Debug@ (maximum) to @Error@ (errors only). A special value of @None@ will silence all logging. Note that the @LogLevel@ is a static variable in the library and will thus not act independently between library instances.
__Type: @Enum@__ - LoggerSink := _@IO.Ably.DefaultLoggerSink@_ The default ILoggerSink outputs messages to the debug console. This property allows the user to pipe the log messages to their own logging infrastructure. From bbe732d13b504e3b2ec376620bdc854031e28c2f Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 8 Mar 2017 01:34:20 +0000 Subject: [PATCH 15/19] api: Make it clear which operations implicitly attach channels Fixes https://github.com/ably/docs/issues/236 --- content/realtime/channels-messages.textile | 13 ++++++++++--- content/realtime/presence.textile | 20 ++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/content/realtime/channels-messages.textile b/content/realtime/channels-messages.textile index 60ee88f2c6..38ddf7b5bb 100644 --- a/content/realtime/channels-messages.textile +++ b/content/realtime/channels-messages.textile @@ -859,7 +859,7 @@ bq(definition#publish-data). csharp: void Publish(string name, object data, Action callback = null, string clientId = null) objc,swift: publish(name: String?, data: AnyObject?, callback: (("ARTErrorInfo":/realtime/types#error-info?) -> Void)?) -Publish a single message on this channel based on a given event name and payload. A callbacklistener may optionally be passed in to this call to be notified of success or failure of the operation. +Publish a single message on this channel based on a given event name and payload. A callbacklistener may optionally be passed in to this call to be notified of success or failure of the operation. If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @publish@ will implicitly attach the channel. bq(definition#publish-msg-array). default: publish(Object[] messages, callback("ErrorInfo":/realtime/types#error-info err)) @@ -868,7 +868,7 @@ bq(definition#publish-msg-array). csharp: void Publish(IEnumerable<"Message":#message> messages, Action callback = null) objc,swift: publish(messages: [ "ARTMessage":#message ], callback: (("ARTErrorInfo":/realtime/types#error-info?) -> Void)?) -Publish several messages on this channel. A callbacklistenerblock may optionally be passed in to this call to be notified of success or failure of the operation. +Publish several messages on this channel. A callbacklistenerblock may optionally be passed in to this call to be notified of success or failure of the operation. If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @publish@ will implicitly attach the channel. h4. Parameters @@ -959,6 +959,12 @@ h4. Parameters -
callback
:= called with each matching "@message@":#message when received on the channel -
handler
:= called with each matching "@message@":#message when received on the channel +h4. Considerations + +* If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @subscribe@ will implicitly attach the channel. However, regardless of the implicit attach outcome, the listenerblockhandler will still be registered +* If @subscribe@ is called more than once with the same listenerblockhandler, then duplicates will be registered. For example, if you @subscribe@ twice with the same listenerblockhandler and a message is later received, the same listenerblockhandler will be invoked twice +* The registered listenerblockhandler remains active on the channel regardless of the current channel state. For example, if you call @subscribe@ when a channel is @attached@ and it later becomes @detached@ or even @failed@, when the channel is reattached and a message is received, the listenersblockshandlers originally registered will still be invoked. Listeners are only removed when calling "@unsubscribe@":#unsubscribe or when a channel is @released@ using the @Realtime.channels.release(name)@@Realtime.Channels.Release(name)@ method + h6(#unsubscribe). default: unsubscribe csharp: Unsubscribe @@ -1145,7 +1151,8 @@ Register the given listener blockChannelStateChangeARTChannelStateChange":#channel-state-change object that contains the current state, previous state, a boolean indicating whether the channel was resumed, and an optional reason for the state change.
-bq(definition). on(String[] events, listener("ChannelStateChange":#channel-state-change stateChange)) +bq(definition#on-state-array-listener). + jsall: on(String[] events, listener("ChannelStateChange":#channel-state-change stateChange)) Same as above, but registers multiple listeners, one for each event in the array.
diff --git a/content/realtime/presence.textile b/content/realtime/presence.textile index cdcef2b267..85971a7f73 100644 --- a/content/realtime/presence.textile +++ b/content/realtime/presence.textile @@ -569,7 +569,7 @@ bq(definition#enter-none). objc,swift: enter(data: nil, callback: ((ARTErrorInfo?) -> Void)?) csharp: Task EnterAsync() -Enter a presence channel without any data. +Enter a presence channel without any data. If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @enter@ will implicitly attach the channel. bq(definition#enter-data). default: enter(Object data, callback("ErrorInfo":/realtime/types#error-info err)) @@ -578,7 +578,7 @@ bq(definition#enter-data). objc,swift: enter(data: AnyObject?, callback: ((ARTErrorInfo?) -> Void)?) csharp: Task EnterAsync(object clientData) -Enter a presence channel and provide data that is associated with the current present member. +Enter a presence channel and provide data that is associated with the current present member. If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @enter@ will implicitly attach the channel. h4. Parameters @@ -695,7 +695,7 @@ bq(definition#update-data). swift,objc: update(data: AnyObject?, callback: ((ARTErrorInfo?) -> Void)?) csharp: Task UpdateAsync(object clientData) -Update the current member's data and broadcast an update event to all subscribers. @data@ may be @null@. +Update the current member's data and broadcast an update event to all subscribers. @data@ may be @null@. If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @update@ will implicitly attach the channel. h4. Parameters @@ -740,6 +740,8 @@ Get the current presence member set for this channel. Typically, this method ret When a channel is attached, the Ably service immediately synchronizes the presence member set with the client. Typically this process completes in milliseconds, however when the presence member set is very large, bandwidth constraints may slow this synchronization process down. +When a channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @get@ will implicitly attach the channel. + bq(definition). default: get(Object options, callback("ErrorInfo":/realtime/types#error-info err, "PresenceMessage[]":#presence-message members)) ruby: "Deferrable":/realtime/types#deferrable get(Hash options) -> yields "PresenceMessage[]":#presence-message @@ -899,6 +901,12 @@ h4. Parameters -
callback
:= called with each matching "@presence message@":#presence-message when received on the channel -
handler
:= called with each matching "@presence message@":#presence-message when received on the channel +h4. Considerations + +* If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @subscribe@ will implicitly attach the channel. However, regardless of the implicit attach outcome, the listenerblockhandler will still be registered +* If @subscribe@ is called more than once with the same listenerblockhandler, then duplicates will be registered. For example, if you @subscribe@ twice with the same listenerblockhandler and a presence message is later received, the same listenerblockhandler will be invoked twice +* The registered listenerblockhandler remains active on the presence channel regardless of the underlying channel state. For example, if you call @subscribe@ when the underlying channel is @attached@ and it later becomes @detached@ or even @failed@, when the channel is reattached and a presence message is received, the listenersblockshandlers originally registered will still be invoked. Listeners are only removed when calling "@unsubscribe@":#unsubscribe or when the underlying channel is @released@ using the @Realtime.channels.release(name)@@Realtime.Channels.Release(name)@ method + h6(#unsubscribe). default: unsubscribe csharp: Unsubscribe @@ -974,7 +982,7 @@ bq(definition#enter-client-none). objc,swift: enterClient(clientId: String, data: nil, callback: ((ARTErrorInfo?) -> Void)?) csharp: Task EnterClientAsync(string clientId, object clientData) -Enter a presence channel on behalf of the provided @clientId@@client_id@@ClientId@ without any data. +Enter a presence channel on behalf of the provided @clientId@@client_id@@ClientId@ without any data. If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @enter@ will implicitly attach the channel. bq(definition#enter-client-data). default: enterClient(String clientId, Object data, callback("ErrorInfo":/realtime/types#error-info err)) @@ -983,7 +991,7 @@ bq(definition#enter-client-data). objc,swift: enterClient(clientId: String, data: AnyObject?, callback: ((ARTErrorInfo?) -> Void)?) csharp: Task EnterClientAsync(string clientId, object clientData) -Enter a presence channel and provide data that is associated with the current present member. +Enter a presence channel and provide data that is associated with the current present member. If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @enter@ will implicitly attach the channel. h4. Parameters @@ -1103,7 +1111,7 @@ bq(definition#update-client-data). swift,objc: update(clientId: String, data: AnyObject?, callback: ((ARTErrorInfo?) -> Void)?) csharp: Task UpdateClientAsync(string clientId, object data) -Update the member data on behalf of the provided @clientId@@client_id@@ClientId@ and broadcast an update event to all subscribers. @data@ may be @null@. +Update the member data on behalf of the provided @clientId@@client_id@@ClientId@ and broadcast an update event to all subscribers. @data@ may be @null@. If the channel is @initialized@ (i.e. no attempt to attach has yet been made for this channel), then calling @enter@ will implicitly attach the channel. h4. Parameters From 9216cca758675b74ff2785394db5a308afd060c4 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 8 Mar 2017 02:32:42 +0000 Subject: [PATCH 16/19] api: Various .NET inconsistencies Fixes https://github.com/ably/docs/issues/247 Includes all mentioned updates at https://github.com/ably/ably-dotnet/pull/89 plus loads of unmentioned ones. --- content/realtime/_stats.textile | 6 ++-- content/realtime/channels-messages.textile | 17 +++++----- content/realtime/connection.textile | 2 +- content/realtime/encryption.textile | 2 +- content/realtime/history.textile | 26 ++++++++-------- content/realtime/presence.textile | 16 +++++----- content/realtime/statistics.textile | 10 +++--- content/realtime/types.textile | 18 +++++------ content/realtime/usage.textile | 2 +- content/realtime/versions/v0.8/_stats.textile | 6 ++-- .../versions/v0.8/channels-messages.textile | 31 ++++++++++--------- .../realtime/versions/v0.8/connection.textile | 2 +- .../realtime/versions/v0.8/encryption.textile | 2 +- .../realtime/versions/v0.8/history.textile | 26 ++++++++-------- .../realtime/versions/v0.8/presence.textile | 16 +++++----- .../realtime/versions/v0.8/statistics.textile | 10 +++--- content/realtime/versions/v0.8/types.textile | 18 +++++------ content/realtime/versions/v0.8/usage.textile | 2 +- content/rest/_stats.textile | 6 ++-- content/rest/channels-messages.textile | 8 ++--- content/rest/history.textile | 16 +++++----- content/rest/presence.textile | 10 +++--- content/rest/statistics.textile | 10 +++--- content/rest/types.textile | 16 +++++----- content/rest/usage.textile | 2 +- content/rest/versions/v0.8/_stats.textile | 6 ++-- .../versions/v0.8/channels-messages.textile | 8 ++--- content/rest/versions/v0.8/history.textile | 16 +++++----- content/rest/versions/v0.8/presence.textile | 10 +++--- content/rest/versions/v0.8/statistics.textile | 10 +++--- content/rest/versions/v0.8/types.textile | 16 +++++----- content/rest/versions/v0.8/usage.textile | 2 +- content/types/_client_options.textile | 2 +- .../types/_connection_state_change.textile | 4 +-- content/types/_error_info.textile | 6 ++-- ...extile => _history_request_params.textile} | 2 +- content/types/_message.textile | 14 ++++----- content/types/_presence_message.textile | 14 ++++----- ....textile => _stats_request_params.textile} | 4 +-- .../versions/v0.8/_client_options.textile | 2 +- .../v0.8/_connection_state_change.textile | 4 +-- .../types/versions/v0.8/_error_info.textile | 6 ++-- ...extile => _history_request_params.textile} | 2 +- content/types/versions/v0.8/_message.textile | 14 ++++----- .../versions/v0.8/_presence_message.textile | 14 ++++----- ....textile => _stats_request_params.textile} | 4 +-- 46 files changed, 221 insertions(+), 219 deletions(-) rename content/types/{_data_request_query.textile => _history_request_params.textile} (71%) rename content/types/{_stats_data_request_query.textile => _stats_request_params.textile} (73%) rename content/types/versions/v0.8/{_data_request_query.textile => _history_request_params.textile} (71%) rename content/types/versions/v0.8/{_stats_data_request_query.textile => _stats_request_params.textile} (73%) diff --git a/content/realtime/_stats.textile b/content/realtime/_stats.textile index cda03454cc..101f0cf250 100644 --- a/content/realtime/_stats.textile +++ b/content/realtime/_stats.textile @@ -1,12 +1,12 @@ h4. Parameters -- optionsquery := an optional objectHash@ARTStatsQuery@@StatsDataRequestQuery@"@Param@":#param[] array containing the query parameters +- optionsquery := an optional objectHash@ARTStatsQuery@@StatsRequestParams@"@Param@":#param[] array containing the query parameters -
callback
:= is a function of the form: @function(err, result)@ -
&block
:= yields a @PaginatedResult@ array -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTStats":/rest/types#stats> object or an error -h4. @options@ parameters@ARTStatsQuery@ properties@StatsDataRequestQuery@ properties +h4. @options@ parameters@ARTStatsQuery@ properties@StatsRequestParams@ properties The following options, as defined in the "REST @/stats@ API":/rest-api#stats endpoint, are permitted: @@ -14,7 +14,7 @@ The following options, as defined in the "REST @/stats@ API":/rest-api#stats end - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any stats retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - direction:directionDirection := _backwards_ @:@@forwards@ or @:@@backwards@
__Type: @String@@Symbol@@Direction@ enum__ - limit:limitLimit := _100_ maximum number of stats to retrieve up to 1,000
__Type: @Integer@__ -- unit:unitUnit := _minute_ @:@@minute@, @:@@hour@, @:@@day@ or @:@@month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @String@"@ARTStatsGranularity@":#stats-granularity@Symbol@@StatsBy@ enum__ +- unit:unitUnit := _minute_ @:@@minute@, @:@@hour@, @:@@day@ or @:@@month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @String@"@ARTStatsGranularity@":#stats-granularity@Symbol@@StatsIntervalGranularity@ enum__ blang[jsall,objc,swift]. h4. Callback result diff --git a/content/realtime/channels-messages.textile b/content/realtime/channels-messages.textile index 38ddf7b5bb..b53b8338da 100644 --- a/content/realtime/channels-messages.textile +++ b/content/realtime/channels-messages.textile @@ -146,7 +146,7 @@ ChannelOptions options = new ChannelOptions(); options.cipher = params; Channel channel = realtime.channels.get("channelName", options); -bc[csharp]. byte[] key = Crypto.GetRandomKey(); +bc[csharp]. byte[] key = Crypto.GenerateRandomKey(); var cipherParams = Crypto.GetDefaultParams(key); var channelOpts = new ChannelOptions(cipherParams); var encryptedChannel = realtime.Channels.Get("channelName", channelOpts); @@ -720,7 +720,7 @@ if(resultPage.hasNext()) { System.out.println(nextPage.items().length + " messages received in second page"); } -bc[csharp]. var history = await channel.HistoryAsync(untilAttached: true); +bc[csharp]. var history = await channel.HistoryAsync(untilAttach: true); Console.WriteLine($"{history.Items.Count} messages received in the first page"); if (history.HasNext) { @@ -830,7 +830,8 @@ h6(#error-reason). ruby: error_reason csharp: ErrorReason -When a channel failure occurs this attributememberproperty contains the "@AblyException@":/realtime/types#ably-exception"@ErrorInfo@":/realtime/types#error-info. +When a channel failure occurs this attributememberpropertyproperty is populated. +The type is "@ErrorInfo@":/realtime/types#error-info"@AblyException@":/realtime/types#ably-exception. h6(#name). default: name @@ -1029,14 +1030,14 @@ bq(definition). default: history(Object options, callback("ErrorInfo":/realtime/types#error-info err, "PaginatedResult":#paginated-result<"Message":#message> resultPage)) ruby: "Deferrable":/realtime/types#deferrable history(Hash options) -> yields "PaginatedResult":#paginated-result<"Message":#message> java: "PaginatedResult":#paginated-result<"Message":#message> history("Param []":#param options) - csharp: Task<"PaginatedResult":#paginated-result> HistoryAsync("DataRequestQuery":#data-request-query dataQuery, bool untilAttached = false) + csharp: Task<"PaginatedResult":#paginated-result> HistoryAsync("HistoryRequestParams":#history-request-params dataQuery, bool untilAttach = false) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTMessage":#message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical messages for this channel. If the "channel is configured to persist messages to disk":https://support.ably.io/support/solutions/articles/3000030059-how-long-are-messages-stored-for, then message history will "typically be available for 24 - 72 hours":https://support.ably.io/solution/articles/3000030059-how-long-are-messages-stored-for. If not, messages are only retained in memory by the Ably service for two minutes. h4. Parameters -- optionsquerydataQuery := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified in the "message history API documentation":/realtime/history#channel-history.
__Type: @Object@@ARTRealtimeHistoryQuery@@DataRequestQuery@@Hash@"@Param []@":#param__ +- optionsquerydataQuery := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified in the "message history API documentation":/realtime/history#channel-history.
__Type: @Object@@ARTRealtimeHistoryQuery@@HistoryRequestParams@@Hash@"@Param []@":#param__ -
callback
:= is a function of the form: @function(err, resultPage)@ -
&block
:= yields a @PaginatedResult@ array @@ -1342,11 +1343,11 @@ h3(#completion-listener). blang[java]. <%= partial 'types/_completion_listener', indent: 2, skip_first_indent: true %> -h3(#data-request-query). - csharp: DataRequestQuery +h3(#history-request-params). + csharp: HistoryRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#message-listener). java: io.ably.lib.realtime.Channel.MessageListener diff --git a/content/realtime/connection.textile b/content/realtime/connection.textile index 4beebcedd5..c756d468ac 100644 --- a/content/realtime/connection.textile +++ b/content/realtime/connection.textile @@ -693,7 +693,7 @@ h3(#connection-state-change). objc,swift: ARTConnectionStateChange java: io.ably.lib.realtime.ConnectionStateListener.ConnectionStateChange ruby: ConnectionStateChange - csharp: IO.Ably.Realtime.ConnectionStateChangedEventArgs + csharp: IO.Ably.Realtime.ConnectionStateChange <%= partial 'types/_connection_state_change' %> diff --git a/content/realtime/encryption.textile b/content/realtime/encryption.textile index aa5b389e34..91fd9631ab 100644 --- a/content/realtime/encryption.textile +++ b/content/realtime/encryption.textile @@ -62,7 +62,7 @@ h2(#getting-started). Getting started ``` ```[csharp] - var key = Crypto.GetRandomKey(); + var key = Crypto.GenerateRandomKey(); var options = new ChannelOptions(key); var channel = realtime.Channels.Get("{{RANDOM_CHANNEL_NAME}}", options); channel.Subscribe(message => { diff --git a/content/realtime/history.textile b/content/realtime/history.textile index 722133fa89..563f909207 100644 --- a/content/realtime/history.textile +++ b/content/realtime/history.textile @@ -127,7 +127,7 @@ h3(#continuous-history). Continuous history It is possible to obtain message history that is continuous with the realtime messages received on an attached channel, in the backwards direction from the point of attachment. When a @Channel@ instance is attached, it's automatically populated by the Ably service with the serial number of the last published message on the channel. As such, using this serial number, the client library is able to make a history request to the Ably service for all messages received since the channel was attached. Any new messages therefore are received in realtime via the attached channel, and any historical messages are accessible via the history method. -In order to benefit from this functionality, the @untilAttach@@untilAttached@ option can be used when making history requests on attached channels. If the channel is not yet attached, this will result in an error. +In order to benefit from this functionality, the @untilAttach@ option can be used when making history requests on attached channels. If the channel is not yet attached, this will result in an error. ```[jsall](code-editor:realtime/channel-history-until-attach) var realtime = new Ably.Realtime('{{API_KEY}}'); @@ -170,7 +170,7 @@ In order to benefit from this functionality, the @untilAtta var realtime = new AblyRealtime("{{API_KEY}}"); var channel = realtime.Channels.Get("{{RANDOM_CHANNEL_NAME}}"); await channel.AttachAsync(); - PaginatedResult resultPage = await channel.HistoryAsync(untilAttached: true); + PaginatedResult resultPage = await channel.HistoryAsync(untilAttach: true); Message lastMessage = resultPage.Items[0]; Console.WriteLine("Last message before attach: " + lastMessage.data); ``` @@ -233,25 +233,25 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable history(Hash option) -> yields "PaginatedResult":#paginated-result<"Message":#message> java: "PaginatedResult":#paginated-result<"Message":#message> history("Param":#param[] option) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTMessage":#message>?, ARTErrorInfo?) -> Void) throws - csharp: Task> HistoryAsync("DataRequestQuery":#data-request-query dataQuery, bool untilAttached = false); + csharp: Task> HistoryAsync("HistoryRequestParams":#history-request-params dataQuery, bool untilAttach = false); Gets a "paginated":#paginated-result set of historical messages for this channel. h4. Parameters -- optionquery"Param":#param[] option"DataRequestQuery":#data-request-query query := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified below. +- optionquery"Param":#param[] option"HistoryRequestParams":#history-request-params query := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified below. -
callback
:= is a function of the form: @function(err, resultPage)@ -
&block
:= yields a @PaginatedResult@ array -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTMessage":#message> object or an error -h4. @options@ parameters@ARTRealtimeHistoryQuery@ properties"@DataRequestQuery@":#data-request-query properties +h4. @options@ parameters@ARTRealtimeHistoryQuery@ properties"@HistoryRequestParams@":#history-request-params properties - start:startStart := _beginning of time_ earliest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any messages retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any messages retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - direction:directionDirection := _backwards_ @:@@forwards@ or @:@@backwards@
__Type: @String@@Symbol@@Direction@ enum__ - limit:limitLimit := _100_ maximum number of messages to retrieve up to 1,000
__Type: @Integer@__ -- untilAttach:until_attachuntilAttached := _false_ when true, ensures message history is up until the point of the channel being attached. See "continuous history":#continuous-history for more info. If the @Channel@ is not attached, enabling this option will result in error
__Type: @Boolean@__ +- untilAttach:until_attach := _false_ when true, ensures message history is up until the point of the channel being attached. See "continuous history":#continuous-history for more info. If the @Channel@ is not attached, enabling this option will result in error
__Type: @Boolean@__ blang[jsall,objc,swift]. h4. Callback result @@ -300,25 +300,25 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable history(Hash option) -> yields "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> java: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history("Param":#param[] option) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message>?, ARTErrorInfo?) -> Void) throws - csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("DataRequestQuery":#data-request-query query, bool untilAttached = false) + csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("HistoryRequestParams":#history-request-params query, bool untilAttach = false) Gets a "paginated":#paginated-result set of historical presence events for this channel. h4. Parameters -- optionquery"Param":#param[] option"DataRequestQuery":#data-request-query query := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified below. +- optionquery"Param":#param[] option"HistoryRequestParams":#history-request-params query := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified below. -
callback
:= is a function of the form: @function(err, resultPage)@ -
&block
:= yields a @PaginatedResult@ array -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message> object or an error -h4. @options@ parameters@ARTRealtimeHistoryQuery@ properties"@DataRequestQuery@":#data-request-query properties +h4. @options@ parameters@ARTRealtimeHistoryQuery@ properties"@HistoryRequestParams@":#history-request-params properties - start:startStart := _beginning of time_ earliest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any presence events retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any presence events retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - direction:directionDirection := _backwards_ @:@@forwards@ or @:@@backwards@
__Type: @String@@Symbol@@Direction@ enum__ - limit:limitLimit := _100_ maximum number of presence events to retrieve up to 1,000
__Type: @Integer@__ -- untilAttach:until_attachuntilAttached := _false_ when true, ensures presence event history is up until the point of the channel being attached. See "continuous history":#continuous-history for more info. If the @Channel@ is not attached, enabling this option will result in error
__Type: @Boolean@__ +- untilAttach:until_attach := _false_ when true, ensures presence event history is up until the point of the channel being attached. See "continuous history":#continuous-history for more info. If the @Channel@ is not attached, enabling this option will result in error
__Type: @Boolean@__ blang[jsall,objc,swift]. h4. Callback result @@ -381,11 +381,11 @@ h3(#presence-action). <%= partial 'types/_presence_action' %> -h3(#data-request-query). - csharp: IO.Ably.DataRequestQuery +h3(#history-request-params). + csharp: IO.Ably.HistoryRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#paginated-result). default: PaginatedResult diff --git a/content/realtime/presence.textile b/content/realtime/presence.textile index 85971a7f73..f90442d965 100644 --- a/content/realtime/presence.textile +++ b/content/realtime/presence.textile @@ -342,7 +342,7 @@ if(resultPage.hasNext()) { ```[csharp] PaginatedResult resultPage; -resultPage = await channel.Presence.HistoryAsync(untilAttached: true); +resultPage = await channel.Presence.HistoryAsync(untilAttach: true); Console.WriteLine(resultPage.Items.Count + " presence events received in first page"); if (resultPage.HasNext) { @@ -747,7 +747,7 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable get(Hash options) -> yields "PresenceMessage[]":#presence-message java: "PresenceMessage[]":#presence-message get("Param":#param[] options) swift,objc: get(query: ARTRealtimePresenceQuery, callback: (["ARTPresenceMessage":#presence-message], ARTErrorInfo?) -> Void) - csharp: Task> GetAsync(bool waitForSync = true, string clientId = "", string connectionId = "") + csharp: Task> GetAsync(GetOptions { bool waitForSync = true, string clientId = "", string connectionId = "" }) Gets an array of members present on the channel as "PresenceMessage":#presence-message objects. @@ -760,7 +760,7 @@ blang[jsall,ruby,java,swift,objc]. -
&block
:= yields a "@PresenceMessage[]@":#presence-message array -
callback
:= called with a "@[ARTPresenceMessage]@":#presence-message, or with an error -h4. @options@ parameters@ARTRealtimePresenceQuery@ propertiesArguments +h4. @options@ parameters@ARTRealtimePresenceQuery@ properties@GetOptions@ properties - clientId:client_id := when provided, will filter array of members returned that match the provided "@clientId@":/realtime/usage#client-id"@client_id@":/realtime/usage#client-id"@ClientId@":/realtime/usage#client-id string - connectionId:connection_id := when provided, will filter array of members returned that match the provided @connectionId@@ConnectionId@@connection_id@":/realtime/connection/#id string @@ -805,14 +805,14 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable history(Hash options) -> yields "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> java: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history("Param":#param[] options) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message>?, ARTErrorInfo?) -> Void) throws - csharp: Task> HistoryAsync("DataRequestQuery":#data-request-query query, bool untilAttached = false) + csharp: Task> HistoryAsync("HistoryRequestParams":#history-request-params query, bool untilAttach = false) Gets a "paginated":#paginated-result set of historical presence message events for this channel. If the "channel is configured to persist messages to disk":https://support.ably.io/support/solutions/articles/3000030059-how-long-are-messages-stored-for, then the presence message event history will "typically be available for 24 - 72 hours":https://support.ably.io/solution/articles/3000030059-how-long-are-messages-stored-for. If not, presence message events are only retained in memory by the Ably service for two minutes. h4. Parameters -- optionsquery"Param":#param[] options"DataRequestQuery":#data-request-query query := an optional object containing query parametersan optional set of key value pairs containing query parameters, as specified in the "presence history API documentation":/realtime/history#presence-history. +- optionsquery"Param":#param[] options"HistoryRequestParams":#history-request-params query := an optional object containing query parametersan optional set of key value pairs containing query parameters, as specified in the "presence history API documentation":/realtime/history#presence-history. -
callback
:= is a function of the form: @function(err, resultPage)@ -
&block
:= yields a @PaginatedResult@ array @@ -1170,11 +1170,11 @@ h3(#presence-action). <%= partial 'shared/_presence_from_encoded' %> -h3(#data-request-query). - csharp: DataRequestQuery +h3(#history-request-params). + csharp: HistoryRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#completion-listener). java: io.ably.lib.realtime.CompletionListener diff --git a/content/realtime/statistics.textile b/content/realtime/statistics.textile index 2fe882c068..8229c2eebb 100644 --- a/content/realtime/statistics.textile +++ b/content/realtime/statistics.textile @@ -56,7 +56,7 @@ The Ably Realtime client library provides a straightforward API for retrieving a ```[csharp] var realtime = new AblyRealtime("{{API_KEY}}"); - var query = new StatsDataRequestQuery() { By = StatsBy.Hour }; + var query = new StatsRequestParams() { By = StatsIntervalGranularity.Hour }; var results = await realtime.StatsAsync(query); Stats thisHour = results.Items[0]; Console.WriteLine("Published this hour " + thisHour.Inbound.All.All); @@ -93,7 +93,7 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable stats(Hash options) -> yields "PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#stats> java: "PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#stats-type> stats("Param":#param[] options) swift,objc: stats(query: ARTStatsQuery?, callback: ("ARTPaginatedResult":/realtime/types#paginated-result<"ARTStats":/realtime/types#stats>?, ARTErrorInfo?) -> Void) throws - csharp: Task<"PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#status>> StatsAsync("StatsDataRequestQuery":#statsdatarequest query) + csharp: Task<"PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#status>> StatsAsync("StatsRequestParams":#statsdatarequest query) This call queries the "REST @/stats@ API":/rest-api#stats-type and retrieves your application's usage statistics. A "PaginatedResult":/realtime/types#paginated-result is returned, containing an array of "Stats":/realtime/types#stats-type for the first page of results. "PaginatedResult":/realtime/types#paginated-result objects are iterable providing a means to page through historical statistics. "See an example set of raw stats returned via the REST API":/general/statistics. @@ -110,11 +110,11 @@ h3(#stats-type). <%= partial 'types/_stats' %> -h3(#stats-data-request-query). - csharp: IO.Ably.StatsDataRequestQuery +h3(#stats-request-params). + csharp: IO.Ably.StatsRequestParams blang[csharp]. - <%= partial 'types/_stats_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#stats-granularity). objc,swift: ARTStatsGranularity diff --git a/content/realtime/types.textile b/content/realtime/types.textile index 2fa682c606..d493ffcb91 100644 --- a/content/realtime/types.textile +++ b/content/realtime/types.textile @@ -37,12 +37,12 @@ jump_to: - Connection State#connection-event - Connection State Listener - Connection State Change - - Data Request Query + - History Request Params - Deferrable - LastConnnectionDetails#last-connection-details - Message Listener - Presence Listener - - Stats Data Request Query + - Stats Request Params - Token Params --- @@ -253,15 +253,15 @@ h3(#connection-state-change). objc,swift: ARTConnectionStateChange ruby: ConnectionStateChange java: io.ably.lib.realtime.ConnectionStateListener.ConnectionStateChange - csharp: IO.Ably.Realtime.ConnectionStateChangedEventArgs + csharp: IO.Ably.Realtime.ConnectionStateChange <%= partial 'types/_connection_state_change' %> -h3(#data-request-query). - csharp: IO.Ably.DataRequestQuery +h3(#history-request-params). + csharp: IO.Ably.HistoryRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#message-listener). java: io.ably.lib.realtime.Channel.MessageListener @@ -287,11 +287,11 @@ blang[ruby]. <%= partial 'types/_deferrable', indent: 2, skip_first_indent: true %> -h3(#stats-data-request-query). - csharp: IO.Ably.StatsDataRequestQuery +h3(#stats-request-params). + csharp: IO.Ably.StatsRequestParams blang[csharp]. - <%= partial 'types/_stats_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#token-params). default: TokenParams Object diff --git a/content/realtime/usage.textile b/content/realtime/usage.textile index 96d31f2227..679f7629bf 100644 --- a/content/realtime/usage.textile +++ b/content/realtime/usage.textile @@ -320,7 +320,7 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable stats(Hash options) -> yields "PaginatedResult":/realtime/types#paginated-result<"Stats":#stats> java: "PaginatedResult":/realtime/types#paginated-result<"Stats":#stats> stats("Param":#param[] options) swift,objc: stats(query: ARTStatsQuery?, callback: ("ARTPaginatedResult":/realtime/types#paginated-result<"ARTStats":/realtime/types#stats>?, ARTErrorInfo?) -> Void) throws - csharp: Task<"PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#stats>> StatsAsync(StatsDataRequestQuery query) + csharp: Task<"PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#stats>> StatsAsync(StatsRequestParams query) This call queries the "REST @/stats@ API":/rest-api#stats and retrieves your application's usage statistics. A "PaginatedResult":/realtime/types#paginated-result is returned, containing an array of "Stats":#stats for the first page of results. "PaginatedResult":/realtime/types#paginated-result objects are iterable providing a means to page through historical statistics. "See an example set of raw stats returned via the REST API":/general/statistics. diff --git a/content/realtime/versions/v0.8/_stats.textile b/content/realtime/versions/v0.8/_stats.textile index cda03454cc..101f0cf250 100644 --- a/content/realtime/versions/v0.8/_stats.textile +++ b/content/realtime/versions/v0.8/_stats.textile @@ -1,12 +1,12 @@ h4. Parameters -- optionsquery := an optional objectHash@ARTStatsQuery@@StatsDataRequestQuery@"@Param@":#param[] array containing the query parameters +- optionsquery := an optional objectHash@ARTStatsQuery@@StatsRequestParams@"@Param@":#param[] array containing the query parameters -
callback
:= is a function of the form: @function(err, result)@ -
&block
:= yields a @PaginatedResult@ array -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTStats":/rest/types#stats> object or an error -h4. @options@ parameters@ARTStatsQuery@ properties@StatsDataRequestQuery@ properties +h4. @options@ parameters@ARTStatsQuery@ properties@StatsRequestParams@ properties The following options, as defined in the "REST @/stats@ API":/rest-api#stats endpoint, are permitted: @@ -14,7 +14,7 @@ The following options, as defined in the "REST @/stats@ API":/rest-api#stats end - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any stats retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - direction:directionDirection := _backwards_ @:@@forwards@ or @:@@backwards@
__Type: @String@@Symbol@@Direction@ enum__ - limit:limitLimit := _100_ maximum number of stats to retrieve up to 1,000
__Type: @Integer@__ -- unit:unitUnit := _minute_ @:@@minute@, @:@@hour@, @:@@day@ or @:@@month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @String@"@ARTStatsGranularity@":#stats-granularity@Symbol@@StatsBy@ enum__ +- unit:unitUnit := _minute_ @:@@minute@, @:@@hour@, @:@@day@ or @:@@month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @String@"@ARTStatsGranularity@":#stats-granularity@Symbol@@StatsIntervalGranularity@ enum__ blang[jsall,objc,swift]. h4. Callback result diff --git a/content/realtime/versions/v0.8/channels-messages.textile b/content/realtime/versions/v0.8/channels-messages.textile index d9087a69de..165b1037b3 100644 --- a/content/realtime/versions/v0.8/channels-messages.textile +++ b/content/realtime/versions/v0.8/channels-messages.textile @@ -144,7 +144,7 @@ ChannelOptions options = new ChannelOptions(); options.cipher = params; Channel channel = realtime.channels.get("channelName", options); -bc[csharp]. byte[] key = Crypto.GetRandomKey(); +bc[csharp]. byte[] key = Crypto.GenerateRandomKey(); var cipherParams = Crypto.GetDefaultParams(key); var channelOpts = new ChannelOptions(cipherParams); var encryptedChannel = realtime.Channels.Get("channelName", channelOpts); @@ -661,7 +661,7 @@ if(resultPage.hasNext()) { System.out.println(nextPage.items().length + " messages received in second page"); } -bc[csharp]. var history = await channel.HistoryAsync(untilAttached: true); +bc[csharp]. var history = await channel.HistoryAsync(untilAttach: true); Console.WriteLine($"{history.Items.Count} messages received in the first page"); if (history.HasNext) { @@ -771,7 +771,8 @@ h6(#error-reason). ruby: error_reason csharp: ErrorReason -When a channel failure occurs this attributememberproperty contains the "@AblyException@":/realtime/types#ably-exception"@ErrorInfo@":/realtime/types#error-info. +When a channel failure occurs this attributememberpropertyproperty is populated. +The type is "@ErrorInfo@":/realtime/types#error-info"@AblyException@":/realtime/types#ably-exception. h6(#name). default: name @@ -950,14 +951,14 @@ bq(definition). default: history(Object options, callback("ErrorInfo":/realtime/types#error-info err, "PaginatedResult":#paginated-result<"Message":#message> resultPage)) ruby: "Deferrable":/realtime/types#deferrable history(Hash options) -> yields "PaginatedResult":#paginated-result<"Message":#message> java: "PaginatedResult":#paginated-result<"Message":#message> history("Param []":#param options) - csharp: Task<"PaginatedResult":#paginated-result> HistoryAsync("DataRequestQuery":#data-request-query dataQuery, bool untilAttached = false) + csharp: Task<"PaginatedResult":#paginated-result> HistoryAsync("HistoryRequestParams":#history-request-params dataQuery, bool untilAttach = false) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTMessage":#message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical messages for this channel. If the "channel is configured to persist messages to disk":https://support.ably.io/support/solutions/articles/3000030059-how-long-are-messages-stored-for, then message history will "typically be available for 24 - 72 hours":https://support.ably.io/solution/articles/3000030059-how-long-are-messages-stored-for. If not, messages are only retained in memory by the Ably service for two minutes. h4. Parameters -- optionsquerydataQuery := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified in the "message history API documentation":/realtime/history#channel-history.
__Type: @Object@@ARTRealtimeHistoryQuery@@DataRequestQuery@@Hash@"@Param []@":#param__ +- optionsquerydataQuery := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified in the "message history API documentation":/realtime/history#channel-history.
__Type: @Object@@ARTRealtimeHistoryQuery@@HistoryRequestParams@@Hash@"@Param []@":#param__ -
callback
:= is a function of the form: @function(err, resultPage)@ -
&block
:= yields a @PaginatedResult@ array @@ -1065,7 +1066,7 @@ bq(definition#on-state-listener). default: on(String state, listener()) ruby: on("ChannelState":#channel-state *state) -> yields "ChannelStateChange":#channel-state-change java: void on("ChannelState":#channel-state state, "ChannelStateListener":#channel-state-listener listener) - csharp: void On("ChannelState":#channel-state event, Action action) + csharp: void On("ChannelState":#channel-state state, Action action) objc,swift: on(event: "ARTChannelEvent":#channel-event, call: ("ARTErrorInfo":#error-info?) -> Void) -> ARTEventListener Register the given listener blockfunction for the specified "ChannelState":#channel-state @state@@state(s)@ changes on the @Channel@. @@ -1074,7 +1075,7 @@ Register the given listener block listener) + csharp: void On(Action listener) java: void on("ChannelStateListener":#channel-state-listener listener) objc,swift: on(call: (ARTErrorInfo?) -> Void) -> ARTEventListener @@ -1091,7 +1092,7 @@ h4. Parameters -
listener
:= is a function of the form @function()@ to be notified for matching state changes. The current state is available as @this.event@ -
listener
:= listener to be notified for matching state changes
__Type: "@ChannelStateListener@":#channel-state-listener__ --
action
:= lambda expression to be notified for matching state changes
__Type: "@ChannelStateChangedEventArgs@":#channel-state-listener__ +-
action
:= lambda expression to be notified for matching state changes
__Type: "@ChannelStateChange@":#channel-state-listener__ -
&block
:= listener block that is yielded to for matching state changes -
call
:= called possibly with an "@ErrorInfo@":#error-info @@ -1109,7 +1110,7 @@ bq(definition#once-state-listener). default: once(String state, listener()) ruby: once("ChannelState":#channel-state *state) -> yields "ChannelStateChange":#channel-state-change java: void once("ChannelState":#channel-state state, "ChannelStateListener":#channel-state-listener listener) - csharp: void Once("ChannelState":#channel-state event, Action action) + csharp: void Once("ChannelState":#channel-state state, Action action) objc,swift: once(event: "ARTChannelEvent":#channel-event, call: ("ARTErrorInfo":#error-info?) -> Void) -> ARTEventListener Register the given listener blockfunctionlambda expression for a single occurrence of the specified "ChannelState":#channel-state @state@@state(s)@@state@ change on the @Channel@. Once the listener has been called, it is removed as a registered listener and will not be called again. @@ -1119,7 +1120,7 @@ bq(definition#once-listener). default: once(listener()) ruby: once -> yields "ChannelStateChange":#channel-state-change java: void once("ChannelStateListener":#channel-state-listener listener) - csharp: void Once(Action listener) + csharp: void Once(Action listener) objc,swift: once(call: (ARTErrorInfo?) -> Void) -> ARTEventListener Register the given listener blockfunctionlambda expression for a single occurrence of any "ChannelState":#channel-state change on the @Channel@. Once the listener has been called, it is removed as a registered listener and will not be called again. @@ -1149,7 +1150,7 @@ bq(definition#off-state-listener). default: off(String state, listener) ruby: off("ChannelState":#channel-state *state, &block) java: void off("ChannelState":#channel-state state, "ChannelStateListener":#channel-state-listener listener) - csharp: void Off("ChannelState":#channel-state event, Action listener) + csharp: void Off("ChannelState":#channel-state state, Action listener) objc,swift: off(event: "ARTChannelEvent":#channel-event, listener: ARTEventListener) Remove the given listener block for the "ChannelState":#channel-state @state@@state(s)@. @@ -1158,7 +1159,7 @@ bq(definition#off-listener). default: off(listener) ruby: off(&block) java: void off("ChannelStateListener":#channel-state-listener listener) - csharp: void Off(Action listener) + csharp: void Off(Action listener) objc,swift: off(listener: ARTEventListener) Remove the given listener block for all "ChannelState":#channel-state states. @@ -1230,11 +1231,11 @@ h3(#completion-listener). blang[java]. <%= partial 'types/versions/v0.8/_completion_listener', indent: 2, skip_first_indent: true %> -h3(#data-request-query). - csharp: DataRequestQuery +h3(#history-request-params). + csharp: HistoryRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_history_request_params', indent: 2, skip_first_indent: true %> h3(#message-listener). java: io.ably.lib.realtime.Channel.MessageListener diff --git a/content/realtime/versions/v0.8/connection.textile b/content/realtime/versions/v0.8/connection.textile index 208cd87751..35f4263f1c 100644 --- a/content/realtime/versions/v0.8/connection.textile +++ b/content/realtime/versions/v0.8/connection.textile @@ -652,7 +652,7 @@ h3(#connection-state-change). objc,swift: ARTConnectionStateChange java: io.ably.lib.realtime.ConnectionStateListener.ConnectionStateChange ruby: ConnectionStateChange - csharp: IO.Ably.Realtime.ConnectionStateChangedEventArgs + csharp: IO.Ably.Realtime.ConnectionStateChange <%= partial 'types/versions/v0.8/_connection_state_change' %> diff --git a/content/realtime/versions/v0.8/encryption.textile b/content/realtime/versions/v0.8/encryption.textile index 2f31eafbc6..d915af49b3 100644 --- a/content/realtime/versions/v0.8/encryption.textile +++ b/content/realtime/versions/v0.8/encryption.textile @@ -62,7 +62,7 @@ h2(#getting-started). Getting started ``` ```[csharp] - var key = Crypto.GetRandomKey(); + var key = Crypto.GenerateRandomKey(); var options = new ChannelOptions(key); var channel = realtime.Channels.Get("{{RANDOM_CHANNEL_NAME}}", options); channel.Subscribe(message => { diff --git a/content/realtime/versions/v0.8/history.textile b/content/realtime/versions/v0.8/history.textile index 0e8991d857..7bc40c5c0f 100644 --- a/content/realtime/versions/v0.8/history.textile +++ b/content/realtime/versions/v0.8/history.textile @@ -123,7 +123,7 @@ h3(#continuous-history). Continuous history It is possible to obtain message history that is continuous with the realtime messages received on an attached channel, in the backwards direction from the point of attachment. When a @Channel@ instance is attached, it's automatically populated by the Ably service with the serial number of the last published message on the channel. As such, using this serial number, the client library is able to make a history request to the Ably service for all messages received since the channel was attached. Any new messages therefore are received in realtime via the attached channel, and any historical messages are accessible via the history method. -In order to benefit from this functionality, the @untilAttach@@untilAttached@ option can be used when making history requests on attached channels. If the channel is not yet attached, this will result in an error. +In order to benefit from this functionality, the @untilAttach@ option can be used when making history requests on attached channels. If the channel is not yet attached, this will result in an error. ```[jsall](code-editor:realtime/channel-history-until-attach) var realtime = new Ably.Realtime('{{API_KEY}}'); @@ -166,7 +166,7 @@ In order to benefit from this functionality, the @untilAtta var realtime = new AblyRealtime("{{API_KEY}}"); var channel = realtime.Channels.Get("{{RANDOM_CHANNEL_NAME}}"); await channel.AttachAsync(); - PaginatedResult resultPage = await channel.HistoryAsync(untilAttached: true); + PaginatedResult resultPage = await channel.HistoryAsync(untilAttach: true); Message lastMessage = resultPage.Items[0]; Console.WriteLine("Last message before attach: " + lastMessage.data); ``` @@ -229,25 +229,25 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable history(Hash option) -> yields "PaginatedResult":#paginated-result<"Message":#message> java: "PaginatedResult":#paginated-result<"Message":#message> history("Param":#param[] option) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTMessage":#message>?, ARTErrorInfo?) -> Void) throws - csharp: Task> HistoryAsync("DataRequestQuery":#data-request-query dataQuery, bool untilAttached = false); + csharp: Task> HistoryAsync("HistoryRequestParams":#history-request-params dataQuery, bool untilAttach = false); Gets a "paginated":#paginated-result set of historical messages for this channel. h4. Parameters -- optionquery"Param":#param[] option"DataRequestQuery":#data-request-query query := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified below. +- optionquery"Param":#param[] option"HistoryRequestParams":#history-request-params query := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified below. -
callback
:= is a function of the form: @function(err, resultPage)@ -
&block
:= yields a @PaginatedResult@ array -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTMessage":#message> object or an error -h4. @options@ parameters@ARTRealtimeHistoryQuery@ properties"@DataRequestQuery@":#data-request-query properties +h4. @options@ parameters@ARTRealtimeHistoryQuery@ properties"@HistoryRequestParams@":#history-request-params properties - start:startStart := _beginning of time_ earliest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any messages retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any messages retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - direction:directionDirection := _backwards_ @:@@forwards@ or @:@@backwards@
__Type: @String@@Symbol@@Direction@ enum__ - limit:limitLimit := _100_ maximum number of messages to retrieve up to 1,000
__Type: @Integer@__ -- untilAttach:until_attachuntilAttached := _false_ when true, ensures message history is up until the point of the channel being attached. See "continuous history":#continuous-history for more info. If the @Channel@ is not attached, enabling this option will result in error
__Type: @Boolean@__ +- untilAttach:until_attach := _false_ when true, ensures message history is up until the point of the channel being attached. See "continuous history":#continuous-history for more info. If the @Channel@ is not attached, enabling this option will result in error
__Type: @Boolean@__ blang[jsall,objc,swift]. h4. Callback result @@ -296,25 +296,25 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable history(Hash option) -> yields "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> java: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history("Param":#param[] option) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message>?, ARTErrorInfo?) -> Void) throws - csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("DataRequestQuery":#data-request-query query, bool untilAttached = false) + csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("HistoryRequestParams":#history-request-params query, bool untilAttach = false) Gets a "paginated":#paginated-result set of historical presence events for this channel. h4. Parameters -- optionquery"Param":#param[] option"DataRequestQuery":#data-request-query query := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified below. +- optionquery"Param":#param[] option"HistoryRequestParams":#history-request-params query := an optional object containing the query parametersan optional set of key value pairs containing the query parameters, as specified below. -
callback
:= is a function of the form: @function(err, resultPage)@ -
&block
:= yields a @PaginatedResult@ array -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message> object or an error -h4. @options@ parameters@ARTRealtimeHistoryQuery@ properties"@DataRequestQuery@":#data-request-query properties +h4. @options@ parameters@ARTRealtimeHistoryQuery@ properties"@HistoryRequestParams@":#history-request-params properties - start:startStart := _beginning of time_ earliest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any presence events retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any presence events retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - direction:directionDirection := _backwards_ @:@@forwards@ or @:@@backwards@
__Type: @String@@Symbol@@Direction@ enum__ - limit:limitLimit := _100_ maximum number of presence events to retrieve up to 1,000
__Type: @Integer@__ -- untilAttach:until_attachuntilAttached := _false_ when true, ensures presence event history is up until the point of the channel being attached. See "continuous history":#continuous-history for more info. If the @Channel@ is not attached, enabling this option will result in error
__Type: @Boolean@__ +- untilAttach:until_attach := _false_ when true, ensures presence event history is up until the point of the channel being attached. See "continuous history":#continuous-history for more info. If the @Channel@ is not attached, enabling this option will result in error
__Type: @Boolean@__ blang[jsall,objc,swift]. h4. Callback result @@ -377,11 +377,11 @@ h3(#presence-action). <%= partial 'types/versions/v0.8/_presence_action' %> -h3(#data-request-query). - csharp: IO.Ably.DataRequestQuery +h3(#history-request-params). + csharp: IO.Ably.HistoryRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_history_request_params', indent: 2, skip_first_indent: true %> h3(#paginated-result). default: PaginatedResult diff --git a/content/realtime/versions/v0.8/presence.textile b/content/realtime/versions/v0.8/presence.textile index 065c429a7f..7c2df9d380 100644 --- a/content/realtime/versions/v0.8/presence.textile +++ b/content/realtime/versions/v0.8/presence.textile @@ -337,7 +337,7 @@ if(resultPage.hasNext()) { ```[csharp] PaginatedResult resultPage; -resultPage = await channel.Presence.HistoryAsync(untilAttached: true); +resultPage = await channel.Presence.HistoryAsync(untilAttach: true); Console.WriteLine(resultPage.Items.Count + " presence events received in first page"); if (resultPage.HasNext) { @@ -736,7 +736,7 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable get(Hash options) -> yields "PresenceMessage[]":#presence-message java: "PresenceMessage[]":#presence-message get("Param":#param[] options) swift,objc: get(query: ARTRealtimePresenceQuery, callback: (["ARTPresenceMessage":#presence-message], ARTErrorInfo?) -> Void) - csharp: Task> GetAsync(bool waitForSync = true, string clientId = "", string connectionId = "") + csharp: Task> GetAsync(GetOptions { bool waitForSync = true, string clientId = "", string connectionId = "" }) Gets an array of members present on the channel as "PresenceMessage":#presence-message objects. @@ -749,7 +749,7 @@ blang[jsall,ruby,java,swift,objc]. -
&block
:= yields a "@PresenceMessage[]@":#presence-message array -
callback
:= called with a "@[ARTPresenceMessage]@":#presence-message, or with an error -h4. @options@ parameters@ARTRealtimePresenceQuery@ propertiesArguments +h4. @options@ parameters@ARTRealtimePresenceQuery@ properties@GetOptions@ properties - clientId:client_id := when provided, will filter array of members returned that match the provided "@clientId@":/realtime/usage#client-id"@client_id@":/realtime/usage#client-id"@ClientId@":/realtime/usage#client-id string - connectionId:connection_id := when provided, will filter array of members returned that match the provided @connectionId@@ConnectionId@@connection_id@":/realtime/connection/#id string @@ -794,14 +794,14 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable history(Hash options) -> yields "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> java: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history("Param":#param[] options) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message>?, ARTErrorInfo?) -> Void) throws - csharp: Task> HistoryAsync("DataRequestQuery":#data-request-query query, bool untilAttached = false) + csharp: Task> HistoryAsync("HistoryRequestParams":#history-request-params query, bool untilAttach = false) Gets a "paginated":#paginated-result set of historical presence message events for this channel. If the "channel is configured to persist messages to disk":https://support.ably.io/support/solutions/articles/3000030059-how-long-are-messages-stored-for, then the presence message event history will "typically be available for 24 - 72 hours":https://support.ably.io/solution/articles/3000030059-how-long-are-messages-stored-for. If not, presence message events are only retained in memory by the Ably service for two minutes. h4. Parameters -- optionsquery"Param":#param[] options"DataRequestQuery":#data-request-query query := an optional object containing query parametersan optional set of key value pairs containing query parameters, as specified in the "presence history API documentation":/realtime/history#presence-history. +- optionsquery"Param":#param[] options"HistoryRequestParams":#history-request-params query := an optional object containing query parametersan optional set of key value pairs containing query parameters, as specified in the "presence history API documentation":/realtime/history#presence-history. -
callback
:= is a function of the form: @function(err, resultPage)@ -
&block
:= yields a @PaginatedResult@ array @@ -1137,11 +1137,11 @@ h3(#presence-action). <%= partial 'types/versions/v0.8/_presence_action' %> -h3(#data-request-query). - csharp: DataRequestQuery +h3(#history-request-params). + csharp: HistoryRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_history_request_params', indent: 2, skip_first_indent: true %> h3(#completion-listener). java: io.ably.lib.realtime.CompletionListener diff --git a/content/realtime/versions/v0.8/statistics.textile b/content/realtime/versions/v0.8/statistics.textile index 14fc1fa866..1cf4e8c7ee 100644 --- a/content/realtime/versions/v0.8/statistics.textile +++ b/content/realtime/versions/v0.8/statistics.textile @@ -56,7 +56,7 @@ The Ably Realtime client library provides a straightforward API for retrieving a ```[csharp] var realtime = new AblyRealtime("{{API_KEY}}"); - var query = new StatsDataRequestQuery() { By = StatsBy.Hour }; + var query = new StatsRequestParams() { By = StatsIntervalGranularity.Hour }; var results = await realtime.StatsAsync(query); Stats thisHour = results.Items[0]; Console.WriteLine("Published this hour " + thisHour.Inbound.All.All); @@ -91,7 +91,7 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable stats(Hash options) -> yields "PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#stats> java: "PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#stats-type> stats("Param":#param[] options) swift,objc: stats(query: ARTStatsQuery?, callback: ("ARTPaginatedResult":/realtime/types#paginated-result<"ARTStats":/realtime/types#stats>?, ARTErrorInfo?) -> Void) throws - csharp: Task<"PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#status>> StatsAsync("StatsDataRequestQuery":#statsdatarequest query) + csharp: Task<"PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#status>> StatsAsync("StatsRequestParams":#statsdatarequest query) This call queries the "REST @/stats@ API":/rest-api#stats-type and retrieves your application's usage statistics. A "PaginatedResult":/realtime/types#paginated-result is returned, containing an array of "Stats":/realtime/types#stats-type for the first page of results. "PaginatedResult":/realtime/types#paginated-result objects are iterable providing a means to page through historical statistics. "See an example set of raw stats returned via the REST API":/general/statistics. @@ -108,11 +108,11 @@ h3(#stats-type). <%= partial 'types/versions/v0.8/_stats' %> -h3(#stats-data-request-query). - csharp: IO.Ably.StatsDataRequestQuery +h3(#stats-request-params). + csharp: IO.Ably.StatsRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_stats_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_stats_request_params', indent: 2, skip_first_indent: true %> h3(#stats-granularity). objc,swift: ARTStatsGranularity diff --git a/content/realtime/versions/v0.8/types.textile b/content/realtime/versions/v0.8/types.textile index dac87802b1..4c65256280 100644 --- a/content/realtime/versions/v0.8/types.textile +++ b/content/realtime/versions/v0.8/types.textile @@ -35,12 +35,12 @@ jump_to: - Connection State#connection-state - Connection State Listener - Connection State Change - - Data Request Query + - History Request Params - Deferrable - LastConnnectionDetails#last-connection-details - Message Listener - Presence Listener - - Stats Data Request Query + - Stats Request Params - Token Params --- @@ -234,15 +234,15 @@ h3(#connection-state-change). objc,swift: ARTConnectionStateChange ruby: ConnectionStateChange java: io.ably.lib.realtime.ConnectionStateListener.ConnectionStateChange - csharp: IO.Ably.Realtime.ConnectionStateChangedEventArgs + csharp: IO.Ably.Realtime.ConnectionStateChange <%= partial 'types/versions/v0.8/_connection_state_change' %> -h3(#data-request-query). - csharp: IO.Ably.DataRequestQuery +h3(#history-request-params). + csharp: IO.Ably.HistoryRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_history_request_params', indent: 2, skip_first_indent: true %> h3(#message-listener). java: io.ably.lib.realtime.Channel.MessageListener @@ -268,11 +268,11 @@ blang[ruby]. <%= partial 'types/versions/v0.8/_deferrable', indent: 2, skip_first_indent: true %> -h3(#stats-data-request-query). - csharp: IO.Ably.StatsDataRequestQuery +h3(#stats-request-params). + csharp: IO.Ably.StatsRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_stats_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_stats_request_params', indent: 2, skip_first_indent: true %> h3(#token-params). default: TokenParams Object diff --git a/content/realtime/versions/v0.8/usage.textile b/content/realtime/versions/v0.8/usage.textile index da2cd4e97a..410b76f98f 100644 --- a/content/realtime/versions/v0.8/usage.textile +++ b/content/realtime/versions/v0.8/usage.textile @@ -294,7 +294,7 @@ bq(definition). ruby: "Deferrable":/realtime/types#deferrable stats(Hash options) -> yields "PaginatedResult":/realtime/types#paginated-result<"Stats":#stats> java: "PaginatedResult":/realtime/types#paginated-result<"Stats":#stats> stats("Param":#param[] options) swift,objc: stats(query: ARTStatsQuery?, callback: ("ARTPaginatedResult":/realtime/types#paginated-result<"ARTStats":/realtime/types#stats>?, ARTErrorInfo?) -> Void) throws - csharp: Task<"PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#stats>> StatsAsync(StatsDataRequestQuery query) + csharp: Task<"PaginatedResult":/realtime/types#paginated-result<"Stats":/realtime/types#stats>> StatsAsync(StatsRequestParams query) This call queries the "REST @/stats@ API":/rest-api#stats and retrieves your application's usage statistics. A "PaginatedResult":/realtime/types#paginated-result is returned, containing an array of "Stats":#stats for the first page of results. "PaginatedResult":/realtime/types#paginated-result objects are iterable providing a means to page through historical statistics. "See an example set of raw stats returned via the REST API":/general/statistics. diff --git a/content/rest/_stats.textile b/content/rest/_stats.textile index 6d33ce9e0b..efa5f6e662 100644 --- a/content/rest/_stats.textile +++ b/content/rest/_stats.textile @@ -1,12 +1,12 @@ h4. Parameters -- optionsquery := an optional objectHash@ARTStatsQuery@@StatsDataRequestQuery@"@Param@":#param[] array containing the query parameters +- optionsquery := an optional objectHash@ARTStatsQuery@@StatsRequestParams@"@Param@":#param[] array containing the query parameters -
callback
:= is a function of the form: @function(err, result)@ -
&block
:= yields a @PaginatedResult@ array -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTStats":/rest/types#stats> object or an error -h4. @options@ parameters@ARTStatsQuery@ properties@StatsDataRequestQuery@ properties +h4. @options@ parameters@ARTStatsQuery@ properties@StatsRequestParams@ properties The following options, as defined in the "REST @/stats@ API":/rest-api#stats endpoint, are permitted: @@ -14,7 +14,7 @@ The following options, as defined in the "REST @/stats@ API":/rest-api#stats end - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any stats retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - direction:directionDirection := _backwards_ @:@@forwards@ or @:@@backwards@
__Type: @String@@Symbol@@Direction@ enum__ - limit:limitLimit := _100_ maximum number of messages to retrieve up to 1,000
__Type: @Integer@__ -- unit:unitUnit := _minute_ @:@@minute@, @:@@hour@, @:@@day@ or @:@@month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @String@"@ARTStatsGranularity@":#stats-granularity@Symbol@@StatsBy@ enum__ +- unit:unitUnit := _minute_ @:@@minute@, @:@@hour@, @:@@day@ or @:@@month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @String@"@ARTStatsGranularity@":#stats-granularity@Symbol@@StatsIntervalGranularity@ enum__ blang[jsall,objc,swift]. h4. Callback result diff --git a/content/rest/channels-messages.textile b/content/rest/channels-messages.textile index 64c8d23182..977d4cc925 100644 --- a/content/rest/channels-messages.textile +++ b/content/rest/channels-messages.textile @@ -415,7 +415,7 @@ bq(definition). python: "PaginatedResult":#paginated-result<"Message":#message> history(kwargs_options) php: "PaginatedResult":#paginated-result<"Message":#message> history(Array options) java: "PaginatedResult":#paginated-result<"Message":#message> history("Param":#param[] options) - csharp: Task<"PaginatedResult":#paginated-result<"Message":#message>> HistoryAsync("DataRequestQuery":#data-request-query dataQuery) + csharp: Task<"PaginatedResult":#paginated-result<"Message":#message>> HistoryAsync("HistoryRequestParams":#history-request-params dataQuery) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTMessage":#message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical messages for this channel. If the "channel is configured to persist messages to disk":https://support.ably.io/support/solutions/articles/3000030059-how-long-are-messages-stored-for, then message history will "typically be available for 24 - 72 hours":https://support.ably.io/solution/articles/3000030059-how-long-are-messages-stored-for. If not, messages are only retained in memory by the Ably service for two minutes. @@ -475,11 +475,11 @@ h3(#channel-options). <%= partial 'types/_channel_options' %> -h3(#data-request-query). - csharp: DataRequestQuery +h3(#history-request-params). + csharp: HistoryRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#paginated-result). default: PaginatedResult diff --git a/content/rest/history.textile b/content/rest/history.textile index 4d8b543671..da61a7ef46 100644 --- a/content/rest/history.textile +++ b/content/rest/history.textile @@ -148,7 +148,7 @@ bq(definition). python: "PaginatedResult":#paginated-result<"Message":#message> history(kwargs_options) php: "PaginatedResult":#paginated-result<"Message":#message> history(Array option) java: "PaginatedResult":#paginated-result<"Message":#message> history("Param":#param[] option) - csharp: Task<"PaginatedResult":#paginated-result<"Message":#message>> HistoryAsync("DataRequestQuery":#data-request query); + csharp: Task<"PaginatedResult":#paginated-result<"Message":#message>> HistoryAsync("HistoryRequestParams":#data-request query); objc,swift: history(query: ARTDataQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTMessage":#message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical messages for this channel. @@ -160,7 +160,7 @@ h4. Parameters -
callback
:= is a function of the form: @function(err, resultPage)@ -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTMessage":#message> object or an error -h4. @options@ parameters@ARTDataQuery@ properties"@DataRequestQuery@":#data-request-query properties +h4. @options@ parameters@ARTDataQuery@ properties"@HistoryRequestParams@":#history-request-params properties - start:startStart := _beginning of time_ earliest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any messages retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any messages retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ @@ -206,19 +206,19 @@ bq(definition). python: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history(kwargs_options) php: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history(Array option) java: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history("Param":#param[] option) - csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("DataRequestQuery":#data-request query); + csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("HistoryRequestParams":#data-request query); objc,swift: history(query: ARTDataQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical presence events for this channel. h4. Parameters -- option"Param":#param[] option"DataRequestQuery":#data-request-query query := an optional object containing the query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing the query parametersan Associate Array containing the query parameters, as specified below. +- option"Param":#param[] option"HistoryRequestParams":#history-request-params query := an optional object containing the query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing the query parametersan Associate Array containing the query parameters, as specified below. -
callback
:= is a function of the form: @function(err, resultPage)@ -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message> object or an error -h4. @options@ parameters@ARTDataQuery@ properties"@DataRequestQuery@":#data-request-query properties +h4. @options@ parameters@ARTDataQuery@ properties"@HistoryRequestParams@":#history-request-params properties - start:startStart := _beginning of time_ earliest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any presence events retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any presence events retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ @@ -278,11 +278,11 @@ h3(#presence-action). <%= partial 'types/_presence_action' %> -h3(#data-request-query). - csharp: IO.Ably.DataRequestQuery +h3(#history-request-params). + csharp: IO.Ably.HistoryRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#paginated-result). default: PaginatedResult diff --git a/content/rest/presence.textile b/content/rest/presence.textile index efbeedfa28..c27e5cb121 100644 --- a/content/rest/presence.textile +++ b/content/rest/presence.textile @@ -278,14 +278,14 @@ bq(definition). python: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history(kwargs_options) php: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history(Array options) java: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history("Param":#param[] options) - csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("DataRequestQuery":#data-request-query query); + csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("HistoryRequestParams":#history-request-params query); objc,swift: history(query: ARTDataQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical presence message events for this channel. If the "channel is configured to persist messages to disk":https://support.ably.io/support/solutions/articles/3000030059-how-long-are-messages-stored-for, then the presence message event history will "typically be available for 24 - 72 hours":https://support.ably.io/solution/articles/3000030059-how-long-are-messages-stored-for. If not, presence message events are only retained in memory by the Ably service for two minutes. h4. Parameters -- options"Param":#param[] optionsquery"DataRequestQuery":#data-request-query query := an optional object containing query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing query parametersan optional Associate Array containing the query parameters, as specified in the "presence history API documentation":/rest/history#presence-history. +- options"Param":#param[] optionsquery"HistoryRequestParams":#history-request-params query := an optional object containing query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing query parametersan optional Associate Array containing the query parameters, as specified in the "presence history API documentation":/rest/history#presence-history. -
callback
:= is a function of the form: @function(err, resultPage)@ -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message> object or an error @@ -329,11 +329,11 @@ h3(#presence-action). <%= partial 'shared/_presence_from_encoded' %> -h3(#data-request-query). - csharp: DataRequestQuery +h3(#history-request-params). + csharp: HistoryRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h3(#paginated-result). default: PaginatedResult diff --git a/content/rest/statistics.textile b/content/rest/statistics.textile index 43bd32ddb3..94a7ef9349 100644 --- a/content/rest/statistics.textile +++ b/content/rest/statistics.textile @@ -71,7 +71,7 @@ The Ably REST client library provides a straightforward API for retrieving appli ```[csharp] AblyRest rest = new AblyRest("{{API_KEY}}"); - var query = new StatsDataRequestQuery() { Unit = StatsGranularity.Hour }; + var query = new StatsRequestParams() { Unit = StatsGranularity.Hour }; PaginatedResult results = await rest.StatsAsync(query); Stats thisHour = results.Items[0]; Console.WriteLine("Published this hour " + thisHour.Inbound.All.All.Count); @@ -109,7 +109,7 @@ bq(definition). python: "PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats> stats(kwargs_options) php: "PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats> stats(Array options) java: "PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats-type> stats("Param":#param[] options) - csharp: Task<"PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats-type>> StatsAsync(@StatsDataRequestQuery@ query) + csharp: Task<"PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats-type>> StatsAsync(@StatsRequestParams@ query) swift,objc: stats(query: ARTStatsQuery?, callback: ("ARTPaginatedResult":#/realtime/types#paginated-result<"ARTStats":/realtime/types#stats>?, ARTErrorInfo?) -> Void) throws This call queries the "Ably REST @/stats@ API endpoint":/rest-api#stats-type and retrieves your application's usage statistics. A "PaginatedResult":/rest/types#paginated-result is returned, containing an array of "Stats":/rest/types#stats-type for the first page of results. "PaginatedResult":/rest/types#paginated-result objects are iterable providing a means to page through historical statistics. "See an example set of raw stats returned via the REST API":/general/statistics. @@ -128,11 +128,11 @@ h3(#stats-type). <%= partial 'types/_stats' %> -h3(#stats-data-request-query). - csharp: IO.Ably.StatsDataRequestQuery +h3(#stats-request-params). + csharp: IO.Ably.StatsRequestParams blang[csharp]. - <%= partial 'types/_stats_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_stats_request_params', indent: 2, skip_first_indent: true %> h3(#stats-granularity). objc,swift: ARTStatsGranularity diff --git a/content/rest/types.textile b/content/rest/types.textile index dfde556747..0949df3fc9 100644 --- a/content/rest/types.textile +++ b/content/rest/types.textile @@ -30,8 +30,8 @@ jump_to: - Client Options - Channel Options - Cipher Params - - Data Request Query - - Stats Data Request Query + - History Request Params + - Stats Request Params - Stats Granularity - Token Params --- @@ -156,11 +156,11 @@ h3(#stats-granularity). <%= partial 'types/_stats_granularity' %> -h3(#data-request-query). - csharp: IO.Ably.DataRequestQuery +h3(#history-request-params). + csharp: IO.Ably.HistoryRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_history_request_params', indent: 2, skip_first_indent: true %> h2. REST Other types @@ -205,11 +205,11 @@ h3(#cipher-params). <%= partial 'types/_cipher_params' %> -h3(#stats-data-request-query). - csharp: IO.Ably.StatsDataRequestQuery +h3(#stats-request-params). + csharp: IO.Ably.StatsRequestParams blang[csharp]. - <%= partial 'types/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/_stats_request_params', indent: 2, skip_first_indent: true %> h3(#token-params). default: TokenParams Object diff --git a/content/rest/usage.textile b/content/rest/usage.textile index c8a74459cc..74ffb15ad9 100644 --- a/content/rest/usage.textile +++ b/content/rest/usage.textile @@ -297,7 +297,7 @@ bq(definition). python: "PaginatedResult":/rest/types#paginated-result<"Stats":#stats> stats(kwargs_options) php: "PaginatedResult":/rest/types#paginated-result<"Stats":#stats> stats(Array options) java: "PaginatedResult":/rest/types#paginated-result<"Stats":#stats> stats("Param":#param[] options) - csharp: Task<"PaginatedResult":#paginated-result<"Stats":#stats>> StatsAsync("StatsDataRequestQuery":/rest/types#data-request query) + csharp: Task<"PaginatedResult":#paginated-result<"Stats":#stats>> StatsAsync("StatsRequestParams":/rest/types#data-request query) swift,objc: stats(query: ARTStatsQuery?, callback: ("ARTPaginatedResult":#/realtime/types#paginated-result<"ARTStats":/realtime/types#stats>?, ARTErrorInfo?) -> Void) throws This call queries the "REST @/stats@ API":/rest-api#stats and retrieves your application's usage statistics. A "PaginatedResult":/rest/types#paginated-result is returned, containing an array of "Stats":#stats for the first page of results. "PaginatedResult":/rest/types#paginated-result objects are iterable providing a means to page through historical statistics. "See an example set of raw stats returned via the REST API":/general/statistics. diff --git a/content/rest/versions/v0.8/_stats.textile b/content/rest/versions/v0.8/_stats.textile index 3f9811f053..4a09792a9d 100644 --- a/content/rest/versions/v0.8/_stats.textile +++ b/content/rest/versions/v0.8/_stats.textile @@ -1,12 +1,12 @@ h4. Parameters -- optionsquery := an optional objectHash@ARTStatsQuery@@StatsDataRequestQuery@"@Param@":#param[] array containing the query parameters +- optionsquery := an optional objectHash@ARTStatsQuery@@StatsRequestParams@"@Param@":#param[] array containing the query parameters -
callback
:= is a function of the form: @function(err, result)@ -
&block
:= yields a @PaginatedResult@ array -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTStats":/rest/types#stats> object or an error -h4. @options@ parameters@ARTStatsQuery@ properties@StatsDataRequestQuery@ properties +h4. @options@ parameters@ARTStatsQuery@ properties@StatsRequestParams@ properties The following options, as defined in the "REST @/stats@ API":/rest-api#stats endpoint, are permitted: @@ -14,7 +14,7 @@ The following options, as defined in the "REST @/stats@ API":/rest-api#stats end - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any stats retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - direction:directionDirection := _backwards_ @:@@forwards@ or @:@@backwards@
__Type: @String@@Symbol@@Direction@ enum__ - limit:limitLimit := _100_ maximum number of messages to retrieve up to 1,000
__Type: @Integer@__ -- unit:unitUnit := _minute_ @:@@minute@, @:@@hour@, @:@@day@ or @:@@month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @String@"@ARTStatsGranularity@":#stats-granularity@Symbol@@StatsBy@ enum__ +- unit:unitUnit := _minute_ @:@@minute@, @:@@hour@, @:@@day@ or @:@@month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @String@"@ARTStatsGranularity@":#stats-granularity@Symbol@@StatsIntervalGranularity@ enum__ blang[jsall,objc,swift]. h4. Callback result diff --git a/content/rest/versions/v0.8/channels-messages.textile b/content/rest/versions/v0.8/channels-messages.textile index b7fb5114a0..11e0422a05 100644 --- a/content/rest/versions/v0.8/channels-messages.textile +++ b/content/rest/versions/v0.8/channels-messages.textile @@ -403,7 +403,7 @@ bq(definition). ruby: "PaginatedResult":#paginated-result<"Message":#message> history(kwargs_options) php: "PaginatedResult":#paginated-result<"Message":#message> history(Array options) java: "PaginatedResult":#paginated-result<"Message":#message> history("Param":#param[] options) - csharp: Task<"PaginatedResult":#paginated-result<"Message":#message>> HistoryAsync("DataRequestQuery":#data-request-query dataQuery) + csharp: Task<"PaginatedResult":#paginated-result<"Message":#message>> HistoryAsync("HistoryRequestParams":#history-request-params dataQuery) objc,swift: history(query: ARTRealtimeHistoryQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTMessage":#message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical messages for this channel. If the "channel is configured to persist messages to disk":https://support.ably.io/support/solutions/articles/3000030059-how-long-are-messages-stored-for, then message history will "typically be available for 24 - 72 hours":https://support.ably.io/solution/articles/3000030059-how-long-are-messages-stored-for. If not, messages are only retained in memory by the Ably service for two minutes. @@ -461,11 +461,11 @@ h3(#channel-options). <%= partial 'types/versions/v0.8/_channel_options' %> -h3(#data-request-query). - csharp: DataRequestQuery +h3(#history-request-params). + csharp: HistoryRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_history_request_params', indent: 2, skip_first_indent: true %> h3(#paginated-result). default: PaginatedResult diff --git a/content/rest/versions/v0.8/history.textile b/content/rest/versions/v0.8/history.textile index cd9cd4b93f..343f5ae899 100644 --- a/content/rest/versions/v0.8/history.textile +++ b/content/rest/versions/v0.8/history.textile @@ -136,7 +136,7 @@ bq(definition). python: "PaginatedResult":#paginated-result<"Message":#message> history(kwargs_options) php: "PaginatedResult":#paginated-result<"Message":#message> history(Array option) java: "PaginatedResult":#paginated-result<"Message":#message> history("Param":#param[] option) - csharp: Task<"PaginatedResult":#paginated-result<"Message":#message>> HistoryAsync("DataRequestQuery":#data-request query); + csharp: Task<"PaginatedResult":#paginated-result<"Message":#message>> HistoryAsync("HistoryRequestParams":#data-request query); objc,swift: history(query: ARTDataQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTMessage":#message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical messages for this channel. @@ -148,7 +148,7 @@ h4. Parameters -
callback
:= is a function of the form: @function(err, resultPage)@ -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTMessage":#message> object or an error -h4. @options@ parameters@ARTDataQuery@ properties"@DataRequestQuery@":#data-request-query properties +h4. @options@ parameters@ARTDataQuery@ properties"@HistoryRequestParams@":#history-request-params properties - start:startStart := _beginning of time_ earliest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any messages retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any messages retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ @@ -194,19 +194,19 @@ bq(definition). python: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history(kwargs_options) php: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history(Array option) java: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history("Param":#param[] option) - csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("DataRequestQuery":#data-request query); + csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("HistoryRequestParams":#data-request query); objc,swift: history(query: ARTDataQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical presence events for this channel. h4. Parameters -- option"Param":#param[] option"DataRequestQuery":#data-request-query query := an optional object containing the query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing the query parametersan Associate Array containing the query parameters, as specified below. +- option"Param":#param[] option"HistoryRequestParams":#history-request-params query := an optional object containing the query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing the query parametersan Associate Array containing the query parameters, as specified below. -
callback
:= is a function of the form: @function(err, resultPage)@ -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message> object or an error -h4. @options@ parameters@ARTDataQuery@ properties"@DataRequestQuery@":#data-request-query properties +h4. @options@ parameters@ARTDataQuery@ properties"@HistoryRequestParams@":#history-request-params properties - start:startStart := _beginning of time_ earliest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any presence events retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ - end:endEnd := _current time_ latest @DateTimeOffset@ or @Time@ or time in milliseconds since the epoch for any presence events retrieved
__Type: @Long@@Int or @Time@@DateTimeOffset@__ @@ -266,11 +266,11 @@ h3(#presence-action). <%= partial 'types/versions/v0.8/_presence_action' %> -h3(#data-request-query). - csharp: IO.Ably.DataRequestQuery +h3(#history-request-params). + csharp: IO.Ably.HistoryRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_history_request_params', indent: 2, skip_first_indent: true %> h3(#paginated-result). default: PaginatedResult diff --git a/content/rest/versions/v0.8/presence.textile b/content/rest/versions/v0.8/presence.textile index f44c6b6a71..c55e723ba6 100644 --- a/content/rest/versions/v0.8/presence.textile +++ b/content/rest/versions/v0.8/presence.textile @@ -266,14 +266,14 @@ bq(definition). python: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history(kwargs_options) php: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history(Array options) java: "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> history("Param":#param[] options) - csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("DataRequestQuery":#data-request-query query); + csharp: Task<"PaginatedResult":#paginated-result<"PresenceMessage":#presence-message>> HistoryAsync("HistoryRequestParams":#history-request-params query); objc,swift: history(query: ARTDataQuery?, callback: ("ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message>?, ARTErrorInfo?) -> Void) throws Gets a "paginated":#paginated-result set of historical presence message events for this channel. If the "channel is configured to persist messages to disk":https://support.ably.io/support/solutions/articles/3000030059-how-long-are-messages-stored-for, then the presence message event history will "typically be available for 24 - 72 hours":https://support.ably.io/solution/articles/3000030059-how-long-are-messages-stored-for. If not, presence message events are only retained in memory by the Ably service for two minutes. h4. Parameters -- options"Param":#param[] optionsquery"DataRequestQuery":#data-request-query query := an optional object containing query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing query parametersan optional Associate Array containing the query parameters, as specified in the "presence history API documentation":/rest/history#presence-history. +- options"Param":#param[] optionsquery"HistoryRequestParams":#history-request-params query := an optional object containing query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing query parametersan optional Associate Array containing the query parameters, as specified in the "presence history API documentation":/rest/history#presence-history. -
callback
:= is a function of the form: @function(err, resultPage)@ -
callback
:= called with a "ARTPaginatedResult":#paginated-result<"ARTPresenceMessage":#presence-message> object or an error @@ -315,11 +315,11 @@ h3(#presence-action). <%= partial 'types/versions/v0.8/_presence_action' %> -h3(#data-request-query). - csharp: DataRequestQuery +h3(#history-request-params). + csharp: HistoryRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_history_request_params', indent: 2, skip_first_indent: true %> h3(#paginated-result). default: PaginatedResult diff --git a/content/rest/versions/v0.8/statistics.textile b/content/rest/versions/v0.8/statistics.textile index 06cfd0c386..293ac94a30 100644 --- a/content/rest/versions/v0.8/statistics.textile +++ b/content/rest/versions/v0.8/statistics.textile @@ -61,7 +61,7 @@ The Ably Rest client library provides a straightforward API for retrieving appli ```[csharp] AblyRest rest = new AblyRest("{{API_KEY}}"); - var query = new StatsDataRequestQuery() { Unit = StatsGranularity.Hour }; + var query = new StatsRequestParams() { Unit = StatsGranularity.Hour }; PaginatedResult results = await rest.StatsAsync(query); Stats thisHour = results.Items[0]; Console.WriteLine("Published this hour " + thisHour.Inbound.All.All.Count); @@ -99,7 +99,7 @@ bq(definition). python: "PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats> stats(kwargs_options) php: "PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats> stats(Array options) java: "PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats-type> stats("Param":#param[] options) - csharp: Task<"PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats-type>> StatsAsync(@StatsDataRequestQuery@ query) + csharp: Task<"PaginatedResult":/rest/types#paginated-result<"Stats":/rest/types#stats-type>> StatsAsync(@StatsRequestParams@ query) swift,objc: stats(query: ARTStatsQuery?, callback: ("ARTPaginatedResult":#/realtime/types#paginated-result<"ARTStats":/realtime/types#stats>?, ARTErrorInfo?) -> Void) throws This call queries the "Ably REST @/stats@ API endpoint":/rest-api#stats-type and retrieves your application's usage statistics. A "PaginatedResult":/rest/types#paginated-result is returned, containing an array of "Stats":/rest/types#stats-type for the first page of results. "PaginatedResult":/rest/types#paginated-result objects are iterable providing a means to page through historical statistics. "See an example set of raw stats returned via the REST API":/general/statistics. @@ -118,11 +118,11 @@ h3(#stats-type). <%= partial 'types/versions/v0.8/_stats' %> -h3(#stats-data-request-query). - csharp: IO.Ably.StatsDataRequestQuery +h3(#stats-request-params). + csharp: IO.Ably.StatsRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_stats_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_stats_request_params', indent: 2, skip_first_indent: true %> h3(#stats-granularity). objc,swift: ARTStatsGranularity diff --git a/content/rest/versions/v0.8/types.textile b/content/rest/versions/v0.8/types.textile index a331a7f741..80f97ba0f5 100644 --- a/content/rest/versions/v0.8/types.textile +++ b/content/rest/versions/v0.8/types.textile @@ -19,8 +19,8 @@ jump_to: - Client Options - Channel Options - Cipher Params - - Data Request Query - - Stats Data Request Query + - History Request Params + - Stats Request Params - Stats Granularity - Token Params --- @@ -140,11 +140,11 @@ h3(#stats-granularity). <%= partial 'types/versions/v0.8/_stats_granularity' %> -h3(#data-request-query). - csharp: IO.Ably.DataRequestQuery +h3(#history-request-params). + csharp: IO.Ably.HistoryRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_history_request_params', indent: 2, skip_first_indent: true %> h2. REST Other types @@ -189,11 +189,11 @@ h3(#cipher-params). <%= partial 'types/versions/v0.8/_cipher_params' %> -h3(#stats-data-request-query). - csharp: IO.Ably.StatsDataRequestQuery +h3(#stats-request-params). + csharp: IO.Ably.StatsRequestParams blang[csharp]. - <%= partial 'types/versions/v0.8/_data_request_query', indent: 2, skip_first_indent: true %> + <%= partial 'types/versions/v0.8/_stats_request_params', indent: 2, skip_first_indent: true %> h3(#token-params). default: TokenParams Object diff --git a/content/rest/versions/v0.8/usage.textile b/content/rest/versions/v0.8/usage.textile index cb63842a54..db844111e9 100644 --- a/content/rest/versions/v0.8/usage.textile +++ b/content/rest/versions/v0.8/usage.textile @@ -263,7 +263,7 @@ bq(definition). python: "PaginatedResult":/rest/types#paginated-result<"Stats":#stats> stats(kwargs_options) php: "PaginatedResult":/rest/types#paginated-result<"Stats":#stats> stats(Array options) java: "PaginatedResult":/rest/types#paginated-result<"Stats":#stats> stats("Param":#param[] options) - csharp: Task<"PaginatedResult":#paginated-result<"Stats":#stats>> StatsAsync("StatsDataRequestQuery":/rest/types#data-request query) + csharp: Task<"PaginatedResult":#paginated-result<"Stats":#stats>> StatsAsync("StatsRequestParams":/rest/types#data-request query) swift,objc: stats(query: ARTStatsQuery?, callback: ("ARTPaginatedResult":#/realtime/types#paginated-result<"ARTStats":/realtime/types#stats>?, ARTErrorInfo?) -> Void) throws This call queries the "REST @/stats@ API":/rest-api#stats and retrieves your application's usage statistics. A "PaginatedResult":/rest/types#paginated-result is returned, containing an array of "Stats":#stats for the first page of results. "PaginatedResult":/rest/types#paginated-result objects are iterable providing a means to page through historical statistics. "See an example set of raw stats returned via the REST API":/general/statistics. diff --git a/content/types/_client_options.textile b/content/types/_client_options.textile index 0f8b4316f4..9f63fef884 100644 --- a/content/types/_client_options.textile +++ b/content/types/_client_options.textile @@ -54,7 +54,7 @@ blang[java]. - logHandler := _@System.out PrintStream@_ A @LogHandler@ interface can be specified to handle each line of log output. If @logHandler@ is not specified, @System.out@ is used. Note that the @logHandler@ is a static variable in the library and will thus not act independently between library instances when multiple library instances exist concurrently.
__Type: PrintStream__ blang[csharp]. - To set the log level and custom logger sink when using the .Net library, configure the static @IO.Ably.Logger@ class. + To set the log level and custom logger sink when using the .Net library, configure the static @IO.Ably.Logger@ class or specify the @ClientOptions@: - LogLevel := _@Error@_ This is an enum controlling the verbosity of the output from @Debug@ (maximum) to @Error@ (errors only). A special value of @None@ will silence all logging. Note that the @LogLevel@ is a static variable in the library and will thus not act independently between library instances.
__Type: @Enum@__ diff --git a/content/types/_connection_state_change.textile b/content/types/_connection_state_change.textile index 8ab62e083b..a5e523203a 100644 --- a/content/types/_connection_state_change.textile +++ b/content/types/_connection_state_change.textile @@ -1,4 +1,4 @@ -A @io.ably.lib.realtime.ConnectionStateListener.ConnectionStateChange@@Ably::Models::ConnectionStateChange@@ARTConnectionStateChange@@IO.Ably.Realtime.ConnectionStateChangedEventArgs@@ConnectionStateChange@ is a type encapsulating state change information emitted by the "@Connection@":/realtime/connection object. See "@Connection#on@":/realtime/connection#on to register a listener for one or more events. +A @io.ably.lib.realtime.ConnectionStateListener.ConnectionStateChange@@Ably::Models::ConnectionStateChange@@ARTConnectionStateChange@@IO.Ably.Realtime.ConnectionStateChange@@ConnectionStateChange@ is a type encapsulating state change information emitted by the "@Connection@":/realtime/connection object. See "@Connection#on@":/realtime/connection#on to register a listener for one or more events. h4. default: Properties @@ -9,4 +9,4 @@ h4. - previousPrevious := the previous state. (for the @update@ event, this will be equal to the @current@ state)
__Type: "State @String@":/realtime/types#connection-state"@Connection::STATE@":/realtime/types#connection-state"@ConnectionState@":/realtime/types#connection-state__ - eventEvent := the event that triggered this state change
__Type: "@ConnectionEvent@Connection::EVENT@":/realtime/types#connection-event__ - reasonReason := an "@ErrorInfo@":#error-info containing any information relating to the transition
__Type: "@ErrorInfo@":/realtime/types#error-info__ -- retryInretry_inRetryin := Duration upon which the library will retry a connection where applicable, as millisecondssecondsa @Timespan@
__Type: @Integer@@Timespan@@Long Integer@__ +- retryInretry_inRetryIn := Duration upon which the library will retry a connection where applicable, as millisecondssecondsa @Timespan@
__Type: @Integer@@Timespan@@Long Integer@__ diff --git a/content/types/_error_info.textile b/content/types/_error_info.textile index 2629e4f9bf..297a64722c 100644 --- a/content/types/_error_info.textile +++ b/content/types/_error_info.textile @@ -5,8 +5,8 @@ h4. java: Members ruby: Attributes -- codecode := Ably error code (see "ably-common/protocol/errors.json":https://github.com/ably/ably-common/blob/master/protocol/errors.json)
__Type: @Integer@__ +- codeCode := Ably error code (see "ably-common/protocol/errors.json":https://github.com/ably/ably-common/blob/master/protocol/errors.json)
__Type: @Integer@__ -- statusCodestatus_codestatusCode := HTTP Status Code corresponding to this error, where applicable
__Type: @Integer@__ +- statusCodestatus_codeStatusCode := HTTP Status Code corresponding to this error, where applicable
__Type: @Integer@__ -- messagemessage := Additional message information, where available
__Type: @String@__ +- messageMessage := Additional message information, where available
__Type: @String@__ diff --git a/content/types/_data_request_query.textile b/content/types/_history_request_params.textile similarity index 71% rename from content/types/_data_request_query.textile rename to content/types/_history_request_params.textile index 88debc0e21..331ab490a9 100644 --- a/content/types/_data_request_query.textile +++ b/content/types/_history_request_params.textile @@ -1,4 +1,4 @@ -@DataRequestQuery@ is a type that encapsulates the parameters for a history queries. For example usage see "@Channel#history@@Channel#History@":/realtime/history#channel-history. +@HistoryRequestParams@ is a type that encapsulates the parameters for a history queries. For example usage see "@Channel#history@@Channel#History@":/realtime/history#channel-history. h4. Members diff --git a/content/types/_message.textile b/content/types/_message.textile index f372072502..4df36f18d6 100644 --- a/content/types/_message.textile +++ b/content/types/_message.textile @@ -6,24 +6,24 @@ h4. ruby: Attributes python: Attributes -- name := Event name, if provided
__Type: @String@__ +- nameName := Event name, if provided
__Type: @String@__ -
data
:= The message payload, if provided
__Type: @String@, @StringBuffer@, @JSON Object@__ -
data
:= The message payload, if provided
__Type: @String@, @ByteArray@, @JSONObject@, @JSONArray@__ --
data
:= The message payload, if provided
__Type: @String@, @byte[]@, plain C# object that can be serialized to Json__ +-
Data
:= The message payload, if provided
__Type: @String@, @byte[]@, plain C# object that can be serialized to Json__ -
data
:= The message payload, if provided
__Type: @String@, @Binary@ (ASCII-8BIT String), @Hash@, @Array@__ -
data
:= The message payload, if provided
__Type: @String@, @Bytearray@, @Dict@, @List@__ -
data
:= The message payload, if provided
__Type: @String@, @Binary String@, @Associative Array@, @Array@__ -
data
:= The message payload, if provided
__Type: @NSString *@, @NSData *@, @NSDictionary *@, @NSArray *@__ -
data
:= The message payload, if provided
__Type: @String@, @NSData@, @Dictionary@, @Array@__ -- id := Unique ID assigned by Ably to this message
__Type: @String@__ +- idId := Unique ID assigned by Ably to this message
__Type: @String@__ -- clientIdclient_id := The client ID of the publisher of this message
__Type: @String@__ +- clientIdclient_idClientId := The client ID of the publisher of this message
__Type: @String@__ -- connectionIdconnection_id := The connection ID of the publisher of this message
__Type: @String@__ +- connectionIdconnection_idConnectionId := The connection ID of the publisher of this message
__Type: @String@__ -- timestamp := Timestamp when the presence update was received by the Ably the realtime service, as milliseconds since the epocha @Time@ object
__Type: @Integer@@Long Integer@@DateTimeOffset@@Time@ +- timestampTimestamp := Timestamp when the presence update was received by the Ably the realtime service, as milliseconds since the epocha @Time@ object
__Type: @Integer@@Long Integer@@DateTimeOffset@@Time@ @NSDate@__ -- encoding := This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the @data@ payload
__Type: @String@__ +- encodingEncoding := This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the @data@ payload
__Type: @String@__ diff --git a/content/types/_presence_message.textile b/content/types/_presence_message.textile index 7189de09df..79c5220161 100644 --- a/content/types/_presence_message.textile +++ b/content/types/_presence_message.textile @@ -6,7 +6,7 @@ h4. ruby: Attributes -
action
:= the event signified by a PresenceMessage. See "@PresenceMessage.action@":/realtime/types#presence-action
__Type: @enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }@__ --
action
:= the event signified by a PresenceMessage. See "@PresenceMessage.action@":/realtime/types#presence-action
__Type: @enum { Absent, Present, Enter, Leave, Update }@__ +-
Action
:= the event signified by a PresenceMessage. See "@PresenceMessage.action@":/realtime/types#presence-action
__Type: @enum { Absent, Present, Enter, Leave, Update }@__ -
action
:= the event signified by a PresenceMessage. See "@Presence action@":/realtime/types#presence-action
__Type: @int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }@__ -
action
:= the event signified by a PresenceMessage. See "@PresenceAction@":/realtime/types#presence-action
__Type: @int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }@__ -
action
:= the event signified by a PresenceMessage. See "@PresenceMessage::ACTION@":/realtime/types#presence-action
__Type: @enum { :absent, :present, :enter, :leave, :update }@__ @@ -14,7 +14,7 @@ h4. -
action
:= the event signified by a PresenceMessage. See "@PresenceMessage.action@":/realtime/types#presence-action
__Type: @ARTPresenceAction@__ -
data
:= The presence update payload, if provided
__Type: @String@, @ByteArray@, @JSONObject@, @JSONArray@__ --
data
:= The presence update payload, if provided
__Type: @String@, @byte[]@, plain C# object that can be converted to Json__ +-
Data
:= The presence update payload, if provided
__Type: @String@, @byte[]@, plain C# object that can be converted to Json__ -
data
:= The presence update payload, if provided
__Type: @String@, @StringBuffer@, @JSON Object@__ -
data
:= The presence update payload, if provided
__Type: @String@, @Binary@ (ASCII-8BIT String), @Hash@, @Array@__ -
data
:= The presence update payload, if provided
__Type: @String@, @Bytearray@, @Dict@, @List@__ @@ -22,12 +22,12 @@ h4. -
data
:= The message payload, if provided
__Type: @NSString *@, @NSData *@, @NSDictionary *@, @NSArray *@__ -
data
:= The message payload, if provided
__Type: @String@, @Binary String@, @Associative Array@, @Array@__ -- id := Unique ID assigned by Ably to this presence update
__Type: @String@__ +- idId := Unique ID assigned by Ably to this presence update
__Type: @String@__ -- clientIdclient_id := The client ID of the publisher of this presence update
__Type: @String@__ +- clientIdclient_idClientId := The client ID of the publisher of this presence update
__Type: @String@__ -- connectionIdconnection_id := The connection ID of the publisher of this presence update
__Type: @String@__ +- connectionIdconnection_idConnectionId := The connection ID of the publisher of this presence update
__Type: @String@__ -- timestamp := Timestamp when the presence update was received by Ably, as milliseconds since the epoch.
__Type: @Integer@@Long Integer@@DateTimeOffset@@Time@@NSDate@__ +- timestampTimestamp := Timestamp when the presence update was received by Ably, as milliseconds since the epoch.
__Type: @Integer@@Long Integer@@DateTimeOffset@@Time@@NSDate@__ -- encoding := This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the @data@ payload
__Type: @String@__ +- encodingEncoding := This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the @data@ payload
__Type: @String@__ diff --git a/content/types/_stats_data_request_query.textile b/content/types/_stats_request_params.textile similarity index 73% rename from content/types/_stats_data_request_query.textile rename to content/types/_stats_request_params.textile index b35fe498d0..ca91c1e781 100644 --- a/content/types/_stats_data_request_query.textile +++ b/content/types/_stats_request_params.textile @@ -1,4 +1,4 @@ -@StatsDataRequestQuery@ is a type that encapsulates the parameters for a stats query. For example usage see "@Realtime#stats@@Realtime#Stats@":/realtime/statistics. +@StatsRequestParams@ is a type that encapsulates the parameters for a stats query. For example usage see "@Realtime#stats@@Realtime#Stats@":/realtime/statistics. h4. Members @@ -6,5 +6,5 @@ h4. Members - End := _null_ The end of the queried interval
__Type: @DateTimeOffset@__ - Limit := _null_ By default it is null. Limits the number of items returned by history or stats
__Type: @Integer@__ - Direction := _Backwards_ Enum which is either @Forwards@ or @Backwards@
__Type: @Direction@ enum__ -- Unit := _Minute_ @Minute@, @Hour@, @Day@ @Month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @StatsBy@ enum__ +- Unit := _Minute_ @Minute@, @Hour@, @Day@ @Month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @StatsIntervalGranularity@ enum__ - ExtraParameters := Optionally any extra query parameters that may be passed to the query. This is mainly used internally by the library to manage paging.
__Type: @Dictionary@__ diff --git a/content/types/versions/v0.8/_client_options.textile b/content/types/versions/v0.8/_client_options.textile index c86f9ff05c..9362bb685f 100644 --- a/content/types/versions/v0.8/_client_options.textile +++ b/content/types/versions/v0.8/_client_options.textile @@ -54,7 +54,7 @@ blang[java]. - logHandler := _@System.out PrintStream@_ A @LogHandler@ interface can be specified to handle each line of log output. If @logHandler@ is not specified, @System.out@ is used. Note that the @logHandler@ is a static variable in the library and will thus not act independently between library instances when multiple library instances exist concurrently.
__Type: PrintStream__ blang[csharp]. - To set the log level and custom logger sink when using the .Net library, configure the static @IO.Ably.Logger@ class. + To set the log level and custom logger sink when using the .Net library, configure the static @IO.Ably.Logger@ class or specify the @ClientOptions@: - LogLevel := _@Error@_ This is an enum controlling the verbosity of the output from @Debug@ (maximum) to @Error@ (errors only). A special value of @None@ will silence all logging. Note that the @LogLevel@ is a static variable in the library and will thus not act independently between library instances.
__Type: @Enum@__ diff --git a/content/types/versions/v0.8/_connection_state_change.textile b/content/types/versions/v0.8/_connection_state_change.textile index 91c8743690..2df925b80c 100644 --- a/content/types/versions/v0.8/_connection_state_change.textile +++ b/content/types/versions/v0.8/_connection_state_change.textile @@ -1,4 +1,4 @@ -A @io.ably.lib.realtime.ConnectionStateListener.ConnectionStateChange@@Ably::Models::ConnectionStateChange@@ARTConnectionStateChange@@IO.Ably.Realtime.ConnectionStateChangedEventArgs@@ConnectionStateChange@ is a type encapsulating state change information emitted by the "@Connection@":/realtime/connection object. See "@Connection#on@":/realtime/connection#on to register a listener for one or more events. +A @io.ably.lib.realtime.ConnectionStateListener.ConnectionStateChange@@Ably::Models::ConnectionStateChange@@ARTConnectionStateChange@@IO.Ably.Realtime.ConnectionStateChange@@ConnectionStateChange@ is a type encapsulating state change information emitted by the "@Connection@":/realtime/connection object. See "@Connection#on@":/realtime/connection#on to register a listener for one or more events. h4. default: Properties @@ -8,4 +8,4 @@ h4. - previousPrevious := the previous state
__Type: "State @String@":/realtime/types#connection-state"@Connection::STATE@":/realtime/types#connection-state"@ConnectionState@":/realtime/types#connection-state__ - currentCurrent := the new state
__Type: "State @String@":/realtime/types#connection-state"@Connection::STATE@":/realtime/types#connection-state"@ConnectionState@":/realtime/types#connection-state__ - reasonReason := an "@ErrorInfo@":#error-info containing any information relating to the transition
__Type: "@ErrorInfo@":/realtime/types#error-info__ -- retryInretry_inRetryin := Duration upon which the library will retry a connection where applicable, as millisecondssecondsa @Timespan@
__Type: @Integer@@Timespan@@Long Integer@__ +- retryInretry_inRetryIn := Duration upon which the library will retry a connection where applicable, as millisecondssecondsa @Timespan@
__Type: @Integer@@Timespan@@Long Integer@__ diff --git a/content/types/versions/v0.8/_error_info.textile b/content/types/versions/v0.8/_error_info.textile index 2629e4f9bf..297a64722c 100644 --- a/content/types/versions/v0.8/_error_info.textile +++ b/content/types/versions/v0.8/_error_info.textile @@ -5,8 +5,8 @@ h4. java: Members ruby: Attributes -- codecode := Ably error code (see "ably-common/protocol/errors.json":https://github.com/ably/ably-common/blob/master/protocol/errors.json)
__Type: @Integer@__ +- codeCode := Ably error code (see "ably-common/protocol/errors.json":https://github.com/ably/ably-common/blob/master/protocol/errors.json)
__Type: @Integer@__ -- statusCodestatus_codestatusCode := HTTP Status Code corresponding to this error, where applicable
__Type: @Integer@__ +- statusCodestatus_codeStatusCode := HTTP Status Code corresponding to this error, where applicable
__Type: @Integer@__ -- messagemessage := Additional message information, where available
__Type: @String@__ +- messageMessage := Additional message information, where available
__Type: @String@__ diff --git a/content/types/versions/v0.8/_data_request_query.textile b/content/types/versions/v0.8/_history_request_params.textile similarity index 71% rename from content/types/versions/v0.8/_data_request_query.textile rename to content/types/versions/v0.8/_history_request_params.textile index 88debc0e21..331ab490a9 100644 --- a/content/types/versions/v0.8/_data_request_query.textile +++ b/content/types/versions/v0.8/_history_request_params.textile @@ -1,4 +1,4 @@ -@DataRequestQuery@ is a type that encapsulates the parameters for a history queries. For example usage see "@Channel#history@@Channel#History@":/realtime/history#channel-history. +@HistoryRequestParams@ is a type that encapsulates the parameters for a history queries. For example usage see "@Channel#history@@Channel#History@":/realtime/history#channel-history. h4. Members diff --git a/content/types/versions/v0.8/_message.textile b/content/types/versions/v0.8/_message.textile index f372072502..4df36f18d6 100644 --- a/content/types/versions/v0.8/_message.textile +++ b/content/types/versions/v0.8/_message.textile @@ -6,24 +6,24 @@ h4. ruby: Attributes python: Attributes -- name := Event name, if provided
__Type: @String@__ +- nameName := Event name, if provided
__Type: @String@__ -
data
:= The message payload, if provided
__Type: @String@, @StringBuffer@, @JSON Object@__ -
data
:= The message payload, if provided
__Type: @String@, @ByteArray@, @JSONObject@, @JSONArray@__ --
data
:= The message payload, if provided
__Type: @String@, @byte[]@, plain C# object that can be serialized to Json__ +-
Data
:= The message payload, if provided
__Type: @String@, @byte[]@, plain C# object that can be serialized to Json__ -
data
:= The message payload, if provided
__Type: @String@, @Binary@ (ASCII-8BIT String), @Hash@, @Array@__ -
data
:= The message payload, if provided
__Type: @String@, @Bytearray@, @Dict@, @List@__ -
data
:= The message payload, if provided
__Type: @String@, @Binary String@, @Associative Array@, @Array@__ -
data
:= The message payload, if provided
__Type: @NSString *@, @NSData *@, @NSDictionary *@, @NSArray *@__ -
data
:= The message payload, if provided
__Type: @String@, @NSData@, @Dictionary@, @Array@__ -- id := Unique ID assigned by Ably to this message
__Type: @String@__ +- idId := Unique ID assigned by Ably to this message
__Type: @String@__ -- clientIdclient_id := The client ID of the publisher of this message
__Type: @String@__ +- clientIdclient_idClientId := The client ID of the publisher of this message
__Type: @String@__ -- connectionIdconnection_id := The connection ID of the publisher of this message
__Type: @String@__ +- connectionIdconnection_idConnectionId := The connection ID of the publisher of this message
__Type: @String@__ -- timestamp := Timestamp when the presence update was received by the Ably the realtime service, as milliseconds since the epocha @Time@ object
__Type: @Integer@@Long Integer@@DateTimeOffset@@Time@ +- timestampTimestamp := Timestamp when the presence update was received by the Ably the realtime service, as milliseconds since the epocha @Time@ object
__Type: @Integer@@Long Integer@@DateTimeOffset@@Time@ @NSDate@__ -- encoding := This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the @data@ payload
__Type: @String@__ +- encodingEncoding := This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the @data@ payload
__Type: @String@__ diff --git a/content/types/versions/v0.8/_presence_message.textile b/content/types/versions/v0.8/_presence_message.textile index 06734422da..48aebdcaf6 100644 --- a/content/types/versions/v0.8/_presence_message.textile +++ b/content/types/versions/v0.8/_presence_message.textile @@ -6,7 +6,7 @@ h4. ruby: Attributes -
action
:= the event signified by a PresenceMessage. See "@PresenceMessage.action@":/realtime/types#presence-action
__Type: @enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }@__ --
action
:= the event signified by a PresenceMessage. See "@PresenceMessage.action@":/realtime/types#presence-action
__Type: @enum { Absent, Present, Enter, Leave, Update }@__ +-
Action
:= the event signified by a PresenceMessage. See "@PresenceMessage.action@":/realtime/types#presence-action
__Type: @enum { Absent, Present, Enter, Leave, Update }@__ -
action
:= the event signified by a PresenceMessage. See "@Presence action@":/realtime/types#presence-action
__Type: @int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }@__ -
action
:= the event signified by a PresenceMessage. See "@PresenceAction@":/realtime/types#presence-action
__Type: @int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }@__ -
action
:= the event signified by a PresenceMessage. See "@PresenceMessage::ACTION@":/realtime/types#presence-action
__Type: @enum { :absent, :present, :enter, :leave, :update }@__ @@ -14,7 +14,7 @@ h4. -
action
:= the event signified by a PresenceMessage. See "@PresenceMessage.action@":/realtime/types#presence-action
__Type: @ARTPresenceAction@__ -
data
:= The presence update payload, if provided
__Type: @String@, @ByteArray@, @JSONObject@, @JSONArray@__ --
data
:= The presence update payload, if provided
__Type: @String@, @byte[]@, plain C# object that can be converted to Json__ +-
Data
:= The presence update payload, if provided
__Type: @String@, @byte[]@, plain C# object that can be converted to Json__ -
data
:= The presence update payload, if provided
__Type: @String@, @StringBuffer@, @JSON Object@__ -
data
:= The presence update payload, if provided
__Type: @String@, @Binary@ (ASCII-8BIT String), @Hash@, @Array@__ -
data
:= The presence update payload, if provided
__Type: @String@, @Bytearray@, @Dict@, @List@__ @@ -22,12 +22,12 @@ h4. -
data
:= The message payload, if provided
__Type: @NSString *@, @NSData *@, @NSDictionary *@, @NSArray *@__ -
data
:= The message payload, if provided
__Type: @String@, @Binary String@, @Associative Array@, @Array@__ -- id := Unique ID assigned by Ably to this presence update
__Type: @String@__ +- idId := Unique ID assigned by Ably to this presence update
__Type: @String@__ -- clientIdclient_id := The client ID of the publisher of this presence update
__Type: @String@__ +- clientIdclient_idClientId := The client ID of the publisher of this presence update
__Type: @String@__ -- connectionIdconnection_id := The connection ID of the publisher of this presence update
__Type: @String@__ +- connectionIdconnection_idConnectionId := The connection ID of the publisher of this presence update
__Type: @String@__ -- timestamp := Timestamp when the presence update was received by the Ably the realtime service, as milliseconds since the epoch.
__Type: @Integer@@Long Integer@@DateTimeOffset@@Time@@NSDate@__ +- timestampTimestamp := Timestamp when the presence update was received by the Ably the realtime service, as milliseconds since the epoch.
__Type: @Integer@@Long Integer@@DateTimeOffset@@Time@@NSDate@__ -- encoding := This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the @data@ payload
__Type: @String@__ +- encodingEncoding := This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the @data@ payload
__Type: @String@__ diff --git a/content/types/versions/v0.8/_stats_data_request_query.textile b/content/types/versions/v0.8/_stats_request_params.textile similarity index 73% rename from content/types/versions/v0.8/_stats_data_request_query.textile rename to content/types/versions/v0.8/_stats_request_params.textile index b35fe498d0..ca91c1e781 100644 --- a/content/types/versions/v0.8/_stats_data_request_query.textile +++ b/content/types/versions/v0.8/_stats_request_params.textile @@ -1,4 +1,4 @@ -@StatsDataRequestQuery@ is a type that encapsulates the parameters for a stats query. For example usage see "@Realtime#stats@@Realtime#Stats@":/realtime/statistics. +@StatsRequestParams@ is a type that encapsulates the parameters for a stats query. For example usage see "@Realtime#stats@@Realtime#Stats@":/realtime/statistics. h4. Members @@ -6,5 +6,5 @@ h4. Members - End := _null_ The end of the queried interval
__Type: @DateTimeOffset@__ - Limit := _null_ By default it is null. Limits the number of items returned by history or stats
__Type: @Integer@__ - Direction := _Backwards_ Enum which is either @Forwards@ or @Backwards@
__Type: @Direction@ enum__ -- Unit := _Minute_ @Minute@, @Hour@, @Day@ @Month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @StatsBy@ enum__ +- Unit := _Minute_ @Minute@, @Hour@, @Day@ @Month@. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query
__Type: @StatsIntervalGranularity@ enum__ - ExtraParameters := Optionally any extra query parameters that may be passed to the query. This is mainly used internally by the library to manage paging.
__Type: @Dictionary@__ From 29156f0d4ce06bfec505adfd994894336a4b23a5 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 8 Mar 2017 02:43:00 +0000 Subject: [PATCH 17/19] api: C# ConnectionStateChange object incorrectly named --- content/realtime/connection.textile | 18 ++++++++--------- .../realtime/versions/v0.8/connection.textile | 20 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/content/realtime/connection.textile b/content/realtime/connection.textile index c756d468ac..b1623b77ea 100644 --- a/content/realtime/connection.textile +++ b/content/realtime/connection.textile @@ -137,7 +137,7 @@ bq. suspended → connecting → suspended → … → connecti h4. Listening for state changes -The @Connection@ object is an @EventEmitter@ and emits an event whose name is the new state whenever there is a connection state change. An event listener function is passed a "ConnectionStateChange":#connection-state-change object as the first argument for state change events.An event listener function is passed a "ConnectionStateChangeEventArgs":#connection-state-change object as the first argument for state change events.The event block is passed the new state and an optional "@ErrorInfo@":/realtime/types#error-info object +The @Connection@ object is an @EventEmitter@ and emits an event whose name is the new state whenever there is a connection state change. An event listener function is passed a "ConnectionStateChange":#connection-state-change object as the first argument for state change events.An event listener function is passed a "ConnectionStateChange":#connection-state-change object as the first argument for state change events.The event block is passed the new state and an optional "@ErrorInfo@":/realtime/types#error-info object The @Connection@ object can also emit an event that is not a state change: an @update@ event. This happens when there's a change to connection conditions for which the connection state doesn't change - that is, when the library remains connected, e.g. after a "reauth":/realtime/authentication#token-upgrading. @@ -503,7 +503,7 @@ bq(definition#on-state-listener). ruby: on("ConnectionEvent":#connection-event *event) -> yields "ConnectionStateChange":#connection-state-change java: void on("ConnectionEvent":#connection-event event, "ConnectionStateListener":#connection-state-listener listener) objc,swift: on(event: "ARTRealtimeConnectionEvent":#connection-event, call: ("ARTConnectionStateChange":#connection-state-change?) -> Void) -> ARTEventListener - csharp: void On("ConnectionEvent":#connection-event event, Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void On("ConnectionEvent":#connection-event event, Action<"ConnectionStateChange":#connection-state-change> action) Register the given listener blockfunctionaction for the specified "@ConnectionEvent@":#connection-event on the @Connection@. The listener is passed a "ConnectionStateChange":#connection-state-change object that contains the current state, previous state, and an optional reason for the event or state change.
@@ -518,7 +518,7 @@ bq(definition#on-listener). ruby: on -> yields "ConnectionStateChange":#connection-state-change java: void on("ConnectionStateListener":#connection-state-listener listener) objc,swift: on(call: ("ARTConnectionStateChange":#connection-state-change?) -> Void) -> ARTEventListener - csharp: void On(Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void On(Action<"ConnectionStateChange":#connection-state-change> action) Register the given listener blockfunctionaction for all "ConnectionEvents":#connection-event on the @Connection@. The listener is passed a "ConnectionStateChange":#connection-state-change object that contains the current state, previous state, the event, and an optional reason for the event or state change. (For the @update@ event, the current and previous states will be the same).
@@ -532,7 +532,7 @@ h4. Parameters -
listener
:= is a function of the form @function(stateChange)@ to be notified for matching events -
listener
:= listener to be notified for matching events
__Type: "@ConnectionStateListener@":#connection-state-listener__ --
action
:= action to be executed for matching events
__Type: "@ConnectionStateChangeEventArgs@":#connection-state-listener__ +-
action
:= action to be executed for matching events
__Type: "@ConnectionStateChange@":#connection-state-listener__ -
&block
:= listener block that is yielded to for matching events -
call
:= called with matching events @@ -551,7 +551,7 @@ bq(definition#once-state-listener). ruby: once("ConnectionEvent":#connection-event *event) -> yields "ConnectionStateChange":#connection-state-change java: void once("ConnectionEvent":#connection-event event, "ConnectionStateListener":#connection-state-listener listener) objc,swift: once(event: "ARTRealtimeConnectionEvent":#connection-event, call: ("ARTConnectionStateChange":#connection-state-change?) -> Void) -> ARTEventListener - csharp: void Once("ConnectionEvent":#connection-event event, Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void Once("ConnectionEvent":#connection-event event, Action<"ConnectionStateChange":#connection-state-change> action) Register the given listener blockfunctionaction for a single occurrence of the specified "ConnectionEvent":#connection-event on the @Connection@. Once the listener has been called, it is removed as a registered listener and will not be called again. The listener is passed a "ConnectionStateChange":#connection-state-change object that contains the current state, previous state, the event, and an optional reason for the state change. (For the @update@ event, the current and previous states will be the same). @@ -560,7 +560,7 @@ bq(definition#once-listener). ruby: once -> yields "ConnectionStateChange":#connection-state-change java: void once("ConnectionStateListener":#connection-state-listener listener) objc,swift: once(call: ("ARTConnectionStateChange":#connection-state-change?) -> Void) -> ARTEventListener - csharp: void Once(Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void Once(Action<"ConnectionStateChange":#connection-state-change> action) Register the given listener blockaction for a single occurrence of any "ConnectionEvent":#connection-event on the @Connection@. Once the listener has been called, it is removed as a registered listener and will not be called again. The listener is passed a "ConnectionStateChange":#connection-state-change object that contains the current state, previous state, and an optional reason for the state change. (For the @update@ event, the current and previous states will be the same). @@ -574,7 +574,7 @@ h4. Parameters -
listener
:= is a function of the form @function(stateChange)@ to be notified for a single occurrence of a matching event -
listener
:= listener to be notified for a single occurrence of a matching state change
__Type: "@ConnectionStateListener@":#connection-state-listener__ --
action
:= action to be executed for matching state changes
__Type: "@ConnectionStateChangeEventArgs@":#connection-state-listener__ +-
action
:= action to be executed for matching state changes
__Type: "@ConnectionStateChange@":#connection-state-listener__ -
&block
:= listener block that is yielded to for a single occurrence of a matching event -
call
:= called with matching events @@ -589,7 +589,7 @@ bq(definition#off-state-listener). ruby: off("ConnectionEvent":#connection-event *event, &block) java: void off("ConnectionEvent":#connection-event event, "ConnectionStateListener":#connection-state-listener listener) objc,swift: off(event: "ARTRealtimeConnectionEvent":#connection-event, listener: ARTEventListener) - csharp: void Off("ConnectionEvent":#connection-event event, Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void Off("ConnectionEvent":#connection-event event, Action<"ConnectionStateChange":#connection-state-change> action) Remove the given listener blockaction for the "ConnectionEvent":#connection-event. @@ -598,7 +598,7 @@ bq(definition#off-listener). ruby: off(&block) java: void off("ConnectionStateListener":#connection-state-listener listener) objc,swift: off(listener: ARTEventListener) - csharp: void Off(Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void Off(Action<"ConnectionStateChange":#connection-state-change> action) Remove the given listener blockaction for all "ConnectionEvents":#connection-event diff --git a/content/realtime/versions/v0.8/connection.textile b/content/realtime/versions/v0.8/connection.textile index 35f4263f1c..8da5b39293 100644 --- a/content/realtime/versions/v0.8/connection.textile +++ b/content/realtime/versions/v0.8/connection.textile @@ -135,7 +135,7 @@ bq. suspended → connecting → suspended → … → connecti h4. Listening for state changes -The @Connection@ object is an @EventEmitter@ and emits an event whose name is the new state whenever there is a connection state change. An event listener function is passed a "ConnectionStateChange":#connection-state-change object as the first argument for state change events.An event listener function is passed a "ConnectionStateChangeEventArgs":#connection-state-change object as the first argument for state change events.The event block is passed the new state and an optional "@ErrorInfo@":/realtime/types#error-info object +The @Connection@ object is an @EventEmitter@ and emits an event whose name is the new state whenever there is a connection state change. An event listener function is passed a "ConnectionStateChange":#connection-state-change object as the first argument for state change events.An event listener function is passed a "ConnectionStateChange":#connection-state-change object as the first argument for state change events.The event block is passed the new state and an optional "@ErrorInfo@":/realtime/types#error-info object blang[jsall]. ```[jsall] @@ -495,7 +495,7 @@ bq(definition#on-state-listener). ruby: on("ConnectionState":#connection-state *state) -> yields "ConnectionStateChange":#connection-state-change java: void on("ConnectionState":#connection-state state, "ConnectionStateListener":#connection-state-listener listener) objc,swift: on(event: "ARTRealtimeConnectionState":#connection-state, call: ("ARTConnectionStateChange":#connection-state-change?) -> Void) -> ARTEventListener - csharp: void On("ConnectionState":#connection-state event, Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void On("ConnectionState":#connection-state event, Action<"ConnectionStateChange":#connection-state-change> action) Register the given listener blockfunctionaction for the specified "ConnectionState":#connection-state @state@@state(s)@@state@@event@ changes on the @Connection@. The listener is passed a "ConnectionStateChange":#connection-state-change object that contains the current state, previous state, and an optional reason for the state change.
@@ -504,7 +504,7 @@ bq(definition#on-listener). ruby: on -> yields "ConnectionStateChange":#connection-state-change java: void on("ConnectionStateListener":#connection-state-listener listener) objc,swift: on(call: ("ARTConnectionStateChange":#connection-state-change?) -> Void) -> ARTEventListener - csharp: void On(Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void On(Action<"ConnectionStateChange":#connection-state-change> action) Register the given listener blockfunctionaction for all "ConnectionState":#connection-state changes on the @Connection@. The listener is passed a "ConnectionStateChange":#connection-state-change object that contains the current state, previous state, and an optional reason for the state change. @@ -518,7 +518,7 @@ h4. Parameters -
listener
:= is a function of the form @function(stateChange)@ to be notified for matching state changes -
listener
:= listener to be notified for matching state changes
__Type: "@ConnectionStateListener@":#connection-state-listener__ --
action
:= action to be executed for matching state changes
__Type: "@ConnectionStateChangeEventArgs@":#connection-state-listener__ +-
action
:= action to be executed for matching state changes
__Type: "@ConnectionStateChange@":#connection-state-listener__ -
&block
:= listener block that is yielded to for matching state changes -
call
:= called with matching state changes @@ -537,7 +537,7 @@ bq(definition#once-state-listener). ruby: once("ConnectionState":#connection-state *state) -> yields "ConnectionStateChange":#connection-state-change java: void once("ConnectionState":#connection-state state, "ConnectionStateListener":#connection-state-listener listener) objc,swift: once(event: "ARTRealtimeConnectionState":#connection-state, call: ("ARTConnectionStateChange":#connection-state-change?) -> Void) -> ARTEventListener - csharp: void Once("ConnectionState":#connection-state event, Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void Once("ConnectionState":#connection-state event, Action<"ConnectionStateChange":#connection-state-change> action) Register the given listener blockfunctionaction for a single occurrence of the specified "ConnectionState":#connection-state @state@@state(s)@@state@ change on the @Connection@. Once the listener has been called, it is removed as a registered listener and will not be called again. The listener is passed a "ConnectionStateChange":#connection-state-change object that contains the current state, previous state, and an optional reason for the state change. @@ -546,7 +546,7 @@ bq(definition#once-listener). ruby: once -> yields "ConnectionStateChange":#connection-state-change java: void once("ConnectionStateListener":#connection-state-listener listener) objc,swift: once(call: ("ARTConnectionStateChange":#connection-state-change?) -> Void) -> ARTEventListener - csharp: void Once(Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void Once(Action<"ConnectionStateChange":#connection-state-change> action) Register the given listener blockaction for a single occurrence of any "ConnectionState":#connection-state change on the @Connection@. Once the listener has been called, it is removed as a registered listener and will not be called again. The listener is passed a "ConnectionStateChange":#connection-state-change object that contains the current state, previous state, and an optional reason for the state change. @@ -560,7 +560,7 @@ h4. Parameters -
listener
:= is a function of the form @function(stateChange)@ to be notified for a single occurrence of a matching state change -
listener
:= listener to be notified for a single occurrence of a matching state change
__Type: "@ConnectionStateListener@":#connection-state-listener__ --
action
:= action to be executed for matching state changes
__Type: "@ConnectionStateChangeEventArgs@":#connection-state-listener__ +-
action
:= action to be executed for matching state changes
__Type: "@ConnectionStateChange@":#connection-state-listener__ -
&block
:= listener block that is yielded to for a single occurrence of a matching state change -
call
:= called with matching state changes @@ -575,7 +575,7 @@ bq(definition#off-state-listener). ruby: off("ConnectionState":#connection-state *state, &block) java: void off("ConnectionState":#connection-state state, "ConnectionStateListener":#connection-state-listener listener) objc,swift: off(event: "ARTRealtimeConnectionState":#connection-state, listener: ARTEventListener) - csharp: void Off("ConnectionState":#connection-state event, Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void Off("ConnectionState":#connection-state event, Action<"ConnectionStateChange":#connection-state-change> action) Remove the given listener blockaction for the "ConnectionState":#connection-state @state@@state(s)@@state@. @@ -584,7 +584,7 @@ bq(definition#off-listener). ruby: off(&block) java: void off("ConnectionStateListener":#connection-state-listener listener) objc,swift: off(listener: ARTEventListener) - csharp: void Off(Action<"ConnectionStateChangeEventArgs":#connection-state-change> action) + csharp: void Off(Action<"ConnectionStateChange":#connection-state-change> action) Remove the given listener blockaction for all "ConnectionState":#connection-state states. @@ -598,7 +598,7 @@ h4. Parameters -
listener
:= is the listener function to be removed -
listener
:= is the listener to be removed
__Type: "@ConnectionStateListener@":#connection-state-listener__ --
action
:= action to be executed for matching state changes
__Type: "@ConnectionStateChangeEventArgs@":#connection-state-listener__ +-
action
:= action to be executed for matching state changes
__Type: "@ConnectionStateChange@":#connection-state-listener__ -
&block
:= is the listener block to be removed -
listener
:= previous return value from a @on@ or @once@ call From 878cb4bb82aee506ebb2778957e3d4bde097b1e9 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 8 Mar 2017 02:57:01 +0000 Subject: [PATCH 18/19] api: Java documentation fixes Fixes https://github.com/ably/docs/issues/264 --- content/realtime/authentication.textile | 4 ++-- content/realtime/channels-messages.textile | 5 +++-- content/realtime/connection.textile | 2 +- content/realtime/encryption.textile | 8 +++++--- content/realtime/types.textile | 2 +- content/realtime/usage.textile | 2 +- content/realtime/versions/v0.8/channels-messages.textile | 5 +++-- content/realtime/versions/v0.8/connection.textile | 2 +- content/realtime/versions/v0.8/encryption.textile | 8 +++++--- content/rest/authentication.textile | 4 ++-- content/rest/channels-messages.textile | 3 ++- content/rest/encryption.textile | 8 +++++--- content/rest/types.textile | 2 +- content/rest/usage.textile | 2 +- content/rest/versions/v0.8/channels-messages.textile | 3 ++- content/rest/versions/v0.8/encryption.textile | 8 +++++--- content/types/_cipher_params.textile | 2 +- content/types/versions/v0.8/_cipher_params.textile | 2 +- 18 files changed, 42 insertions(+), 30 deletions(-) diff --git a/content/realtime/authentication.textile b/content/realtime/authentication.textile index 52b0c417cb..7294eda56d 100644 --- a/content/realtime/authentication.textile +++ b/content/realtime/authentication.textile @@ -238,7 +238,7 @@ h6(#authorize). bq(definition). default: authorize("TokenParams":#token-params tokenParams, "AuthOptions":#auth-options authOptions, callback("ErrorInfo":/realtime/types#error-info err, "TokenDetails":#token-details tokenDetails)) ruby: "Deferrable":/realtime/types#deferrable authorize("TokenParams":#token-params token_params, "AuthOptions":#auth-options auth_options) -> yields "TokenDetails":#token-details - java: "TokenDetails":#token-details authorize("AuthOptions":#auth-options authOptions, "TokenParams":#token-params tokenParams) + java: "TokenDetails":#token-details authorize("TokenParams":#token-params tokenParams, "AuthOptions":#auth-options authOptions) csharp: "Task:#token-details AuthorizeAsync("TokenParams:#token-params?, "AuthOptions":#auth-options?) swift,objc: authorize(tokenParams: "ARTTokenParams":#token-params?, authOptions: "ARTAuthOptions":#auth-options?, callback: ("ARTTokenDetails":#token-details?, NSError?) -> Void) @@ -319,7 +319,7 @@ bc[jsall]. client.auth.authorize({ clientId: 'bob' }, function(err, tokenDetails bc[java]. try { TokenParams tokenParams = new TokenParams(); tokenParams.clientId = "bob"; - TokenDetails tokenDetails = client.auth.authorize(null, tokenParams); + TokenDetails tokenDetails = client.auth.authorize(tokenParams, null); System.out.println("Success; token = " + tokenDetails.token); } catch(AblyException e) { System.out.println("An error occurred; err = " + e.getMessage()); diff --git a/content/realtime/channels-messages.textile b/content/realtime/channels-messages.textile index b53b8338da..701b032683 100644 --- a/content/realtime/channels-messages.textile +++ b/content/realtime/channels-messages.textile @@ -143,7 +143,8 @@ bc[jsall]. Ably.Realtime.Crypto.generateRandomKey(function(err, key) { bc[java]. CipherParams params = Crypto.getDefaultParams(key); ChannelOptions options = new ChannelOptions(); -options.cipher = params; +options.encrypted = true; +options.cipherParams = params; Channel channel = realtime.channels.get("channelName", options); bc[csharp]. byte[] key = Crypto.GenerateRandomKey(); @@ -407,7 +408,7 @@ Previously registered listeners can be removed individually or all together. h3(#handling-failures). Handling channel failures -Channel attach and detach operations are synchronous - after initiating an attach request, the client must wait for a response from Ably that confirms that the channel is established on the service. +Channel attach and detach operations are asynchronous - after initiating an attach request, the client will wait for a response from Ably that confirms that the channel is established on the service and then trigger a state change event. The client libraries will attempt to automatically recover from non-fatal error conditions. However, you can handle them yourself if you prefer by subscribing to channel state changes, or using the callbacks availablewaiting for a result when explicitly calling @attach@. diff --git a/content/realtime/connection.textile b/content/realtime/connection.textile index b1623b77ea..c482f80f54 100644 --- a/content/realtime/connection.textile +++ b/content/realtime/connection.textile @@ -171,7 +171,7 @@ blang[jsall]. blang[java]. ```[java] - realtime.connection.on('connected', new ConnectionStateListener() { + realtime.connection.on(ConnectionEvent.connected, new ConnectionStateListener() { @Override public void onConnectionStateChanged(ConnectionStateChange change) { System.out.println("New state is connected"); diff --git a/content/realtime/encryption.textile b/content/realtime/encryption.textile index 91fd9631ab..c651457a2e 100644 --- a/content/realtime/encryption.textile +++ b/content/realtime/encryption.textile @@ -166,7 +166,8 @@ h4. Example ```[java] CipherParams params = Crypto.getDefaultParams(new Param[]{ new Param("key", ) }); ChannelOptions options = new ChannelOptions(); - options.cipher = params; + options.encrypted = true; + options.cipherParams = params; Channel channel = realtime.channels.get("{{RANDOM_CHANNEL_NAME}}", options); ``` @@ -205,8 +206,9 @@ This call obtains a randomly-generated binary key of the specified key length. h4. Parameters -- keyLength := Optional @Int@ with the length of key to generate. For AES, this should be either 128 or 256. If unspecified, defaults to 256. +- keyLengthkey_length := Optional @Int@ with the length of key to generate. For AES, this should be either 128 or 256. If unspecified, defaults to 256128. +-
mode
:= Optional AES @CipherMode@ which is used when the key is generated -
callback
:= is a function of the form @function(err, key)@ which is called upon completion blang[jsall]. @@ -266,7 +268,7 @@ h3(#channel-options). default: ChannelOptions Object objc,swift: ARTChannelOptions ruby: ChannelOptions Hash - java: io.ably.lib.types.ClientOptions + java: io.ably.types.ClientOptions csharp: IO.Ably.ClientOptions <%= partial 'types/_channel_options' %> diff --git a/content/realtime/types.textile b/content/realtime/types.textile index d493ffcb91..774e662c8c 100644 --- a/content/realtime/types.textile +++ b/content/realtime/types.textile @@ -170,7 +170,7 @@ h3(#client-options). default: ClientOptions Object objc,swift: ARTClientOptions ruby: ClientOptions Hash - java: io.ably.lib.types.ClientOptions + java: io.ably.types.ClientOptions csharp: IO.Ably.ClientOptions <%= partial 'types/_client_options' %> diff --git a/content/realtime/usage.textile b/content/realtime/usage.textile index 679f7629bf..081596e580 100644 --- a/content/realtime/usage.textile +++ b/content/realtime/usage.textile @@ -381,7 +381,7 @@ h2(#related-types). Related types h3(#client-options). default: ClientOptions swift,objc: ARTClientOptions - java: io.ably.lib.types.ClientOptions + java: io.ably.types.ClientOptions csharp: IO.Ably.ClientOptions <%= partial 'types/_client_options' %> diff --git a/content/realtime/versions/v0.8/channels-messages.textile b/content/realtime/versions/v0.8/channels-messages.textile index 165b1037b3..e61c63b09d 100644 --- a/content/realtime/versions/v0.8/channels-messages.textile +++ b/content/realtime/versions/v0.8/channels-messages.textile @@ -141,7 +141,8 @@ bc[jsall]. Ably.Realtime.Crypto.generateRandomKey(function(err, key) { bc[java]. CipherParams params = Crypto.getDefaultParams(key); ChannelOptions options = new ChannelOptions(); -options.cipher = params; +options.encrypted = true; +options.cipherParams = params; Channel channel = realtime.channels.get("channelName", options); bc[csharp]. byte[] key = Crypto.GenerateRandomKey(); @@ -372,7 +373,7 @@ Previously registered listeners can be removed individually or all together. h3(#handling-failures). Handling channel failures -Channel attach and detach operations are synchronous - after initiating an attach request, the client must wait for a response from Ably that confirms that the channel is established on the service. +Channel attach and detach operations are asynchronous - after initiating an attach request, the client will wait for a response from Ably that confirms that the channel is established on the service and then trigger a state change event. There are cases where an attach will fail deterministically, such as if the client doesn't have the necessary rights to access the channel. diff --git a/content/realtime/versions/v0.8/connection.textile b/content/realtime/versions/v0.8/connection.textile index 8da5b39293..7351089d98 100644 --- a/content/realtime/versions/v0.8/connection.textile +++ b/content/realtime/versions/v0.8/connection.textile @@ -167,7 +167,7 @@ blang[jsall]. blang[java]. ```[java] - realtime.connection.on('connected', new ConnectionStateListener() { + realtime.connection.on(ConnectionState.connected, new ConnectionStateListener() { @Override public void onConnectionStateChanged(ConnectionStateChange change) { System.out.println("New state is connected"); diff --git a/content/realtime/versions/v0.8/encryption.textile b/content/realtime/versions/v0.8/encryption.textile index d915af49b3..8fd86c8a71 100644 --- a/content/realtime/versions/v0.8/encryption.textile +++ b/content/realtime/versions/v0.8/encryption.textile @@ -164,7 +164,8 @@ h4. Example ```[java] CipherParams params = Crypto.getDefaultParams(new Param[]{ new Param("key", ) }); ChannelOptions options = new ChannelOptions(); - options.cipher = params; + options.encrypted = true; + options.cipherParams = params; Channel channel = realtime.channels.get("{{RANDOM_CHANNEL_NAME}}", options); ``` @@ -203,8 +204,9 @@ This call obtains a randomly-generated binary key of the specified key length. h4. Parameters -- keyLength := Optional @Int@ with the length of key to generate. For AES, this should be either 128 or 256. If unspecified, defaults to 256. +- keyLengthkey_length := Optional @Int@ with the length of key to generate. For AES, this should be either 128 or 256. If unspecified, defaults to 256128. +-
mode
:= Optional AES @CipherMode@ which is used when the key is generated -
callback
:= is a function of the form @function(err, key)@ which is called upon completion blang[jsall]. @@ -264,7 +266,7 @@ h3(#channel-options). default: ChannelOptions Object objc,swift: ARTChannelOptions ruby: ChannelOptions Hash - java: io.ably.lib.types.ClientOptions + java: io.ably.types.ClientOptions csharp: IO.Ably.ClientOptions <%= partial 'types/versions/v0.8/_channel_options' %> diff --git a/content/rest/authentication.textile b/content/rest/authentication.textile index 5ebdeecbc1..8dcfb69f91 100644 --- a/content/rest/authentication.textile +++ b/content/rest/authentication.textile @@ -263,7 +263,7 @@ bq(definition). ruby: "TokenDetails":#token-details authorize("TokenParams":#token-params token_params, "AuthOptions":#auth-options auth_options) python: "TokenDetails":#token-details authorize(token_params="TokenParams":#token-params, auth_options="AuthOptions":#auth-options) php: "TokenDetails":#token-details authorize("TokenParams":#token-params tokenParams, "AuthOptions":#auth-options authOptions) - java: "TokenDetails":#token-details authorize("AuthOptions":#auth-options authOptions, "TokenParams":#token-params tokenParams) + java: "TokenDetails":#token-details authorize("TokenParams":#token-params tokenParams, "AuthOptions":#auth-options authOptions) csharp: Task AuthorizeAsync("TokenParams":#token-params tokenParams = null, "AuthOptions":#auth-options options = null); swift,objc: authorize(tokenParams: "ARTTokenParams":#token-params?, authOptions: "ARTAuthOptions":#auth-options?, callback: ("ARTTokenDetails":#token-details?, NSError?) -> Void) @@ -316,7 +316,7 @@ bc[jsall]. client.auth.authorize({ clientId: 'bob' }, function(err, tokenDetails bc[java]. try { TokenParams tokenParams = new TokenParams(); tokenParams.clientId = "bob"; - TokenDetails tokenDetails = client.auth.authorize(null, tokenParams); + TokenDetails tokenDetails = client.auth.authorize(tokenParams, null); System.out.println("Success; token = " + tokenDetails.token); } catch(AblyException e) { System.out.println("An error occurred; err = " + e.getMessage()); diff --git a/content/rest/channels-messages.textile b/content/rest/channels-messages.textile index 977d4cc925..a7a3d8dddb 100644 --- a/content/rest/channels-messages.textile +++ b/content/rest/channels-messages.textile @@ -151,7 +151,8 @@ bc[jsall]. Crypto.generateRandomKey(function(err, key) { bc[java]. CipherParams params = Crypto.getDefaultParams(key); ChannelOptions options = new ChannelOptions(); -options.cipher = params; +options.encrypted = true; +options.cipherParams = params; Channel channel = rest.channels.get("channelName", options); bc[csharp]. CipherParams cipherParams = Crypto.GetDefaultParams(key); diff --git a/content/rest/encryption.textile b/content/rest/encryption.textile index a774c149fb..275b780085 100644 --- a/content/rest/encryption.textile +++ b/content/rest/encryption.textile @@ -175,7 +175,8 @@ h4. Example ```[java] CipherParams params = Crypto.getDefaultParams(new Param[]{ new Param("key", ) }); ChannelOptions options = new ChannelOptions(); - options.cipher = params; + options.encrypted = true; + options.cipherParams = params; Channel channel = rest.channels.get("{{RANDOM_CHANNEL_NAME}}", options); ``` @@ -215,8 +216,9 @@ This call obtains a randomly-generated binary key of the specified key lengthkeyLengthkey_length := Optional @Int@ with the length of key to generate. For AES, this should be either 128 or 256. If unspecified, defaults to 256. -- mode := Optional AES @CipherMode@ which is used when the key is generated +- keyLengthkey_length := Optional @Int@ with the length of key to generate. For AES, this should be either 128 or 256. If unspecified, defaults to 256128. + +-
mode
:= Optional AES @CipherMode@ which is used when the key is generated -
callback
:= is a function of the form @function(err, key)@ which is called upon completion blang[jsall]. diff --git a/content/rest/types.textile b/content/rest/types.textile index 0949df3fc9..063479add4 100644 --- a/content/rest/types.textile +++ b/content/rest/types.textile @@ -179,7 +179,7 @@ h3(#client-options). objc,swift: ARTClientOptions ruby: ClientOptions Hash php: ClientOptions Array - java: io.ably.lib.types.ClientOptions + java: io.ably.types.ClientOptions csharp: IO.Ably.ClientOptions <%= partial 'types/_client_options' %> diff --git a/content/rest/usage.textile b/content/rest/usage.textile index 74ffb15ad9..b050c33b44 100644 --- a/content/rest/usage.textile +++ b/content/rest/usage.textile @@ -342,7 +342,7 @@ h2(#related-types). Related types h3(#client-options). default: ClientOptions swift,objc: ARTClientOptions - java: io.ably.lib.types.ClientOptions + java: io.ably.types.ClientOptions csharp: IO.Ably.ClientOptions <%= partial 'types/_client_options' %> diff --git a/content/rest/versions/v0.8/channels-messages.textile b/content/rest/versions/v0.8/channels-messages.textile index 11e0422a05..0da5e962fd 100644 --- a/content/rest/versions/v0.8/channels-messages.textile +++ b/content/rest/versions/v0.8/channels-messages.textile @@ -139,7 +139,8 @@ bc[jsall]. Crypto.generateRandomKey(function(err, key) { bc[java]. CipherParams params = Crypto.getDefaultParams(key); ChannelOptions options = new ChannelOptions(); -options.cipher = params; +options.encrypted = true; +options.cipherParams = params; Channel channel = rest.channels.get("channelName", options); bc[csharp]. CipherParams cipherParams = Crypto.GetDefaultParams(key); diff --git a/content/rest/versions/v0.8/encryption.textile b/content/rest/versions/v0.8/encryption.textile index 56dff55c3e..5563f6f346 100644 --- a/content/rest/versions/v0.8/encryption.textile +++ b/content/rest/versions/v0.8/encryption.textile @@ -165,7 +165,8 @@ h4. Example ```[java] CipherParams params = Crypto.getDefaultParams(new Param[]{ new Param("key", ) }); ChannelOptions options = new ChannelOptions(); - options.cipher = params; + options.encrypted = true; + options.cipherParams = params; Channel channel = rest.channels.get("{{RANDOM_CHANNEL_NAME}}", options); ``` @@ -205,8 +206,9 @@ This call obtains a randomly-generated binary key of the specified key lengthkeyLengthkey_length := Optional @Int@ with the length of key to generate. For AES, this should be either 128 or 256. If unspecified, defaults to 256. -- mode := Optional AES @CipherMode@ which is used when the key is generated +- keyLengthkey_length := Optional @Int@ with the length of key to generate. For AES, this should be either 128 or 256. If unspecified, defaults to 256128. + +-
mode
:= Optional AES @CipherMode@ which is used when the key is generated -
callback
:= is a function of the form @function(err, key)@ which is called upon completion blang[jsall]. diff --git a/content/types/_cipher_params.textile b/content/types/_cipher_params.textile index 175c4488a4..979e2e69a3 100644 --- a/content/types/_cipher_params.textile +++ b/content/types/_cipher_params.textile @@ -10,7 +10,7 @@ h4. -
keyKey:key
:= A binary (@byte[]@@ArrayBuffer@ or @WordArray@@Buffer@byte array@NSData@) containing the secret key used for encryption and decryption - algorithm:algorithmAlgorithm := _AES_ The name of the algorithm in the default system provider, or the lower-cased version of it; eg "aes" or "AES"
__Type: @String@__ -- key_length:key_lengthkeyLengthKeyLength := _256_ The key length in bits of the cipher, either 128 or 256
__Type: @Integer@__ +- key_length:key_lengthkeyLengthKeyLength := _256__128_ The key length in bits of the cipher, either 128 or 256
__Type: @Integer@__ - mode:modeMode := _CBC_ The cipher mode
__Type: @String@@CipherMode@__ -
keySpec
:= A @KeySpec@ for the cipher key
__Type: @SecretKeySpec@__ diff --git a/content/types/versions/v0.8/_cipher_params.textile b/content/types/versions/v0.8/_cipher_params.textile index cfbdcb050c..8374a639bc 100644 --- a/content/types/versions/v0.8/_cipher_params.textile +++ b/content/types/versions/v0.8/_cipher_params.textile @@ -10,7 +10,7 @@ h4. -
keyKey:key
:= A binary (@byte[]@@ArrayBuffer@ or @WordArray@@Buffer@byte array@NSData@) containing the secret key used for encryption and decryption - algorithm:algorithmAlgorithm := _AES_ The name of the algorithm in the default system provider, or the lower-cased version of it; eg "aes" or "AES"
__Type: @String@__ -- key_length:key_lengthkeyLengthKeyLength := _256_ The key length in bits of the cipher, either 128 or 256
__Type: @Integer@__ +- key_length:key_lengthkeyLengthKeyLength := _256__128_ The key length in bits of the cipher, either 128 or 256
__Type: @Integer@__ - mode:modeMode := _CBC_ The cipher mode
__Type: @String@@CipherMode@__ -
keySpec
:= A @KeySpec@ for the cipher key
__Type: @SecretKeySpec@__ From 155fa738ceaef30137501a5329f041bb8047bfb8 Mon Sep 17 00:00:00 2001 From: Matthew O'Riordan Date: Wed, 8 Mar 2017 03:11:20 +0000 Subject: [PATCH 19/19] api: Updates for Ably-iOS library Fixes https://github.com/ably/ably-ios/issues/581 --- content/realtime/connection.textile | 6 ++--- .../realtime/versions/v0.8/connection.textile | 6 ++--- content/root/quick-start-guide.textile | 2 +- content/types/_auth_options.textile | 6 ++--- content/types/_connection_event.textile | 22 +++++++++---------- content/types/_token_request.textile | 4 ++-- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/content/realtime/connection.textile b/content/realtime/connection.textile index c482f80f54..94c2c3f4e0 100644 --- a/content/realtime/connection.textile +++ b/content/realtime/connection.textile @@ -70,7 +70,7 @@ ably.Connection.On(ConnectionState.Connected, args => { }); bc[objc]. ARTRealtime *ably = [[ARTRealtime alloc] initWithKey:@"{{API_KEY}}"]; -[ably.connection on:ARTRealtimeConnected call:^(ARTConnectionStateChange *change) { +[ably.connection on:ARTRealtimeConnectionEventConnected call:^(ARTConnectionStateChange *change) { NSLog(@"Connected, that was easy"); }]; @@ -255,7 +255,7 @@ blang[ruby]. blang[objc]. ```[objc] - ARTEventListener *listener = [realtime.connection on:ARTRealtimeConnected call:^(ARTConnectionStateChange *change) { + ARTEventListener *listener = [realtime.connection on:ARTRealtimeConnectionEventConnected call:^(ARTConnectionStateChange *change) { NSLog(@"Ably is connected"); }]; ``` @@ -272,7 +272,7 @@ blang[objc]. ```[objc] // remove a listener registered for a single event - [realtime.connection off:ARTRealtimeConnected listener:listener]; + [realtime.connection off:ARTRealtimeConnectionEventConnected listener:listener]; // remove a listener registered for all events [realtime.connection off:listener]; diff --git a/content/realtime/versions/v0.8/connection.textile b/content/realtime/versions/v0.8/connection.textile index 7351089d98..46dabcf2d7 100644 --- a/content/realtime/versions/v0.8/connection.textile +++ b/content/realtime/versions/v0.8/connection.textile @@ -70,7 +70,7 @@ ably.Connection.On(ConnectionState.Connected, args => { }); bc[objc]. ARTRealtime *ably = [[ARTRealtime alloc] initWithKey:@"{{API_KEY}}"]; -[ably.connection on:ARTRealtimeConnected call:^(ARTConnectionStateChange *change) { +[ably.connection on:ARTRealtimeConnectionEventConnected call:^(ARTConnectionStateChange *change) { NSLog(@"Connected, that was easy"); }]; @@ -251,7 +251,7 @@ blang[ruby]. blang[objc]. ```[objc] - ARTEventListener *listener = [realtime.connection on:ARTRealtimeConnected call:^(ARTConnectionStateChange *change) { + ARTEventListener *listener = [realtime.connection on:ARTRealtimeConnectionEventConnected call:^(ARTConnectionStateChange *change) { NSLog(@"Ably is connected"); }]; ``` @@ -268,7 +268,7 @@ blang[objc]. ```[objc] // remove a listener registered for a single event - [realtime.connection off:ARTRealtimeConnected listener:listener]; + [realtime.connection off:ARTRealtimeConnectionEventConnected listener:listener]; // remove a listener registered for all events [realtime.connection off:listener]; diff --git a/content/root/quick-start-guide.textile b/content/root/quick-start-guide.textile index a0a4cdb32e..2574be06af 100644 --- a/content/root/quick-start-guide.textile +++ b/content/root/quick-start-guide.textile @@ -146,7 +146,7 @@ ably.Connection.On(ConnectionState.Connected, args => }); bc[objc]. ARTRealtime *ably = [[ARTRealtime alloc] initWithKey:@"{{API_KEY}}"]; -[ably.connection on:ARTRealtimeConnected call:^(ARTConnectionStateChange *stateChange) { +[ably.connection on:ARTRealtimeConnectionEventConnected call:^(ARTConnectionStateChange *stateChange) { NSLog(@"That was simple, you're now connected to Ably in realtime"); }]; diff --git a/content/types/_auth_options.textile b/content/types/_auth_options.textile index 5fa51bb321..5fdf788ceb 100644 --- a/content/types/_auth_options.textile +++ b/content/types/_auth_options.textile @@ -21,13 +21,13 @@ h4. - authCallbackAuthCallbackauth_callback:auth_callback := A functionfunction with the form @function(tokenParams, callback(err, tokenOrTokenRequest))@@TokenCallback@ instancecallable (eg a lambda)proc / lambda (called synchronously in REST and Realtime but does not block EventMachine in the latter) which is called when a new token is required. The role of the callback is to either generate a signed "@TokenRequest@":/realtime/types#token-request which may then be submitted automatically by the library to the "Ably REST API @requestToken@":/rest-api#request-token; or to provide a valid token in as a "@TokenDetails@":/realtime/types#token-details object. See "an authentication callback example":<%= JsBins.url_for('authentication/auth-callback') %> or "our authentication documentation":/rest/authentication for details of the token request format and associated API calls.
__Type: @Callable@@TokenCallback@@Proc@@Func>@__ -- authUrlAuthUrl:auth_urlauth_url := A URL that the library may use to obtain a token string (in plain text format), or a signed "@TokenRequest@":/realtime/types#token-request or "@TokenDetails@":/realtime/types#token-details (in JSON format). For example, this can be used by a client to obtain signed token requests from an application server.
__Type: @String@@Uri@__ +- authUrlAuthUrl:auth_urlauth_url := A URL that the library may use to obtain a token string (in plain text format), or a signed "@TokenRequest@":/realtime/types#token-request or "@TokenDetails@":/realtime/types#token-details (in JSON format). For example, this can be used by a client to obtain signed token requests from an application server.
__Type: @String@@Uri@@NSURL@__ - authMethodAuthMethod:auth_methodauth_method := _@GET@@:get@_ The HTTP verb to use for the request, either @GET@@:get@ or @POST@@:post@
__Type: @String@@Symbol@@HttpMethod@__ -- authHeadersAuthHeaders:auth_headersauth_headers := A set of key value pair headers to be added to any request made to the @authUrl@@AuthUrl@. Useful when an application requires these to be added to validate the request or implement the response. If the @authHeaders@ object contains an @authorization@ key, then @withCredentials@ will be set on the xhr request.
__Type: @Object@@Hash@@Associative Array@@Param[]@@Dictionary@__ +- authHeadersAuthHeaders:auth_headersauth_headers := A set of key value pair headers to be added to any request made to the @authUrl@@AuthUrl@. Useful when an application requires these to be added to validate the request or implement the response. If the @authHeaders@ object contains an @authorization@ key, then @withCredentials@ will be set on the xhr request.
__Type: @Object@@Hash@@Associative Array@@Param[]@@Dictionary@@NSDictionary@@[String, String]/Dictionary@__ -- authParamsAuthParams:auth_paramsauth_params := A set of key value pair params to be added to any request made to the @authUrl@@AuthUrl@. When the @authMethod@@AuthMethod@ is @GET@, query params are added to the URL, whereas when @authMethod@@AuthMethod@ is @POST@, the params are sent as URL encoded form data. Useful when an application require these to be added to validate the request or implement the response.
__Type: @Object@@Hash@@Associative Array@@Param[]@@Dictionary@__ +- authParamsAuthParams:auth_paramsauth_params := A set of key value pair params to be added to any request made to the @authUrl@@AuthUrl@. When the @authMethod@@AuthMethod@ is @GET@, query params are added to the URL, whereas when @authMethod@@AuthMethod@ is @POST@, the params are sent as URL encoded form data. Useful when an application require these to be added to validate the request or implement the response.
__Type: @Object@@Hash@@Associative Array@@Param[]@@Dictionary@@NSArray@@[NSURLQueryItem]/Array@__ - keyKey:keykey := Optionally the "API key":https://support.ably.io/solution/articles/3000030054-what-is-an-app-api-key to use can be specified as a full key string; if not, the API key passed into "@ClientOptions@":#client-options when instancing the Realtime or REST library is used
__Type: @String@__ diff --git a/content/types/_connection_event.textile b/content/types/_connection_event.textile index 69fa236d08..8dea2f46e2 100644 --- a/content/types/_connection_event.textile +++ b/content/types/_connection_event.textile @@ -99,21 +99,21 @@ blang[objc,swift]. @ARTRealtimeConnectionEvent@ is an enum representing all the events that can be emitted be the @Connection@; either a "@Realtime Connection@ state":/realtime/connection#connection-states or an @Update@ event. ```[objc] - typedef NS_ENUM(NSUInteger, ARTRealtimeConnectionState) { - ARTRealtimeInitialized, - ARTRealtimeConnecting, - ARTRealtimeConnected, - ARTRealtimeDisconnected, - ARTRealtimeSuspended, - ARTRealtimeClosing, - ARTRealtimeClosed, - ARTRealtimeFailed, - ARTRealtimeUpdate + typedef NS_ENUM(NSUInteger, ARTRealtimeConnectionEvent) { + ARTRealtimeConnectionEventInitialized, + ARTRealtimeConnectionEventConnecting, + ARTRealtimeConnectionEventConnected, + ARTRealtimeConnectionEventDisconnected, + ARTRealtimeConnectionEventSuspended, + ARTRealtimeConnectionEventClosing, + ARTRealtimeConnectionEventClosed, + ARTRealtimeConnectionEventFailed, + ARTRealtimeConnectionEventUpdate }; ``` ```[swift] - public enum ARTRealtimeConnectionState : UInt { + public enum ARTRealtimeConnectionEvent : UInt { case Initialized case Connecting case Connected diff --git a/content/types/_token_request.textile b/content/types/_token_request.textile index 75e6cd2f6d..a726bda7c4 100644 --- a/content/types/_token_request.textile +++ b/content/types/_token_request.textile @@ -6,8 +6,8 @@ h4. ruby: Attributes - keyNamekey_nameKeyName := The key name of the key against which this request is made. The key name is public, whereas the key secret is private
__Type: @String@__ -- ttlTtl := Requested time to live for the token in millisecondsin secondsas a @TimeSpan@. If the token request is successful, the TTL of the returned token will be less than or equal to this value depending on application settings and the attributes of the issuing key.
__Type: @Integer@@TimeSpan@__ -- timestampTimestamp := The timestamp of this request in milliseconds
__Type: @Integer@@Long Integer@@Time@@DateTimeOffset@__ +- ttlTtl := Requested time to live for the token in millisecondsin secondsas a @TimeSpan@. If the token request is successful, the TTL of the returned token will be less than or equal to this value depending on application settings and the attributes of the issuing key.
__Type: @Integer@@TimeSpan@@NSTimeInterval@__ +- timestampTimestamp := The timestamp of this request in milliseconds
__Type: @Integer@@Long Integer@@Time@@DateTimeOffset@@NSDate@__ - capabilityCapability := Capability of the token. If the token request is successful, the capability of the returned token will be the intersection of this capability with the capability of the issuing key. The capability is a a JSON stringified canonicalized representation of the resource paths and associated operations. "Read more about authentication and capabilities":/realtime/authentication
__Type: @String@__ - clientIdclient_idClientId := The client ID to associate with this token. When provided, the token may only be used to perform operations on behalf of that client ID
__Type: @String@__ - nonceNonce := An opaque nonce string of at least 16 characters
__Type: @String@__