Skip to content
This repository was archived by the owner on Aug 10, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5ce9b0b
1.2 spec: add channel params, modes, M_ATTACH_RESUME flag
SimonWoolf Nov 12, 2019
a552687
1.2 Channel params: update per feedback
SimonWoolf Nov 14, 2019
028a2f2
Fix textile not rendering @foo@s correctly
SimonWoolf Nov 13, 2019
2828dae
Give example imlementation for ATTACH_RESUME
SimonWoolf Dec 13, 2019
964afe1
Protocolmessage.params: update spec item to avoid clash
SimonWoolf Dec 17, 2019
de1ece2
Squashing commits
tsviatko Nov 27, 2019
db654d7
Moving RSL6c to RTL18
tsviatko Dec 16, 2019
eef72bb
Fixes based on PR comments
tsviatko Dec 16, 2019
c77f8cd
Specifying RTL17 better
tsviatko Dec 17, 2019
3cc2dec
Fixes as per PR comments
tsviatko Dec 19, 2019
26381e4
Add addRequestIds client option
SimonWoolf Nov 6, 2019
1a9c567
Spec: item renumbering for TO3o conflict
SimonWoolf Jan 20, 2020
77ed027
Spec: fix whitespace
SimonWoolf Jan 20, 2020
582d8db
Spec: ChannelParams tweak to expose them in the attached for any way …
SimonWoolf Feb 6, 2020
9d04fd7
Spec: ChannelParams: clarify result when ATTACHED.params is missing
SimonWoolf Feb 7, 2020
f277c2f
Documenting the delta channel param
tsviatko Mar 9, 2020
4b74777
Fix markup.
Mar 23, 2020
7c3dfc2
Make changes suggested by Simon in PR #835, plus some other language/…
Mar 23, 2020
8e61396
Fix code indentation, including converting tabs to spaces, plus remov…
Mar 23, 2020
d09737f
Correct spec reference.
Mar 23, 2020
302df29
Update current version to 1.2 and freeze the pages that have changed …
Mar 23, 2020
8081076
Update current API version in the features spec (G4) including X-Ably…
Mar 23, 2020
7d31c26
Create features spec diff from 1.1 to 1.2.
Mar 23, 2020
adc2805
Add link to the 1.1 to 1.2 features spec diff to the features spec.
Mar 23, 2020
488b467
Reduce scope of Git ignore where specific files are being targeted re…
Mar 23, 2020
012d473
Remove beta caveat from code commentary.
Mar 23, 2020
1d7515c
Update the root docs gem spec version.
Mar 25, 2020
d77ab3a
Update Java and Android library version references.
Mar 25, 2020
41b5d6e
Update JavaScript library version references.
Mar 25, 2020
127a90c
Update X-Ably-Version headers.
Mar 25, 2020
bfaa586
Update version number in query strings.
Mar 25, 2020
b0b5adf
Update version number in SSE docs for the v query param.
Mar 25, 2020
9470cdb
Revert version increment that should have not been done because it wa…
Mar 25, 2020
da0ccf7
Update JSBin pointers.
Mar 31, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .gitignore
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
tmp
output
crash.log
/crash.log
.sass*
config/jsbin_config.yaml
package-lock.json
/config/jsbin_config.yaml
/package-lock.json
*.DS_Store
tags
94 changes: 81 additions & 13 deletions content/client-lib-development-guide/features.textile

Large diffs are not rendered by default.

285 changes: 285 additions & 0 deletions content/client-lib-development-guide/versions/features-1-1__1-2.diff

Large diffs are not rendered by default.

1,933 changes: 1,933 additions & 0 deletions content/client-lib-development-guide/versions/v1.1/features.textile

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion content/code/sse/eventstream.code
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
[--- Javascript ---]
var channel = "{{RANDOM_CHANNEL_NAME}}";
var apiKey = "{{API_KEY}}";
var url = "https://realtime.ably.io/event-stream?v=1.1&key=" + apiKey + "&channels=" + channel;
var url = "https://realtime.ably.io/event-stream?v=1.2&key=" + apiKey + "&channels=" + channel;

var xhttp = new XMLHttpRequest();

Expand Down
2 changes: 1 addition & 1 deletion content/code/sse/sse.code
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
[--- Javascript ---]
var channel = "{{RANDOM_CHANNEL_NAME}}";
var apiKey = "{{API_KEY}}";
var url = "https://realtime.ably.io/sse?v=1.1&key=" + apiKey + "&channels=" + channel;
var url = "https://realtime.ably.io/sse?v=1.2&key=" + apiKey + "&channels=" + channel;

var eventSource = new EventSource(url);
eventSource.onopen = function() {
Expand Down
2 changes: 1 addition & 1 deletion content/general/events/ifttt.textile
Original file line numberDiff line numberDiff line change
Expand Up@@ -65,7 +65,7 @@ x-ably-envelope-source: channel.message
x-ably-message-encoding: json
x-ably-message-id: {UNIQUE_ABLY_MESSAGE_ID}
x-ably-message-timestamp: {TIMESTAMP_ORIGINAL_MESSAGE_WAS_SENT}
x-ably-version: 1.0
x-ably-version: 1.2
content-length: 18
connection: keep-alive
```
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,4 +3,4 @@ Batched events will have the following headers:
- content-type := the type of the payload. This can be either @application/json@, @text/plain@, or @application/octet-stream@, depending on if it's @JSON@, @text@, or @binary@ respectively
- x-ably-envelope-appid := the "app ID":https://support.ably.io/support/solutions/articles/3000063083 which the message came from
- content-type := the type of the payload. This will be @application/json@ or @application/x-msgpack@
- x-ably-version := the version of Reactor Event. At present this should be @1.0@, though older Events will be @0.8@
- x-ably-version := the version of Reactor Event. At present this should be @1.2@
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
Enveloped events will have the following headers:

- content-type := the type of the payload. This can be either @application/json@, @text/plain@, or @application/octet-stream@, depending on if it's @JSON@, @text@, or @binary@ respectively
- x-ably-version := the version of Reactor Event. At present this should be @1.0@, though older Events will be @0.8@
- x-ably-version := the version of Reactor Event. At present this should be @1.2@
- x-ably-envelope-appid := the "app ID":https://support.ably.io/support/solutions/articles/3000063083 which the message came from
- content-type := the type of the payload. This will be @application/json@ or @application/x-msgpack@ for "enveloped":#envelope messages
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
Non-enveloped events have quite a few headers, in order to provide context to the data sent in the payload. These are:

- content-type := the type of the payload. This can be either @application/json@, @text/plain@, or @application/octet-stream@, depending on if it's @JSON@, @text@, or @binary@ respectively
- x-ably-version := the version of Reactor Event. At present this should be @1.0@, though older Events will be @0.8@
- x-ably-version := the version of Reactor Event. At present this should be @1.2@
- x-ably-envelope-appid := the "app ID":https://support.ably.io/support/solutions/articles/3000063083 which the message came from
- x-ably-envelope-channel := the Ably channel which the message came from
- x-ably-envelope-rule-id := the Ably Reactor Rule ID which was activated to send this message
Expand Down
114 changes: 110 additions & 4 deletions content/realtime/channel-params.textile
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,7 @@ h3. SSE example
For example, to specify the @rewind@ channel param with the value @"1"@ using a querystring parameter, where it will apply to all channels:

```[javascript]
var querystring = 'v=1.1&channels={{RANDOM_CHANNEL_NAME}}&rewind=1&key={{API_KEY}}';
var querystring = 'v=1.2&channels={{RANDOM_CHANNEL_NAME}}&rewind=1&key={{API_KEY}}';
var eventSource = new EventSource('https://realtime.ably.io/event-stream?' + querystring);
```

Expand All@@ -67,7 +67,7 @@ Or to specify the same parameter but only applying to one channel of two, using
var channelOne = encodeURIComponent('[?rewind=1]channel1');
var channelTwo = 'channel2';
var channels = channelOne + ',' + channelTwo;
var querystring = 'v=1.1&key={{API_KEY}}&channels=' + channels';
var querystring = 'v=1.2&key={{API_KEY}}&channels=' + channels';
var eventSource = new EventSource('https://realtime.ably.io/event-stream?' + querystring);
```

Expand DownExpand Up@@ -98,7 +98,7 @@ h3(#rewind-example-ably). Rewind example with an Ably client library
To subscribe to a channel, getting the most recent message if available:

```[jsall]
// only with ably-js v1.2 or later; currently in beta
// only with ably-js v1.2 or later
const realtime = new Ably.Realtime('{{API_KEY}}');
realtime.channels.get('{{RANDOM_CHANNEL_NAME}}', {
rewind: '1'
Expand All@@ -117,7 +117,7 @@ h3(#rewind-example-sse). Rewind example with SSE
To subscribe to a channel, getting the most recent message if available:

```[javascript]
var querystring = 'v=1.1&channels={{RANDOM_CHANNEL_NAME}}&rewind=1&key={{API_KEY}}';
var querystring = 'v=1.2&channels={{RANDOM_CHANNEL_NAME}}&rewind=1&key={{API_KEY}}';
var eventSource = new EventSource('https://realtime.ably.io/event-stream?' + querystring);
```

Expand All@@ -139,3 +139,109 @@ h3(#rewind-examples-mqtt). Rewind example with MQTT
...
});
```

h2(#delta). Delta parameter

The @delta@ channel parameter allows subscribers to expresse their desire to receive deltas (diffs) between the previous and current message instead of the current message in full on a given channel. The effects of this parameter are invisible to message senders and only affect subscribers that specify it - i.e. the sender sends messages in full and Ably computes and sends the message deltas to any subscriber which subscribed using this parameter.

Note that requesting deltas does not guarantee that every message received will be a delta, as the server may chose to send some messages in full depending on system load and other factors. Therefore a subscriber using the @delta@ parameter should be prepared to handle a random mix of delta and full messages.

The @delta@ parameter can take only the value @vcdiff@. VCDIFF is the format of the deltas. It is an open format specified in "RFC 3284":https://tools.ietf.org/html/rfc3284.

Ably provides a JavaScript "delta codec library":https://github.com/ably/delta-codec-js to help you avoid writing boilerplate VCDIFF handling code. Some examples follow.

h3(#delta-example-sse). Delta example with enveloped SSE

```[jsall]
const key = '{{API_KEY}}';
const channel = 'sample-app-sse';
const url = `https://realtime.ably.io/event-stream?channels=${channel}&v=1.2&key=${key}&delta=vcdiff`;
const eventSource = new EventSource(url);
const channelDecoder = new DeltaCodec.CheckedVcdiffDecoder();

eventSource.onmessage = (event) => {
/* event.data is JSON-encoded Ably Message (see https://www.ably.io/documentation/realtime/types#message) */
const message = JSON.parse(event.data);
const { id, extras } = message;
let { data } = message;

try {
if (extras && extras.delta) {
data = channelDecoder.applyBase64Delta(data, id, extras.delta.from).asUtf8String();
} else {
channelDecoder.setBase(data, id);
}
} catch(e) {
/* Delta decoder error */
console.log(e);
}

/* Process decoded data */
console.log(data);
};
```

h3(#delta-example-unenv-sse). Delta example with unenveloped SSE

```[jsall]
const key = '{{API_KEY}}';
const channel = 'sample-app-sse';
const url = `https://realtime.ably.io/event-stream?channels=${channel}&v=1.2&key=${key}&delta=vcdiff&enveloped=false`;
const eventSource = new EventSource(url);
const channelDecoder = new DeltaCodec.VcdiffDecoder();

eventSource.onmessage = (event) => {
let data = event.data;

try {
if (DeltaCodec.VcdiffDecoder.isBase64Delta(data)) {
data = channelDecoder.applyBase64Delta(data).asUtf8String();
} else {
channelDecoder.setBase(data);
}
} catch(e) {
/* Delta decoder error */
console.log(e);
}

/* Process decoded data */
console.log(data);
};
```

h3(#delta-example-mqtt). Delta example with MQTT

```[jsall]
const mqtt = require('mqtt');
const { VcdiffDecoder } = require('./lib');

const options = {
keepalive: 30,
username: 'FIRST_HALF_OF_API_KEY',
password: 'SECOND_HALF_OF_API_KEY',
port: 8883
};
const client = mqtt.connect('mqtts:mqtt.ably.io', options);
const channelName = 'sample-app-mqtt';
const channelDecoder = new VcdiffDecoder();

client.on('message', (_, payload) => {
let data = payload;

try {
if (VcdiffDecoder.isDelta(data)) {
data = channelDecoder.applyDelta(data).asUint8Array();
} else {
channelDecoder.setBase(data);
}
} catch(e) {
/* Delta decoder error */
console.log(e);
}

/* Process decoded data */
console.log(data);
});

client.subscribe(`[?delta=vcdiff]${channelName}`);
```
4 changes: 2 additions & 2 deletions content/realtime/usage.textile
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,13 +100,13 @@ blang[java].
For Java applications:

```[java]
compile 'io.ably:ably-java:1.0.0'
compile 'io.ably:ably-java:1.2.0'
```

For Android apps:

```[java]
compile 'io.ably:ably-android:1.0.0'
compile 'io.ably:ably-android:1.2.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.
Expand Down
141 changes: 141 additions & 0 deletions content/realtime/versions/v1.1/channel-params.textile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
---
title: Channel Parameters
section: realtime
index: 32
jump_to:
Help with:
- Overview#overview
- Using params with v1.1 or earlier Ably libraries#using-params-with-lib-v11
- Using params with non-Ably transports#using-params-with-other-transports
- Examples#examples
Parameters:
- rewind#rewind
---

h2(#overview). Overview

Channel parameters are a general mechanism by which a client can express properties of a channel, or of its attachment to a channel. A set of channel parameters is simply a set of key/value pairs, where both keys and values are strings; the keys correspond to specific features that Ably defines.

The methods provided for specifying channel parameters, and the currently available features, are outlined below.

h2(#supported-params). Currently supported channel params

- rewind := Used to request that an attachment start from some number of messages or point in time in the past. See "rewind":#rewind for more information
- delta := **In an experimental state**. Used to request that data payloads should be sent as deltas to the previous payload. "Contact us":https://www.ably.io/contact for more information and supported values

h2(#using-params-with-lib-v11). Using channel params with v1.1 or earlier Ably client libraries

The current Ably libraries, at version 1.1, do not expose an API for expressing channel parameters. This means that it is necessary to specify parameters in a way that is opaque to the library.

A set of params is expressed by including a query string, using standard URL query syntax and encoding, within the qualifier part of a channel name. The qualifier part is in square brackets at the start of the channel name.

For example, to specify the parameter @foo@ with value @bar@ on channel @baz@, the qualified channel name would be @[?foo=bar]baz@. If the channel name already has a qualifier, such as @[meta]log@, then the query string follows the existing qualifier, as in @[meta?foo=bar]log@.

Using this syntax with the Ably library means that channel parameters are specified for the lifetime of the @Channel@ instance; in order to reference the same channel, but with different channel parameters, it is necessary to get a new @Channel@ instance, using a qualified name that includes the new channel parameters.

h3. Example

For example, to specify the @rewind@ channel param with the value @"1"@:

```[javascript]
const realtime = new Ably.Realtime('{{API_KEY}}');
const channel = realtime.channels.get('[?rewind=1]{{RANDOM_CHANNEL_NAME}}');
```

h2(#using-params-with-other-transports). Using params with non-Ably transports

It is possible to interact with Ably channels using transports that do not involve using an Ably library; for example using SSE without any library, or using a supported non-Ably protocol such as MQTT. In these cases, it is also necessary to use a qualified channel name.

A set of params is expressed by including a query string, using standard URL query syntax and encoding, within the qualifier part of a channel name. The qualifier part is in square brackets at the start of the channel name.

For example, to specify the parameter @foo@ with value @bar@ on channel @baz@, the qualified channel name would be @[?foo=bar]baz@. If the channel name already has a qualifier, such as @[meta]log@, then the query string follows the existing qualifier, as in @[meta?foo=bar]log@.

In an SSE connection, it is also possible to specify channel parameters as a query string in the connection URL, instead of as a qualifier on an individual channel name. In this case, the given channel parameters apply to all channel attachments associated with that connection.

h3. SSE example

For example, to specify the @rewind@ channel param with the value @"1"@ using a querystring parameter, where it will apply to all channels:

```[javascript]
var querystring = 'v=1.1&channels={{RANDOM_CHANNEL_NAME}}&rewind=1&key={{API_KEY}}';
var eventSource = new EventSource('https://realtime.ably.io/event-stream?' + querystring);
```

Or to specify the same parameter but only applying to one channel of two, using a qualified channel name:

```[javascript]
var channelOne = encodeURIComponent('[?rewind=1]channel1');
var channelTwo = 'channel2';
var channels = channelOne + ',' + channelTwo;
var querystring = 'v=1.1&key={{API_KEY}}&channels=' + channels';
var eventSource = new EventSource('https://realtime.ably.io/event-stream?' + querystring);
```

h2(#rewind). Rewind parameter

The @rewind@ channel parameter relates to the initial attachment of a connection to a channel, and expresses the intent to attach to the channel at a position, or a point in time, in the past (that is, effectively "rewinding" the channel for the purposes of the present attachment).

A @rewind@ parameter can express a channel position in terms of a number of messages, or a time interval.

A @rewind@ value that is simply a number @n@ (eg @rewind=1@) is a request to attach to the channel at a position @n@ messages before the present position. If that attachment is successful, and one or more messages exist on the channel prior to the present position, then those messages will be delivered to the subscriber immediately after the attachment has completed, and before any subsequent messages that arise in real time.

If fewer than the requested number of messages exists on the channel (including the case that there are no prior messages), then the available messages are sent; this does not constitute an error.

A @rewind@ value can also be a string that is a time interval specifier. Supported specifier values express an integral number of seconds (eg @15s@) or minutes (eg @2m@). If that attachment is successful, and one or more messages exist on the channel in the given time interval prior to the present time, then those messages will be delivered to the subscriber immediately after the attachment has completed, and before any subsequent messages that arise in real time.

If you wish to use a time interval rewind but additionally specify a limit on the number of messages to be returned, you can use the @rewindLimit@ channel param. For example, to request up to 10 messages in a window 5m before the present time, specify a channel parameter string of @rewind=5m&rewindLimit=10@. If fewer than the requested number of messages exists on the channel in that interval (including the case that there are no messages), then the available messages are sent; this does not constitute an error.

At most 100 messages will be sent in a rewind request. If the number of messages within the specified interval is greater than that limit, then only the most recent messages up to that limit are sent. The attachment succeeds, but truncation of the message backlog is indicated as a non-fatal error in the attachment response.

By default, a maximum of two minutes of channel history is available when attaching. This means that a rewind time specifier of greater than two minutes will only be able to rewind by two minutes. If a channel has persistence enabled, then it is possible to rewind back in time by up to the persistence TTL on the channel.

The channel position expressed by a @rewind@ parameter has an effect only on an initial channel attachment. Any subsequent reattachment of the same channel on the same connection, in order to resume the connection, will attempt to resume with continuity from the point at which the connection dropped. (There are a few exceptions to this: in particular, client libraries earlier than v1.2 that have been disconnected for over two minutes, and all clients when using "@recover@ mode":/realtime/connection#connection-state-recovery ; in both cases the previous attachment state is not preserved).

Any @rewind@ parameter value that cannot be parsed either as a number or a time specifier represents an error, and any attachment request will fail with an error.

h3(#rewind-example-ably). Rewind example with an Ably client library

To subscribe to a channel, getting the most recent message if available:

```[jsall]
// only with ably-js v1.2 or later; currently in beta
const realtime = new Ably.Realtime('{{API_KEY}}');
realtime.channels.get('{{RANDOM_CHANNEL_NAME}}', {
rewind: '1'
}).subscribe(msg => console.log("Received message: ", msg));
```

```[jsall]
// with ably-js v1.1 or below
const realtime = new Ably.Realtime('{{API_KEY}}');
const channel = realtime.channels.get('[?rewind=1]{{RANDOM_CHANNEL_NAME}}');
channel.subscribe(msg => console.log("Received message: ", msg));
```

h3(#rewind-example-sse). Rewind example with SSE

To subscribe to a channel, getting the most recent message if available:

```[javascript]
var querystring = 'v=1.1&channels={{RANDOM_CHANNEL_NAME}}&rewind=1&key={{API_KEY}}';
var eventSource = new EventSource('https://realtime.ably.io/event-stream?' + querystring);
```

h3(#rewind-examples-mqtt). Rewind example with MQTT

```[nodejs]
var mqtt = require('mqtt');
var options = {
keepalive: 30,
username: 'FIRST_HALF_OF_API_KEY',
password: 'SECOND_HALF_OF_API_KEY',
port: 8883
};
var client = mqtt.connect('mqtts:mqtt.ably.io', options);
client.on('connect', () => {
client.subscribe('[?rewind=1]{{RANDOM_CHANNEL_NAME}}');
});
client.on('message', (topic, message) => {
...
});
```
6 changes: 3 additions & 3 deletions content/rest-api/index.textile
Original file line numberDiff line numberDiff line change
Expand Up@@ -147,14 +147,14 @@ By default, all requests receive the latest version of the API, which is current

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:
1. Include the @X-Ably-Version@ header. Example:

bc[sh]. curl https://rest.ably.io/time \
-H "X-Ably-Version: 1.0"
-H "X-Ably-Version: 1.2"

2. Include the version query string param @v@. Example:

bc[sh]. curl https://rest.ably.io/time?v=1.0
bc[sh]. curl https://rest.ably.io/time?v=1.2

h3(#pagination). Pagination

Expand Down
4 changes: 2 additions & 2 deletions content/rest/usage.textile
Original file line numberDiff line numberDiff line change
Expand Up@@ -126,13 +126,13 @@ blang[java].
For Java applications:

```[java]
compile 'io.ably:ably-java:1.0.0'
compile 'io.ably:ably-java:1.2.0'
```

For Android apps:

```[java]
compile 'io.ably:ably-android:1.0.0'
compile 'io.ably:ably-android:1.2.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.
Expand Down
Loading