Skip to content
This repository has been archived by the owner on Mar 12, 2019. It is now read-only.

V8 #2

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

V8 #2

Show file tree
Hide file tree
Changes from all commits
Commits
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
79 changes: 76 additions & 3 deletions protocol.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ endif::awestruct[]
{description}

Changes to this protocol are handled by incrementing an integer version
number. The current protocol, version 7, is documented here. Currently
number. The current protocol, version 8, is documented here. Currently
protocol 4 and later are supported by Pusher, however clients are encouraged
to keep up to date with changes.

Expand Down Expand Up @@ -61,12 +61,15 @@ used to determine what should happen to the payload.
[source,json]
----
{
"id": String,
"event": String,
"channel": String,
"data": String
}
----

id (Maybe String) ::
Event identifier unique per channel.
event (String) ::
Valid names must be alpha-numerical. The `pusher` prefix is reserved by
Pusher for protocol expansions.
Expand Down Expand Up @@ -410,7 +413,8 @@ Where the `data` field is a JSON-encoded hash of following format:
{
"channel": String,
"auth": String,
"channel_data": Object
"channel_data": Object,
"resume_after_id": String
}
----

Expand All @@ -427,7 +431,12 @@ data.channel_data (Object) [optional] ::
channel if the channel is a presence channel. The JSON for the
`channel_data` will be generated on the application server and should
simply be assigned to this property within the client library. The format
of the object is as follows:
of the object is as follows.
data.resume_after_id (String) [optional] ::
An event ID to resume the subscription from. If provided, Pusher will send
the next events after the given ID until it catches up with history. If
Pusher doesn't have that ID in store the `pusher:subscription_succeeded`
event will have a different event ID in its `resume_after_id` key value.

.Example JSON
[source,json]
Expand Down Expand Up @@ -523,6 +532,19 @@ Where the `data` field is empty except for presence channels.
}
----

Resume info will also be present.

.Resume data
[source,json]
----
{
"resume": {
"after_id": String,
"ok": Bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this give us enough information? Say it's false should there also be something to provide a bit more information?

With potential future changes in mind - without trying to think too far ahead - would a code be better? And would some sort of error description property be useful?

If it's always going to be a "it worked" or "it didn't" then clearly a boolean value is fine. I do think a description field may be useful though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDs are incremental (but not exposed as such to the user) so we can make a few assumptions.

Here are some possible errors:

  • The ID is not in store anymore, we know we used to but can't tell the user how many events in between belonged to that channel. We know that at most N events where lost.
  • The ID is in store but in a different channel
  • The ID is not in store and never was

I don't feel it's particularly helpful to say: "Nope, too late. There are at most N events missing but it's probably less."

Initially the key was named complete. I don't mind changing that back or to something else.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with ok: Bool as long as when ok: false occurs it's clear to the developer what they should do. Ideally they'll also get a why the error occurred.

The first thing I'd do is check for some kind of error code. Then maybe take a look at the library docs. If the protocol provided a bit more information about what the error was that'd be great.

So, if we think of it from a customer developer point of view:

pusher.subscribe( 'pusher:subscription_succeeded', function( status ) {
  if( status.resumed === false ) {
    // didn't expect to get in here
    console.error( status );
  }
} );

The JS console may then show something like

{
  resumed: false,
  resumeFailureReason: "Could not resume events from event ID EV_ID. Please retrieve any missed events from your own data store. For more information see: https://pusher.com/docs/event_resume"
}

Does that seem like a sensible workflow? Could we expose that error description via the protocol?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resume error is likely to happen often, I don't want to push a big string over the network when that happens. As a developer you would do something like that in any of these cases:

pusher.subscribe( 'pusher:subscription_succeeded', function( channel, sub ) {
  if( !sub.resume.ok ) {
    // we didn't get all the data, let's fetch the rest from the backend
    // here we need the last data and the newest
    // this assumes that the customer keeps all the pusher event ID, channel probably maps to a SQL table
    customerBackend.query(table: channel.name, from: channel.resumeFrom, to: sub.resume.from, function(data) {
      // update UI
    })
  }
} );

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
}
----

channel (String) ::
The presence channel name
data.presence.ids (Array) ::
Expand All @@ -531,6 +553,12 @@ data.presence.hash (Hash) ::
A hash of user IDs to object literals containing information about that user.
data.presence.count (Integer) ::
The number of users subscribed to the presence channel
data.resume.after_id (String) ::
The ID this subscription is going to resume after. If the requested
data is not available the ID will differ from the requested one.
data.resume.ok (Bool) ::
Returns true if Pusher was able to resume from the requested event ID.
False means one or more messages might be missing.

.Example JSON
[source,json]
Expand All @@ -556,6 +584,39 @@ data.presence.count (Integer) ::
}
----

=== `pusher_internal:subscription_failed` (Pusher -> Client)

The `pusher_internal:subscription_failed` event is sent when the subscription
to a channel couldn't complete for any reasons.

[source,json]
----
{
"event": "pusher:subscription_failed",
"channel": String,
"data": String
}
----

Where the `data` field is a JSON-encoded hash of following format:

[source,json]
----
{
"code": Integer,
"message": String
}
----

data.code (Integer) ::
An error code. The table of specified errors follows.
data.message (String) ::
Explanation in english of the error.

Some existing errors:

* 3000 : Authentication error
* 3001 : Resume not supported

=== `pusher:unsubscribe` (Client -> Pusher)

Expand Down Expand Up @@ -697,12 +758,15 @@ User events are user defined and associated with a single channel.
[source,json]
----
{
"id": String,
"event": String,
"channel": String,
"data": String
}
----

id (String) ::
Event identifier
event (String) ::
The name of the event
channel (String) ::
Expand Down Expand Up @@ -841,6 +905,15 @@ Any other type of error.
[[changelog]]
## CHANGELOG

=== Version 8 (???)

Published events now have an event ID associated to them.

Add a resume arguments to the subscription and subscription ack.

Add a `pusher_internal:subscription_failed` event to notify subscription
issues to the client.

=== Version 7 (2013-11)

The server now sends the activity timeout in the
Expand Down
117 changes: 113 additions & 4 deletions protocol.html
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ <h1>Pusher Protocol</h1>
</div>
<div class="paragraph">
<p>Changes to this protocol are handled by incrementing an integer version
number. The current protocol, version 7, is documented here. Currently
number. The current protocol, version 8, is documented here. Currently
protocol 4 and later are supported by Pusher, however clients are encouraged
to keep up to date with changes.</p>
</div>
Expand Down Expand Up @@ -466,6 +466,7 @@ <h1>Pusher Protocol</h1>
<li><a href="#pusher-pong"><code>pusher:pong</code> (Pusher &#8592;&#8594; Client)</a></li>
<li><a href="#pusher-subscribe"><code>pusher:subscribe</code> (Client &#8594; Pusher)</a></li>
<li><a href="#code-pusher_internal-subscription_succeeded-code-pusher-client"><code>pusher_internal:subscription_succeeded</code> (Pusher &#8594; Client)</a></li>
<li><a href="#code-pusher_internal-subscription_failed-code-pusher-client"><code>pusher_internal:subscription_failed</code> (Pusher &#8594; Client)</a></li>
<li><a href="#code-pusher-unsubscribe-code-client-pusher"><code>pusher:unsubscribe</code> (Client &#8594; Pusher)</a></li>
<li><a href="#code-pusher_internal-member_added-code-pusher-client"><code>pusher_internal:member_added</code> (Pusher &#8594; Client)</a></li>
<li><a href="#code-pusher_internal-member_removed-code-pusher-client"><code>pusher_internal:member_removed</code> (Pusher &#8594; Client)</a></li>
Expand All @@ -483,6 +484,7 @@ <h1>Pusher Protocol</h1>
</li>
<li><a href="#changelog">CHANGELOG</a>
<ul class="sectlevel2">
<li><a href="#version-8">Version 8 (???)</a></li>
<li><a href="#version-7-2013-11">Version 7 (2013-11)</a></li>
<li><a href="#version-6-2013-03">Version 6 (2013-03)</a></li>
<li><a href="#version-5-2012-01">Version 5 (2012-01)</a></li>
Expand Down Expand Up @@ -528,6 +530,7 @@ <h3 id="events">Events</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"id": String,
"event": String,
"channel": String,
"data": String
Expand All @@ -536,6 +539,10 @@ <h3 id="events">Events</h3>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">id (Maybe String) </dt>
<dd>
<p>Event identifier unique per channel.</p>
</dd>
<dt class="hdlist1">event (String) </dt>
<dd>
<p>Valid names must be alpha-numerical. The <code>pusher</code> prefix is reserved by
Expand Down Expand Up @@ -1041,7 +1048,8 @@ <h3 id="pusher-subscribe"><code>pusher:subscribe</code> (Client &#8594; Pusher)<
<pre class="highlight"><code class="language-json" data-lang="json">{
"channel": String,
"auth": String,
"channel_data": Object
"channel_data": Object,
"resume_after_id": String
}</code></pre>
</div>
</div>
Expand All @@ -1065,7 +1073,14 @@ <h3 id="pusher-subscribe"><code>pusher:subscribe</code> (Client &#8594; Pusher)<
channel if the channel is a presence channel. The JSON for the
<code>channel_data</code> will be generated on the application server and should
simply be assigned to this property within the client library. The format
of the object is as follows:</p>
of the object is as follows.</p>
</dd>
<dt class="hdlist1">data.resume_after_id (String) [optional] </dt>
<dd>
<p>An event ID to resume the subscription from. If provided, Pusher will send
the next events after the given ID until it catches up with history. If
Pusher doesn&#8217;t have that ID in store the <code>pusher:subscription_succeeded</code>
event will have a different event ID in its <code>resume_after_id</code> key value.</p>
</dd>
</dl>
</div>
Expand Down Expand Up @@ -1165,6 +1180,20 @@ <h3 id="code-pusher_internal-subscription_succeeded-code-pusher-client"><code>pu
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resume info will also be present.</p>
</div>
<div class="listingblock">
<div class="title">Resume data</div>
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"resume": {
"after_id": String,
"ok": Bool
}
}</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">channel (String) </dt>
Expand All @@ -1183,6 +1212,16 @@ <h3 id="code-pusher_internal-subscription_succeeded-code-pusher-client"><code>pu
<dd>
<p>The number of users subscribed to the presence channel</p>
</dd>
<dt class="hdlist1">data.resume.after_id (String) </dt>
<dd>
<p>The ID this subscription is going to resume after. If the requested
data is not available the ID will differ from the requested one.</p>
</dd>
<dt class="hdlist1">data.resume.ok (Bool) </dt>
<dd>
<p>Returns true if Pusher was able to resume from the requested event ID.
False means one or more messages might be missing.</p>
</dd>
</dl>
</div>
<div class="listingblock">
Expand Down Expand Up @@ -1211,6 +1250,58 @@ <h3 id="code-pusher_internal-subscription_succeeded-code-pusher-client"><code>pu
</div>
</div>
<div class="sect2">
<h3 id="code-pusher_internal-subscription_failed-code-pusher-client"><code>pusher_internal:subscription_failed</code> (Pusher &#8594; Client)</h3>
<div class="paragraph">
<p>The <code>pusher_internal:subscription_failed</code> event is sent when the subscription
to a channel couldn&#8217;t complete for any reasons.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"event": "pusher:subscription_failed",
"channel": String,
"data": String
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where the <code>data</code> field is a JSON-encoded hash of following format:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"code": Integer,
"message": String
}</code></pre>
</div>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">data.code (Integer) </dt>
<dd>
<p>An error code. The table of specified errors follows.</p>
</dd>
<dt class="hdlist1">data.message (String) </dt>
<dd>
<p>Explanation in english of the error.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Some existing errors:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>3000 : Authentication error</p>
</li>
<li>
<p>3001 : Resume not supported</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="code-pusher-unsubscribe-code-client-pusher"><code>pusher:unsubscribe</code> (Client &#8594; Pusher)</h3>
<div class="paragraph">
<p>The <code>pusher:unsubscribe</code> event is generated on the client and sent to Pusher
Expand Down Expand Up @@ -1378,6 +1469,7 @@ <h3 id="channel-events">User events (Pusher &#8594; Client)</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"id": String,
"event": String,
"channel": String,
"data": String
Expand All @@ -1386,6 +1478,10 @@ <h3 id="channel-events">User events (Pusher &#8594; Client)</h3>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">id (String) </dt>
<dd>
<p>Event identifier</p>
</dd>
<dt class="hdlist1">event (String) </dt>
<dd>
<p>The name of the event</p>
Expand Down Expand Up @@ -1601,6 +1697,19 @@ <h3 id="4300-4399">4300-4399</h3>
<h2 id="changelog">CHANGELOG</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="version-8">Version 8 (???)</h3>
<div class="paragraph">
<p>Published events now have an event ID associated to them.</p>
</div>
<div class="paragraph">
<p>Add a resume arguments to the subscription and subscription ack.</p>
</div>
<div class="paragraph">
<p>Add a <code>pusher_internal:subscription_failed</code> event to notify subscription
issues to the client.</p>
</div>
</div>
<div class="sect2">
<h3 id="version-7-2013-11">Version 7 (2013-11)</h3>
<div class="paragraph">
<p>The server now sends the activity timeout in the
Expand Down Expand Up @@ -1653,7 +1762,7 @@ <h3 id="version-1">Version 1</h3>
<div id="footer">
<div id="footer-text">
Version 1.0<br>
Last updated 2015-01-21 12:47:56 GMT
Last updated 2015-04-28 11:32:01 BST
</div>
</div>
</body>
Expand Down