diff --git a/.circleci/config.yml b/.circleci/config.yml index 38d656dad2..2722a83591 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -146,6 +146,12 @@ jobs: printf '.' sleep 1 done + - run: + name: Test nginx /docs rewriting + command: | + ./bin/assert-success.sh /docs + ./bin/assert-redirect.sh /docs/ https://localhost/docs + ./bin/assert-success.sh /docs/channels - run: name: Smoke test quickstart redirects command: | diff --git a/README.md b/README.md index 82f6aa7960..af95cf45d6 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,48 @@ Other one-off instances of redirects may be added to additional config files, an For how to create and include these redirects. +## Images + +Wherever possible, images should live in `src/images` and _not_ in `static/images`. The authors of Gatsby recommend [importing images](https://www.gatsbyjs.com/docs/how-to/images-and-media/importing-assets-into-files/) into components. The `static` folder in Gatsby is an escape hatch for the rare cases where files cannot be imported. + +The benefit of sticking to the Gatsby approach is that our images get processed and optimized during build time. It also allows us to serve our images over a CDN which is much better for our users. + +### Images in components + +Images in components can be imported and rendered as follows: + +~~~typescript +import myImage from 'src/path/to/my-image.png'; + +export default Component => (); +~~~ + +### Images in YAML data + +_TBD_ + +### Images in textfile files + +For rendering images in Textfile we have a special convention. + +Firstly, place the image file in `src/images/content`. The in the textile files reference it with a special path `@content`, for example: + +~~~textile + +~~~ + +The above will render the image at `src/images/content/path/to/image.png`. + +Content images in textile is powered by `ContentImagesProvider` and `useContentImages`. Templates rendering content need to add the following to their GraphQL queries to get all the images loaded before passing it to the `ContentImagesProvider`: + +~~~graphql + images: allFile(filter: { relativeDirectory: { glob: "content/**" } }) { + nodes { + ...ContentImage + } + } +~~~ + ## Environment Variables Note that any env variables needed to show in the browser must be prefixed with `GATSBY_` in order to appear. diff --git a/config/nginx.conf.erb b/config/nginx.conf.erb index ff86d157e5..2958e9c933 100644 --- a/config/nginx.conf.erb +++ b/config/nginx.conf.erb @@ -74,11 +74,12 @@ http { error_page 404 500 /404.html; - # Removes trailing slashes everywhere + # Removes trailing slashes everywhere (by redirecting) rewrite ^/(.*)/$ <%= ENV['SKIP_HTTPS'] == 'true' ? '$scheme' : 'https' %>://$host/$1 permanent; - # Strip /docs from the requests (we build with --prefix-paths) - rewrite ^/docs/(.*)$ /$1; + # Strip /docs from the requests (we build with --prefix-paths and our files are in public/) + rewrite ^/docs/(.*)$ /$1 last; + rewrite ^/docs$ / last; location ~* \.json$ { more_set_headers 'Access-Control-Allow-Origin: *'; diff --git a/content/account/control-api.textile b/content/account/control-api.textile index 1a8958114d..247fe96651 100644 --- a/content/account/control-api.textile +++ b/content/account/control-api.textile @@ -24,8 +24,8 @@ Repetitive operations such as creating, updating or deleting Ably apps, enumerat The following diagram illustrates an example use case: - - Provision and Test + + Provision and Test In this use case, Control API is used to provision a sample app for review and testing purposes. Once provisioned, the "realtime":/api/realtime-sdk or "REST API":/api/rest-api can be used to test the app as needed. Once fully tested, the Control API can be used to replicate the app for users as required, using the known-good configuration. @@ -48,14 +48,14 @@ Before you can use the Control API you must create an access token to authentica In the "Ably dashboard":https://ably.com/accounts/any, on the top menu bar, select your account from the dropdown list and then select "My Access Tokens" from the menu: - - My Settings + + My Settings You are presented with the "My Access Tokens" area, where you can create tokens for use with the Control API: - - My Settings + + My Settings h3(#creating-access-token). Creating an access token @@ -66,8 +66,8 @@ To create a new token, click the "Create new access token" button. Then enter th 2. Select the capabilities you wish the token to have, depending on your use case. 3. Click the "Create" button to create the token. - - My Settings + + My Settings h3(#using-access-token). Using the access token @@ -128,14 +128,14 @@ h3(#account-id). How to find your account ID In the "Ably dashboard":https://ably.com/accounts/any, on the top menu bar, select your account from the dropdown list and then select "Account settings": - - Account Settings + + Account Settings Your account settings are displayed. From here you can obtain your Ably account ID, as shown in the following screenshot: - - Account ID + + Account ID You'll need your account ID for account-level Control API requests, such as listing all the apps in your Ably account. @@ -144,8 +144,8 @@ h3(#app-id). How to find your app ID In the "Ably dashboard":https://ably.com/accounts/any select the app you want to find the app ID for. Click on the "Settings" tab: - - Application Settings + + Application Settings The "App ID" is displayed under "Application settings". It is also the first part of your API key for that app. For example, if your API key is @28AB6c.DEFi0Q@, then the App ID is @28AB6c@. You can find out more in the Ably Help Center article "what is an app API key?":/auth#api-key. @@ -681,26 +681,26 @@ A convenient way to try out the Control API is by importing the OpenAPI document 2. Start Postman and select "File > Import" from the main menu. The import dialog is displayed: - - Postman import dialog + + Postman import dialog 3. Click the "Link" tab, and paste in the following URL: @https://raw.githubusercontent.com/ably/open-specs/main/definitions/control-v1.yaml@, then click "Continue": - - Link to OpenAPI document + + Link to OpenAPI document 4. In the Import dialog, use the default settings and click "Import": - - Postman import default + + Postman import default 5. The imported document now appears in your Postman collections: - - Postman imported collection + + Postman imported collection You have now imported the OpenAPI document into Postman. @@ -715,30 +715,30 @@ Now that you have obtained the token and IDs, you can learn how to send a reques 1. Expand the collection to the @Lists account apps@ request. The following screenshot shows the parameters for the request: - - App list request + + App list request 2. The @Lists account apps@ request is an account-level operation and therefore requires your account ID in the @account_id@ path variable. This path variable is highlighted with the green box in the previous screenshot. Paste your Ably account ID into the "VALUE" field. 3. You also need to enter your Control API token as a @Bearer Token@ in the "Authorization" tab. Paste your Ably Control API token into the token field marked with the placeholder text @@, as shown in the following screenshot: - - Bearer token + + Bearer token *Note:* If you don't supply this token, your request will fail to authenticate. 4. Now that this request is configured, you can send the request by clicking the "Send" button: - - Send request + + Send request 5. The server returns a response, listing your Ably apps: - - Response + + Response You can now try out other requests. You need to set the necessary parameters and authentication token as required by that specific request. Consult the "API Reference":/api/control-api for further information. diff --git a/content/asset-tracking/example-apps.textile b/content/asset-tracking/example-apps.textile index e28d9977d3..4bef2324ec 100644 --- a/content/asset-tracking/example-apps.textile +++ b/content/asset-tracking/example-apps.textile @@ -24,43 +24,43 @@ blang[kotlin]. 1. Download and install "Android Studio":https://developer.android.com/studio, if not already available on your development system. 2. Make sure Android SDK build tools are installed. You'll need to accept the licenses. - - Installed SDK build tools + + Installed SDK build tools 3. Clone the Ably Asset Tracking SDK Android "GitHub repo":https://github.com/ably/ably-asset-tracking-android. 4. Open the cloned directory in Android Studio. 5. From the drop-down menu in Android Studio, select the app to run: @publishing-example-app@ and a device to run it on, then click Run. - - Select the publishing app + + Select the publishing app The app builds and the emulator is displayed. It takes a while to boot up. - 6. By default the location source that the app will use for updates is set to phone. Using the Settings button in the app you can also select an Ably channel, or an S3 file as the source. The S3 file is a location history file downloaded from AWS S3 that replays the location data. + 6. By default the location source that the app will use for updates is set to phone. Using the Settings button in the app you can also select an Ably channel, or an S3 file as the source. The S3 file is a location history file downloaded from AWS S3 that replays the location data. - - How to select location source + + How to select location source 7. Assuming you keep the default option, you can then create a simulated route in the Extended controls. In the emulator, use the Extended controls to create a route. This route is the simulated route that the publisher (asset) will follow. - - Extended controls + + Extended controls 8. Start the route. 9. In the publishing app click '+' to add a trackable. - 10. Enter a tracking ID and click Add. - 11. Run the subscribing app on an additional device. + 10. Enter a tracking ID and click Add. + 11. Run the subscribing app on an additional device. 12. Enter the tracking ID. 13. The asset will be displayed on the map. The following screenshot shows the example apps running: - - Example apps running + + Example apps running blang[swift]. @@ -71,8 +71,8 @@ blang[swift]. 5. In @Example/Secrets.xcconfig@, configure your @ABLY_API_KEY@ and @MAPBOX_ACCESS_TOKEN@. This is the public Mapbox token, which you can find on your Mapbox account's "token page":https://account.mapbox.com/access-tokens/. 6. Select the @PublisherExample@ scheme, choose an iOS simulator or device, and then press the run button. The following screen displays: - - Provide a tracking ID + + Provide a tracking ID 7. Click the Ask for location permissions button and grant the appropriate permissions. @@ -81,15 +81,15 @@ blang[swift]. 10. In the Simulator > Features > Location menu, select a sample route, such as "Freeway drive". 11. Click the Start publishing button. The publisher starts broadcasting location data for the selected route: - - Starting the Publisher Example app + + Starting the Publisher Example app 12. In Xcode, run the @SubscriberExample@ project, with a suitable target device. 13. When the target device loads, enter the same tracking ID that you provided in step 8 and click Start Tracking. The subscribing device receives updates from the publishing device and plots them on the map: - - Publisher and subscriber apps running together + + Publisher and subscriber apps running together blang[javascript]. @@ -97,7 +97,7 @@ blang[javascript]. 1. Clone the Ably Asset Tracking SDK JavaScript "GitHub repo":https://github.com/ably/ably-asset-tracking-js. 2. In the root directory of the project, install the SDK dependencies: - + ```[sh] npm install ``` @@ -109,7 +109,7 @@ blang[javascript]. ``` 4. Change into the @examples/subscribing-example-app@ directory and install the example app's dependencies: - + ```[sh] npm install ``` @@ -123,22 +123,22 @@ blang[javascript]. 6. Open your browser and visit @http://localhost:5000@: - - Select map provider + + Select map provider 7. Select your preferred map provider (Google Maps or Mapbox) and enter your provider's API key when prompted. 8. Enter the ID of the asset you want to track: - - Select trackable ID + + Select trackable ID 9. The example app receives updates from the publisher and shows the current location of the asset on the map: - - Example app running + + Example app running h2(#see-also). See also diff --git a/content/asset-tracking/index.textile b/content/asset-tracking/index.textile index abc2aca426..9c702339c7 100644 --- a/content/asset-tracking/index.textile +++ b/content/asset-tracking/index.textile @@ -25,7 +25,7 @@ The Ably Asset Tracking solution provides two "SDKs":/asset-tracking/using-the-s * **Publishing SDK** (Android, iOS) - for embedding in apps on the asset to be tracked. * **Subscribing SDK** (Android, iOS, JavaScript) - for embedding in apps that want to observe the asset being tracked using a realtime subscription. -As Ably is used as the underlying transport, you have direct access to your data and can use "Ably Integrations":/general/integrations for a wide range of applications, in addition to direct realtime subscriptions. Examples include: +As Ably is used as the underlying transport, you have direct access to your data and can use "Ably Integrations":/general/integrations for a wide range of applications, in addition to direct realtime subscriptions. Examples include: * Passing data to another service for realtime processing or tracking. * Persistence of data to a database for later retrieval. @@ -35,8 +35,8 @@ As the asset being tracked moves, it publishes its position through the app to a The following diagram provides an overview of an asset tracking use case: - - Overview + + Overview In a typical asset tracking scenario key components are: @@ -80,13 +80,13 @@ Resolution governs how often to sample locations, at what level of positional ac - @desiredInterval@ := Desired time between updates, in milliseconds. Lowering this value increases the temporal resolution. Location updates whose timestamp differs from the last captured update timestamp by less that this value are to be filtered out. Used to govern the frequency of updates requested from the underlying location provider, as well as the frequency of messages broadcast to subscribers. **Note:** For iOS, it is not possible to change the time interval for GPS resolution. It does however affect network resolution (how often location updates are sent to the subscribers). For further details see the "Apple documentation":https://developer.apple.com/documentation/corelocation/cllocationmanager. - @minimumDisplacement@ := Minimum positional granularity required, in metres. Lowering this value increases the spatial resolution. Location updates whose position differs from the last known position by a distance smaller than this value are to be filtered out. Used to configure the underlying location provider, as well as to filter the broadcast of updates to subscribers. -h3(#request-different-resolution). Request a different Resolution +h3(#request-different-resolution). Request a different Resolution The subscriber may require different resolutions of updates depending on state. For example, whether the map is currently displayed to the user or not, what zoom level the map is set to, and so on. This feature allows the subscriber to specify different preferences depending on any factors of interest to the client. h2(#resolution-set). Resolution set -A resolution set is a set of resolutions that, when provided, can be used by the resolution policy to create the best possible resolution for a given situation. +A resolution set is a set of resolutions that, when provided, can be used by the resolution policy to create the best possible resolution for a given situation. While developers can define their own resolution sets, Ably also provides a default resolution set that can be used with the default resolution policy. @@ -110,7 +110,7 @@ h3(#default-resolution-constraints). Default resolution constraints The SDK provides default resolution constraints consisting of: - @DefaultResolutionSet@ := The set of resolutions for values for proximity and number of active subscribers. -- @DefaultProximity@ := This is the proximity to the destination at which point the resolution from the @DefaultResolutionSet@ will be used. Proximity can be spatial, temporal, or both. +- @DefaultProximity@ := This is the proximity to the destination at which point the resolution from the @DefaultResolutionSet@ will be used. Proximity can be spatial, temporal, or both. - @batteryLevelThreshold@ := This is a battery level for the publisher's device that is considered to be low. When the battery level falls below this, the resolution of updates is reduced. - @lowBatteryMultiplier@ := The multiplier to be applied to the interval when the battery level is below @batteryLevelThreshold@. @@ -156,7 +156,7 @@ Ably Asset Tracking SDKs come with a @DefaultResolutionPolicy@ implementation pr Each @Trackable@ added to the @Publisher@ has a destination and set of @ResolutionConstraints@. Both @destination@ and @resolutionConstraints@ are optional for @Trackable@, but having them enables the resolution policy to reflect those constraints. The SDK provides an optional set of "default resolution constraints":#default-resolution-constraints, @DefaultResolutionContraints@. -When the SDK is running, on each change of the device or trackable status, the @ResolutionPolicy@ recalculates the resolution to be applied. Example changes include: +When the SDK is running, on each change of the device or trackable status, the @ResolutionPolicy@ recalculates the resolution to be applied. Example changes include: * Subscribers added or removed from the list of subscribers. * Battery or proximity threshold hit. @@ -171,8 +171,8 @@ The following logic is used: The following diagram illustrates the default resolution policy in the Ably Asset Tracking SDK: - - Default Resolution Policy + + Default Resolution Policy h4(#example-scenarios). Example scenarios diff --git a/content/auth/basic.textile b/content/auth/basic.textile index c525ea6419..b4bec6b05a 100644 --- a/content/auth/basic.textile +++ b/content/auth/basic.textile @@ -14,7 +14,7 @@ languages: - swift --- -Basic authentication is the simplest way to authenticate with Ably. It requires passing an "API key":/auth#api-key when instancing an SDK. +Basic authentication is the simplest way to authenticate with Ably. It requires passing an "API key":/auth#api-key when instancing an SDK. -blang[default]. +blang[default]. Message interactions are only supported by the Ably JavaScript SDK. blang[javascript,nodejs]. Message interactions are only supported by the Ably JavaScript SDK. - + To enable message interactions for a channel: @@ -82,8 +82,8 @@ blang[javascript,nodejs]. 5. Give your new rule a Namespace or provide a specific Channel ID. 6. Select the *Message interactions enabled* checkbox then click *Create channel rule*. - - Message interactions in dashboard + + Message interactions in dashboard You now have a namespace based rule you can apply to channels to enable message interactions or a specific channel with message interactions enabled. @@ -92,20 +92,20 @@ blang[javascript,nodejs]. Once message interactions have been enabled for a channel you can start to reference the @timeSerial@ of previous messages to publish interactions. All messages sent on channels that have interactions enabled will automatically include a @timeSerial@. - To reference a previous message, include the @ref@ object inside the @extras@ object with: + To reference a previous message, include the @ref@ object inside the @extras@ object with: * A @type@ constant string defining the reason for interaction. Note that Ably has reserved strings beginning with @com.ably.@. * The @timeserial@ string of the message to interact with. The following is an example of sending an emoji reaction: - ```[javascript] + ```[javascript] function sendReaction(emoji) { channel.publish({ name: 'event_name', data: emoji, extras: { ref: { type: "com.ably.reaction", timeserial: "1656424960320-1" } } }) } ``` - ```[nodejs] + ```[nodejs] function sendReaction(emoji) { channel.publish({ name: 'event_name', data: emoji, extras: { ref: { type: "com.ably.reaction", timeserial: "1656424960320-1" } } }) } @@ -125,55 +125,55 @@ blang[javascript,nodejs]. To subscribe to all reaction interactions: - ```[realtime_javascript] + ```[realtime_javascript] channel.subscribe({ refType: "com.ably.reaction" - }, onReaction); + }, onReaction); ``` - ```[realtime_nodejs] + ```[realtime_nodejs] channel.subscribe({ refType: "com.ably.reaction" - }, onReaction); + }, onReaction); ``` To subscribe to any interaction: - ```[realtime_javascript] + ```[realtime_javascript] channel.subscribe({ isRef: true - }, onReference); + }, onReference); ``` - ```[realtime_nodejs] + ```[realtime_nodejs] channel.subscribe({ isRef: true - }, onReference); + }, onReference); ``` To subscribe to any non-interaction: - ```[realtime_javascript] + ```[realtime_javascript] channel.subscribe({ - isRef: false + isRef: false }, onRegularMessage); ``` - ```[realtime_nodejs] + ```[realtime_nodejs] channel.subscribe({ - isRef: false + isRef: false }, onRegularMessage); ``` To subscribe to interactions to a specific message: - ```[realtime_javascript] + ```[realtime_javascript] channel.subscribe({ refTimeserial: "v1b25XrTDg:0" }, onReference); ``` - ```[realtime_nodejs] + ```[realtime_nodejs] channel.subscribe({ refTimeserial: "v1b25XrTDg:0" }, onReference); @@ -181,14 +181,14 @@ blang[javascript,nodejs]. To subscribe to a combination of filters: - ```[realtime_javascript] + ```[realtime_javascript] channel.subscribe({ refTimeserial: "v1b25XrTDg:0", refType: "com.ably.reaction", }, onReference); ``` - ```[realtime_nodejs] + ```[realtime_nodejs] channel.subscribe({ refTimeserial: "v1b25XrTDg:0", refType: "com.ably.reaction", @@ -204,13 +204,13 @@ blang[javascript,nodejs]. For example, to unsubscribe to reaction interactions: - ```[realtime_javascript] + ```[realtime_javascript] channel.unsubscribe({ refType: "com.ably.reaction" }); ``` - ```[realtime_nodejs] + ```[realtime_nodejs] channel.unsubscribe({ refType: "com.ably.reaction" }); diff --git a/content/channels/options/deltas.textile b/content/channels/options/deltas.textile index 471aa9bbdd..5074d5a4f4 100644 --- a/content/channels/options/deltas.textile +++ b/content/channels/options/deltas.textile @@ -14,7 +14,7 @@ redirect_from: - /realtime/channels/channel-parameters/deltas --- -The @delta@ channel option enables delta compression. It is applied on the channel you are subscribing to, enabling delta mode. +The @delta@ channel option enables delta compression. It is applied on the channel you are subscribing to, enabling delta mode. Delta mode is a way for a client to subscribe to a channel so that message payloads sent contain only the difference between the present message and the previous message sent on the channel. @@ -24,8 +24,8 @@ As @delta@ only applies to channel subscriptions, it is only available when usin Using delta mode can significantly reduce the encoded size of each message when the difference between successive message payload sizes are small, relative to the overall size. The reduction can reduce bandwidth costs and transit latencies, and enable greater message throughput on a connection. - - Deltas explanation + + Deltas explanation h2(#processing). Delta processing @@ -36,13 +36,13 @@ Messages retrieved via "history":/storage-history/history, and messages delivere The @delta@ channel option implementation supports a single representation of a delta, "VCDIFF":https://tools.ietf.org/html/rfc3284. -Delta compression via @vcdiff@ is supported for all payloads, whether string, binary, or JSON-encoded. The delta algorithm processes message payloads as opaque binaries and has no dependency on the structure of the payload, for example, it does not process line-oriented diffs. +Delta compression via @vcdiff@ is supported for all payloads, whether string, binary, or JSON-encoded. The delta algorithm processes message payloads as opaque binaries and has no dependency on the structure of the payload, for example, it does not process line-oriented diffs. As delta compression is specified by a subscriber, the publisher has no control over whether or not deltas are generated for any given message. Delta processing is performed for all messages if there is at least one subscriber on a channel that has subscribed with the @delta@ option. There is no constraint on how many publishers or subscribers there are. If there are multiple publishers, then deltas can still be generated, and they will be determined based on the order of messages. Deltas are calculated strictly based on the message ordering in that channel, with the effectiveness being dependent on the level of similarity between successive payloads. -If a delta is generated and it results in a difference that is not appreciably smaller than the original message, or is larger than the original message, for example if successive messages are completely different, then the delta will not be sent. Clients will receive the original, unprocessed message. +If a delta is generated and it results in a difference that is not appreciably smaller than the original message, or is larger than the original message, for example if successive messages are completely different, then the delta will not be sent. Clients will receive the original, unprocessed message. h2(#subscribe). Subscribe using delta @@ -60,10 +60,10 @@ Note that in some SDKs, the @vcdiff@ delta decoding library is excluded from the vcdiff: vcdiffDecoder } }); - realtime.channels.get('{{RANDOM_CHANNEL_NAME}}', { - params: { - delta: 'vcdiff' - } + realtime.channels.get('{{RANDOM_CHANNEL_NAME}}', { + params: { + delta: 'vcdiff' + } }).subscribe(msg => console.log("Received message: ", msg)); ``` @@ -75,10 +75,10 @@ Note that in some SDKs, the @vcdiff@ delta decoding library is excluded from the vcdiff: vcdiffPlugin } }); - realtime.channels.get('{{RANDOM_CHANNEL_NAME}}', { - params: { - delta: 'vcdiff' - } + realtime.channels.get('{{RANDOM_CHANNEL_NAME}}', { + params: { + delta: 'vcdiff' + } }).subscribe(msg => console.log("Received message: ", msg)); ``` diff --git a/content/general/aws-authentication.textile b/content/general/aws-authentication.textile index 2fa69daa4a..06a07d0806 100644 --- a/content/general/aws-authentication.textile +++ b/content/general/aws-authentication.textile @@ -51,8 +51,8 @@ The following steps show you how to create a policy for AWS Lambda. 1. In the IAM console sidebar select "Policies": - - Create policy + + Create policy 2. Click "Create Policy". @@ -86,8 +86,8 @@ The following steps show you how to create a policy for AWS Lambda. 6. Enter a suitable name for your policy: - - Review and create policy + + Review and create policy 7. Click "Create Policy". @@ -100,8 +100,8 @@ The following steps show you how to create a policy for AWS SQS. 1. In the IAM console sidebar select "Policies": - - Create policy + + Create policy 2. Click "Create Policy". @@ -154,8 +154,8 @@ The following steps show you how to create a policy for AWS Kinesis. 1. In the IAM console sidebar select "Policies": - - Create policy + + Create policy 2. Click "Create Policy". @@ -206,14 +206,14 @@ Create an IAM role as follows: 1. In the AWS IAM console, click "Roles" in the sidebar and then click the "Create Role" button: - - Create Role + + Create Role 2. For type of trusted entity select "Another AWS account": - - Select type of trusted entity + + Select type of trusted entity 3. For Account ID specify 203461409171. This is the Ably AWS account. @@ -224,8 +224,8 @@ Create an IAM role as follows: 6. Now select the policy you created earlier to attach to this role. You can type the name of your policy into the "Filter policies" search box: - - Select type of trusted entity + + Select type of trusted entity Then ensure the checkbox for the policy is selected. @@ -236,8 +236,8 @@ Then ensure the checkbox for the policy is selected. 9. Enter a suitable name for your role. - - Review and create Role + + Review and create Role 9. Click "Create Role". @@ -246,24 +246,24 @@ h3(#obtaining-the-arn). Obtaining the ARN of the role When setting up an Ably integration rule, you can copy the ARN for your rule using the button provided: - - Copy ARN + + Copy ARN h3(#using-the-arn). Using the ARN of the role When creating the Ably integration rule, enter the ARN of the rule created into the "Assume Role ARN" text field of the rule creation dialog: - - Assume ARN Role + + Assume ARN Role h2(#testing-rule). Testing the rule You can test your Ably rule by clicking "Test rule" in the Dashboard. If the test returns success you have the necessary AWS permissions in place and are correctly configured: - - Test rule + + Test rule h2(#see-also). See also diff --git a/content/general/firehose.textile b/content/general/firehose.textile index faecfba764..64e646a74b 100644 --- a/content/general/firehose.textile +++ b/content/general/firehose.textile @@ -27,18 +27,18 @@ redirect_from: Ably's Firehose can stream your realtime data published within the Ably platform directly to another streaming or queueing service. For example, all messages published by any device on a channel could be immediately streamed to Amazon Kinesis allowing you to process this data in realtime. Firehose is offered as part of "Ably Integrations":/general/integrations. -Using configurable rules, you can stream various "data-sources":#data-sources, including messages, presence events, occupancy, and channel lifecycle events. +Using configurable rules, you can stream various "data-sources":#data-sources, including messages, presence events, occupancy, and channel lifecycle events. Unlike "channels":/channels, which follow a "pub/sub pattern":https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern, where each message is delivered to any number of subscribers, Firehose operates such that each message is delivered once to your streaming or queueing server. -As each message is delivered once to your streaming or queueing server, this design is commonly used to process realtime data published by Ably asynchronously. For example, using workers consuming data from your stream or queue, you could persist each message of a live chat to your own database, start publishing updates once a channel becomes active, or trigger an event if a device has submitted a location that indicates that it has reached its destination. +As each message is delivered once to your streaming or queueing server, this design is commonly used to process realtime data published by Ably asynchronously. For example, using workers consuming data from your stream or queue, you could persist each message of a live chat to your own database, start publishing updates once a channel becomes active, or trigger an event if a device has submitted a location that indicates that it has reached its destination. Find out why Ably thinks streams and message queues help solve many of the challenges associated with consuming pub/sub data server-side in the article: "Message queues — the right way to process and work with realtime data on your servers":https://ably.com/blog/message-queues-the-right-way. Note that if you want to consume realtime data from a queue, you should take a look at "Ably Queues":/general/queues. They provide a simple and robust way to consume realtime data from your worker servers without having to worry about queueing infrastructure. - - Ably Firehose diagram + + Ably Firehose diagram h2(#data-sources). Data sources diff --git a/content/general/firehose/amqp-rule.textile b/content/general/firehose/amqp-rule.textile index c61f712e77..9d7f13e424 100644 --- a/content/general/firehose/amqp-rule.textile +++ b/content/general/firehose/amqp-rule.textile @@ -30,36 +30,36 @@ To create a rule in your "dashboard":https://ably.com/dashboard#58: 1. Login and select the application you wish to integrate with AMQP. 2. Click the *Integrations* tab. - - Integrations tab + + Integrations tab 3. Click the *+ New Integration Rule* button. 4. Choose Firehose. 5. Choose AMQP. - - Choose amqp + + Choose amqp 6. Configure the settings applicable to your use case and your AMQP installation. Header and authentication settings: - - amqp rule settings - header and auth + + amqp rule settings - header and auth The general settings: - - amqp rule settings - general + + amqp rule settings - general The AMQP-specific settings: - - amqp rule settings - amqp-specific + + amqp rule settings - amqp-specific 7. Click *Create* to create the rule. diff --git a/content/general/firehose/kafka-rule.textile b/content/general/firehose/kafka-rule.textile index 84297f6823..bf52c936aa 100644 --- a/content/general/firehose/kafka-rule.textile +++ b/content/general/firehose/kafka-rule.textile @@ -32,16 +32,16 @@ To create a rule in your "dashboard":https://ably.com/dashboard#58: 1. Login and select the application you wish to integrate with Kafka. 2. Click the *Integrations* tab. - - Integrations tab + + Integrations tab 3. Click the *+ New Integration Rule* button. 4. Choose Firehose. 5. Choose Kafka. - - Choose Kafka + + Choose Kafka 6. Configure the settings applicable to your use case and your Kafka installation. @@ -49,19 +49,19 @@ To create a rule in your "dashboard":https://ably.com/dashboard#58: The general settings: - - Kafka rule settings - general + + Kafka rule settings - general The Kafka-specific settings: - - Kafka rule settings - Kafka-specific + + Kafka rule settings - Kafka-specific -In this section you need to set up your Authentication for Kafka by selecting your preferred mechanism for authentication and providing credentials. +In this section you need to set up your Authentication for Kafka by selecting your preferred mechanism for authentication and providing credentials. -The supported Authentication Mechanisms are: +The supported Authentication Mechanisms are: * "SASL/PLAIN":https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_plain.html#kafka-sasl-auth-plain * "SASL/SCRAM-SHA-256":https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_scram.html#kafka-sasl-auth-scram diff --git a/content/general/firehose/kinesis-rule.textile b/content/general/firehose/kinesis-rule.textile index b0278d1528..1985b3c3df 100644 --- a/content/general/firehose/kinesis-rule.textile +++ b/content/general/firehose/kinesis-rule.textile @@ -30,37 +30,37 @@ To create a rule in your "dashboard":https://ably.com/dashboard#58: 1. Login and select the application you wish to integrate with Kinesis. 2. Click the *Integrations* tab. - - Integrations tab + + Integrations tab 3. Click the *+ New Integration Rule* button. 4. Choose Firehose. 5. Choose AWS Kinesis. - - Choose kinesis + + Choose kinesis 6. Configure the settings applicable to your use case and your Kinesis installation. The AWS Settings: - - kinesis rule settings - AWS + + kinesis rule settings - AWS The general settings: - - kinesis rule settings - general + + kinesis rule settings - general The Kinesis-specific settings: - - kinesis rule settings - kinesis-specific + + kinesis rule settings - kinesis-specific 7. Click *Create* to create the rule. diff --git a/content/general/firehose/pulsar-rule.textile b/content/general/firehose/pulsar-rule.textile index 93162b91e9..e46ace061c 100644 --- a/content/general/firehose/pulsar-rule.textile +++ b/content/general/firehose/pulsar-rule.textile @@ -35,30 +35,30 @@ To create a rule in your "dashboard":https://ably.com/dashboard#58: 1. Login and select the application you wish to integrate with Pulsar. 2. Click the *Integrations* tab. - - Integrations tab + + Integrations tab 3. Click the *+ New Integration Rule* button. 4. Choose Firehose. 5. Choose Pulsar. - - Choose Pulsar + + Choose Pulsar 6. Configure the settings applicable to your use case and your Pulsar installation. The general settings: - - Pulsar rule settings - general + + Pulsar rule settings - general The Pulsar-specific settings: - - Pulsar rule settings - Pulsar-specific + + Pulsar rule settings - Pulsar-specific 7. Click *Create* to create the rule. diff --git a/content/general/firehose/sqs-rule.textile b/content/general/firehose/sqs-rule.textile index 0b60d1498e..5c245168e1 100644 --- a/content/general/firehose/sqs-rule.textile +++ b/content/general/firehose/sqs-rule.textile @@ -30,30 +30,30 @@ To create a rule in your "dashboard":https://ably.com/dashboard#58: 1. Login and select the application you wish to integrate with SQS. 2. Click the *Integrations* tab. - - Integrations tab + + Integrations tab 3. Click the *+ New Integration Rule* button. 4. Choose Firehose. 5. Choose AWS SQS. - - Choose sqs + + Choose sqs 6. Configure the settings applicable to your use case and your SQS installation. The SQS-specific settings: - - sqs rule settings - sqs-specific + + sqs rule settings - sqs-specific The general settings: - - sqs rule settings - general + + sqs rule settings - general 7. Click *Create* to create the rule. diff --git a/content/general/kafka-connector.textile b/content/general/kafka-connector.textile index 13370de8c4..f2f3bcaba4 100644 --- a/content/general/kafka-connector.textile +++ b/content/general/kafka-connector.textile @@ -23,15 +23,15 @@ The Ably Kafka Connector is verified by Confluent as "Gold":https://www.confluen You can use the Ably Kafka Connector to send data from one or more "Kafka topics":https://developer.confluent.io/learn-kafka/apache-kafka/topics/ into Ably "channels":/channels. The following diagram illustrates a typical deployment: - - + Ably Kafka Connector overview h2(#how). How does the Ably Kafka Connector work? The Ably Kafka Connector is a sink connector built on top of Kafka Connect. It can be self-hosted or hosted with a third-party provider, the most common being the Confluent Platform. You can download it from either "GitHub":https://github.com/ably/kafka-connect-ably or "Confluent Hub":https://www.confluent.io/hub/ably/kafka-connect-ably and install it into your Kafka Connect workers. - + The Ably Kafka Connector provides a ready-made integration between Kafka and Ably via your Ably API key. Once installed, you can configure the connector with your Ably API key to enable data from one or more Kafka topics to be published into a single Ably channel or multiple Ably channels. Events are then distributed in realtime to web, mobile, and IoT clients over feature-rich, multi-protocol pub/sub Ably channels optimized for last-mile delivery. h2(#mapping-options). Mapping options @@ -80,7 +80,7 @@ View detailed instructions for installation on "GitHub":https://github.com/ably/ h2(#configure). Configure the connector -Configure the connector to set "properties":https://github.com/ably/kafka-connect-ably#configuration such as which Kafka topics to send data from, and which Ably channel should receive the data. +Configure the connector to set "properties":https://github.com/ably/kafka-connect-ably#configuration such as which Kafka topics to send data from, and which Ably channel should receive the data. Note that the configuration method differs depending on whether you are running a single or distributed set of "connect workers":https://docs.confluent.io/home/connect/self-managed/userguide.html#configuring-and-running-workers. diff --git a/content/general/push.textile b/content/general/push.textile index 349cd364ba..4d3fce1655 100644 --- a/content/general/push.textile +++ b/content/general/push.textile @@ -27,8 +27,8 @@ Ably can deliver push notifications to devices using, amongst others, "Apple's P h2(#deliver). Delivering push notifications - - Push Notifications in Ably + + Push Notifications in Ably As shown above, Ably provides two models for delivering push notifications to devices: diff --git a/content/general/push/activate-subscribe.textile b/content/general/push/activate-subscribe.textile index 4ec940f4f7..594f187a7a 100644 --- a/content/general/push/activate-subscribe.textile +++ b/content/general/push/activate-subscribe.textile @@ -23,8 +23,8 @@ redirect_from: Every device that will receive push notifications must register itself with the platform specific push notification service (APNs on iOS, FCM on Android). The Ably client libraries provide a consistent API for registration across all platforms, including device registration and receiving push notifications via Ably channels sent from other platforms. - - Push Notifications process using Ably + + Push Notifications process using Ably The client libraries also provide a set of admin functionality that is typically used server-side (in a trusted environment) to manage all devices and push notification delivery and subscriptions. You can find out more in the "push admin documentation":/general/push/admin. @@ -118,8 +118,8 @@ h2(#device-activation). Activating push on your device Activating a device for push notifications and registering it with Ably is commonly performed entirely from the device. However, it is possible to separate the concerns such that activation with the underlying platform is performed on the device, and registration of that activated device with Ably is performed using your own servers. This latter pattern is more commonly used when you want to minimize the capabilities assigned to an untrusted device. "Find out how to register the device from your servers":#activation-from-server - - Push Notifications direct device registration + + Push Notifications direct device registration In the following example, we will both activate the device with the underlying platform and register the device with Ably from the device itself. @@ -312,8 +312,8 @@ h2(#activation-from-server). Activating devices from your server The default for @AblyRealtime.push.activate@ is to register the device with Ably directly from the device, but you can instead delegate that to your server. Don't forget to register the device using the "push admin API":/general/push/admin in your server. - - Push Notifications device registration via server + + Push Notifications device registration via server diff --git a/content/general/push/publish.textile b/content/general/push/publish.textile index 5590d18ecd..8931e02ac2 100644 --- a/content/general/push/publish.textile +++ b/content/general/push/publish.textile @@ -26,8 +26,8 @@ redirect_from: Ably provides two models for delivering push notifications to devices. Channel-based broadcasting provides automatic fan-out capabilities for push notifications, and direct publishing provides a means to deliver individual notifications to devices. - - Push Notifications in Ably + + Push Notifications in Ably diff --git a/content/general/queues.textile b/content/general/queues.textile index aa94873b4d..16030b55e8 100644 --- a/content/general/queues.textile +++ b/content/general/queues.textile @@ -17,20 +17,20 @@ redirect_from: - /general/versions/v0.8/queues --- -Ably queues are traditional message queues that provide a reliable and straightforward mechanism for customers to consume, process, store, augment or reroute data from our realtime platform efficiently to your servers. +Ably queues are traditional message queues that provide a reliable and straightforward mechanism for customers to consume, process, store, augment or reroute data from our realtime platform efficiently to your servers. h2(#what). What are Ably Queues? -Ably Queues provide an asynchronous machine-to-machine communication protocol that follows a "traditional message queueing pattern":https://patterns.arcitura.com/soa-patterns/design_patterns/asynchronous_queuing. At a high level, each machine participates in one or both roles: producers (Ably channels) publish messages (data) to a queue; consumers retrieve messages from the queue. +Ably Queues provide an asynchronous machine-to-machine communication protocol that follows a "traditional message queueing pattern":https://patterns.arcitura.com/soa-patterns/design_patterns/asynchronous_queuing. At a high level, each machine participates in one or both roles: producers (Ably channels) publish messages (data) to a queue; consumers retrieve messages from the queue. -The queue service is responsible for the following functions: +The queue service is responsible for the following functions: * Storing published messages by placing them at the back of the queue. -* Retrieving the oldest messages from the front of the queue and passing them to a consumer. -* Ensuring a "FIFO or 'first in, first out'":https://en.wikipedia.org/wiki/FIFO policy is followed. -* Ensuring messages that are consumed successfully are only handed to one of the consumers. +* Retrieving the oldest messages from the front of the queue and passing them to a consumer. +* Ensuring a "FIFO or 'first in, first out'":https://en.wikipedia.org/wiki/FIFO policy is followed. +* Ensuring messages that are consumed successfully are only handed to one of the consumers. -This messaging pattern provides the following advantages: +This messaging pattern provides the following advantages: * Decoupling: publishers can publish without waiting for consumers. * Scalability: adding more consumers increases throughput capacity. @@ -38,16 +38,16 @@ This messaging pattern provides the following advantages: "Ably's platform":https://ably.com/platform also provides "channels":/channels for realtime data distribution using the pub/sub messaging pattern. Unlike queues, pub/sub channels provide fan-out so that every message published on a channel is received by all devices subscribed for that data. When delivered with "connection state recovery":/connect/states#connection-state-recovery, this pattern provides a decoupled, resilient and scalable means to publishing realtime data to any number of devices. -No single pattern is better than the other, both have their merits and valid use cases. Take for example a delivery van driving through a city publishing its location periodically. Any number of customers waiting for their parcel can subscribe for updates and thus a pub/sub channel is well suited due to its inherent fan-out capability. However, emails may need to be triggered when the van is nearing its destination as well. +No single pattern is better than the other, both have their merits and valid use cases. Take for example a delivery van driving through a city publishing its location periodically. Any number of customers waiting for their parcel can subscribe for updates and thus a pub/sub channel is well suited due to its inherent fan-out capability. However, emails may need to be triggered when the van is nearing its destination as well. -A message queueing pattern is a better fit here as multiple worker servers can share the workload by consuming the location messages from the queue and performing work for each message without having to share any state. +A message queueing pattern is a better fit here as multiple worker servers can share the workload by consuming the location messages from the queue and performing work for each message without having to share any state. The message queue ensures that work is distributed evenly to the pool of servers, work is not duplicated (resulting for example in more than one email notification being sent) and the system is resilient to crashes or spikes in load (messages are stored until a consumer is ready to retrieve them). Ably combines both pub/sub and queueing functionality in its "platform":https://ably.com/platform as illustrated in the diagram below: - - Ably Queues overview + + Ably Queues overview **Note:** It's not a requirement for this scenario, but Ably has the "Asset Tracking SDK":https://ably.com/solutions/asset-tracking, which can provide a complete and convenient asset tracking solution. You can read more about what's provided in the "Asset Tracking SDK docs":/asset-tracking. @@ -90,14 +90,14 @@ The procedure to provision a queue is as follows: 2. Click the **Provision a new Queue** button: - - Provision an Ably queue + + Provision an Ably queue 3. Fill out information for your queue in the **New Queue** dialog, and click **Create**: - - New Queue dialog + + New Queue dialog 4. Confirm your queue has been provisioned. Your new queue will appear in the **Queues** tab along with realtime metrics for your queue. @@ -124,14 +124,14 @@ The procedure to create a queue rule is as follows: 2. Click the **New Integration Rule** button: - - New Integration Rule + + New Integration Rule 3. Now choose an Ably Queue: - - Choose Ably Queue + + Choose Ably Queue 4. Fill out information as detailed previously in this section, and then click **Create**. @@ -140,14 +140,14 @@ h3(#dashboard-stats). Queue dashboards and stats Provisioned queues are visible in your app "dashboard":https://ably.com/dashboard and provide near-realtime stats for the current state of each queue. See an example screenshot below: - - Queue dashboard example + + Queue dashboard example Whilst the queue dashboard stats show the current state of your queue, your app and account dashboard provide up-to-date live and historical stats for all messages published to your queues. See an example screenshot from an "app dashboard":https://ably.com/dashboard below: - - App stats example + + App stats example h3(#testing-rules). Testing your queue rules @@ -212,8 +212,8 @@ However, unlike our pub/sub channels, queues are pre-provisioned via our queue d Take the following queue as an example: - - Queue dashboard example + + Queue dashboard example In order to subscribe to messages from this queue you will need: @@ -271,8 +271,8 @@ The STOMP protocol is a simple text-based protocol designed for working with mes Assuming the following queue has been set up, we'll show you a simple example of subscribing to a STOMP queue: - - Queue dashboard example + + Queue dashboard example In order to subscribe to messages from this queue you will need: diff --git a/content/general/webhooks.textile b/content/general/webhooks.textile index 54e8519622..bca74f6c68 100644 --- a/content/general/webhooks.textile +++ b/content/general/webhooks.textile @@ -40,11 +40,11 @@ If you want to be notified as events arise, trigger serverless functions, or inv In addition, various existing systems, such as Azure Functions, Google Functions, and AWS Lambda rely on HTTP events. Webhooks enable you to integrate with "these systems":#integrations. - - Ably Webhooks Overview + + Ably Webhooks Overview -You can configure integration rules from the **Integrations** tab in your "dashboard":https://ably.com/dashboard on a per-app basis which can apply to one or more channels in that app. +You can configure integration rules from the **Integrations** tab in your "dashboard":https://ably.com/dashboard on a per-app basis which can apply to one or more channels in that app. Integration rules can filter by channel naming using a regular expression, for example @^click_.*_mouse$@. This would match the string @click_@ followed by a string followed by @_mouse@, for example, @click_left_mouse@. diff --git a/content/livesync/examples/examples.textile b/content/livesync/examples/examples.textile index 79d455bfa5..2f4048745b 100644 --- a/content/livesync/examples/examples.textile +++ b/content/livesync/examples/examples.textile @@ -4,18 +4,16 @@ nmeta_description: "A realtime comments application, built with LiveSync, demons product: livesync --- -The following example is realtime comments application, built with LiveSync, showing interactive user communication. Active users contribute their thoughts and feedback by creating new comments. Users also have the flexibility to edit and delete their previously posted comments. +The following example is realtime comments application, built with LiveSync, showing interactive user communication. Active users contribute their thoughts and feedback by creating new comments. Users also have the flexibility to edit and delete their previously posted comments. - - LiveSync live comments example + + LiveSync live comments example When a user adds, edits, or deletes a comment, the updates are stored in a "Postgres":https://www.postgresql.org/ database. The "Database Connector":/livesync/connector uses an outbox pattern to broadcast the changes from the database to the frontend client. The "Models SDK":/livesync/models is subscribed to changes in the database's state and updates the frontend client. These updates are immediately reflected in the application's user interface in realtime. - - diff --git a/content/livesync/index.textile b/content/livesync/index.textile index b2f9c1fd30..5faec0ead7 100644 --- a/content/livesync/index.textile +++ b/content/livesync/index.textile @@ -12,8 +12,8 @@ LiveSync is made up of two key components: The following diagram provides a simplified overview of the LiveSync solution: - - What is LiveSync + + What is LiveSync h2(#db-connector). Database Connector diff --git a/content/livesync/models/index.textile b/content/livesync/models/index.textile index b7a8ee0943..e1b2f00152 100644 --- a/content/livesync/models/index.textile +++ b/content/livesync/models/index.textile @@ -10,8 +10,8 @@ The "Ably Models SDK":https://github.com/ably-labs/models is a standalone SDK bu The following diagram provides a simplified overview of the Models SDK: - - Models SDK optimistic update + + Models SDK optimistic update