Skip to content
Merged
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
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,26 @@ tracker](https://github.com/share/sharedb/issues).
- Projections to select desired fields from documents and operations
- Middleware for implementing access control and custom extensions
- Ideal for use in browsers or on the server
- Reconnection of document and query subscriptions
- Offline change syncing upon reconnection
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! It's high time this documentation be updated.

Choose a reason for hiding this comment

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

Actually, as per #121, this is correct.

When the WebSocket reconnects, the Connection middleware reconnects both documents and query subscriptions.

We might need more clear documentation, but this line is correct.

Choose a reason for hiding this comment

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

Perhaps a more clear wording would be - Reconnection of document and query subscriptions on socket reconnection (Check 'Reconnection' section below). Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

@pedrosanta I think that would be more clear. I'd welcome that addition here.

@nateps This PR seems to address a common source of frustration/confusion on ShareDB reconnection. Any chance it could be reviewed by the team?

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that the frequent confusion indicates we should change the wording.

However, I would like to highlight the fact that subscriptions state is re-established as soon as the connection resumes. This is a key feature of the ShareDB client.

I prefer the suggestion of more clear wording.

Copy link

@pedrosanta pedrosanta May 19, 2017

Choose a reason for hiding this comment

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

@mbalex99 I mean, if reconnection doesn't come out of the box, I think this line should also be removed, as it's misleading.

Choose a reason for hiding this comment

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

Actually I retract my comment, this actually happens too.

Ops are added to pending 'queue'/array and flushed/synced on socket reconnection.

This line is also correct.

Choose a reason for hiding this comment

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

Also, a better wording could be - Offline change syncing upon socket reconnection.

- In-memory implementations of database and pub/sub for unit testing

### Reconnection

**TLDR**
```javascript
const WebSocket = require('reconnecting-websocket');
var socket = new WebSocket('ws://' + window.location.host);
var connection = new sharedb.Connection(socket);
```

The native Websocket object that you feed to ShareDB's `Connection` constructor **does not** handle reconnections.

The easiest way is to give it a WebSocket object that does reconnect. There are plenty of example on the web. The most important thing is that the custom reconnecting websocket, must have the same API as the native rfc6455 version.

In the "textarea" example we show this off using a Reconnecting Websocket implementation from [https://github.com/pladaria/reconnecting-websocket](reconnecting-websocket).
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a great README addition, and it clarifies one way that ShareDB Connections support reconnection.

I'd also like to highlight that it is possible and intended that reconnection is implemented by calling Connection::bindToSocket() with a new WebSocket instance, as @DetweilerRyan pointed out. We've chosen not to implement reconnection logic in ShareDB, itself. There are other great libraries for that purpose, and application developers may need to leverage different libraries or custom logic depending on their requirements.

Reading the code of Reconnecting WebSocket, a significant amount of its complexity is necessitated by the constraint of exposing a single instance externally and internally creating new instances of WebSocket objects. If the reconnection logic of Reconnecting WebSocket implementation works for you, this is totally fine!

However, if you want to implement custom reconnection logic for your production environment (say you want to do backoff in a different way or fallback to other protocols or libraries), calling the ShareDB bindToSocket() with a new WebSocket or WebSocket-like instance might be simpler.




## Example apps

[<img src="examples/counter/demo.gif" height="300">
Expand Down
23 changes: 22 additions & 1 deletion examples/textarea/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,35 @@ var sharedb = require('sharedb/lib/client');
var StringBinding = require('sharedb-string-binding');

// Open WebSocket connection to ShareDB server
const WebSocket = require('reconnecting-websocket');
var socket = new WebSocket('ws://' + window.location.host);
var connection = new sharedb.Connection(socket);

var element = document.querySelector('textarea');
var statusSpan = document.getElementById('status-span');
status.innerHTML = "Not Connected"

element.style.backgroundColor = "gray";
socket.onopen = function(){
status.innerHTML = "Connected"
Copy link
Contributor

Choose a reason for hiding this comment

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

This is quite useful stuff!

element.style.backgroundColor = "white";
};

socket.onclose = function(){
status.innerHTML = "Closed"
element.style.backgroundColor = "gray";
};

socket.onerror = function() {
status.innerHTML = "Error"
element.style.backgroundColor = "red";
}

// Create local Doc instance mapped to 'examples' collection document with id 'textarea'
var doc = connection.get('examples', 'textarea');
doc.subscribe(function(err) {
if (err) throw err;
var element = document.querySelector('textarea');

var binding = new StringBinding(element, doc);
binding.setup();
});
1 change: 1 addition & 0 deletions examples/textarea/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"license": "MIT",
"dependencies": {
"express": "^4.14.0",
"reconnecting-websocket": "^3.0.3",
"sharedb": "^1.0.0-beta",
"sharedb-string-binding": "^1.0.0",
"websocket-json-stream": "^0.0.1",
Expand Down
6 changes: 6 additions & 0 deletions examples/textarea/static/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>ShareDB Textarea</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<style>
body {
background: #ddd;
Expand All @@ -19,9 +20,14 @@
width: 100%;
box-sizing: border-box;
}
#title {
font-size: 24;
}
</style>

<div id="container">
<h1 id="title">Text Area Example with Reconnecting Websockets</h1>
<p>Connection Status: <span id="status-span"></span></p>
<textarea autofocus></textarea>
</div>

Expand Down