Update the README to match the current API.

R=rnystrom@google.com
Closes #2

Review URL: https://codereview.chromium.org//899093003
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1934fc0..a1bd217 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.1.1
+
+* Update the README to match the current API.
+
 ## 1.1.0
 
 * Add a `done` getter to `Client`, `Server`, and `Peer`.
diff --git a/README.md b/README.md
index 3d09d0f..67afc31 100644
--- a/README.md
+++ b/README.md
@@ -10,89 +10,118 @@
 ```dart
 import "package:json_rpc_2/json_rpc_2.dart" as json_rpc;
 
-var server = new json_rpc.Server();
+void main() {
+  WebSocket.connect('ws://localhost:4321').then((socket) {
+    // You can start the server with a Stream for requests and a StreamSink for
+    // responses, or with an object that's both, like a WebSocket.
+    var server = new json_rpc.Server(socket);
 
-// Any string may be used as a method name. JSON-RPC 2.0 methods are
-// case-sensitive.
-var i = 0;
-server.registerMethod("count", () {
-  // Just return the value to be sent as a response to the client. This can be
-  // anything JSON-serializable, or a Future that completes to something
-  // JSON-serializable.
-  return i++;
-});
-
-// Methods can take parameters. They're presented as a [Parameters] object which
-// makes it easy to validate that the expected parameters exist.
-server.registerMethod("echo", (params) {
-  // If the request doesn't have a "message" parameter, this will automatically
-  // send a response notifying the client that the request was invalid.
-  return params.getNamed("message");
-});
-
-// [Parameters] has methods for verifying argument types.
-server.registerMethod("subtract", (params) {
-  // If "minuend" or "subtrahend" aren't numbers, this will reject the request.
-  return params.getNum("minuend") - params.getNum("subtrahend");
-});
-
-// [Parameters] also supports optional arguments.
-server.registerMethod("sort", (params) {
-  var list = params.getList("list");
-  list.sort();
-  if (params.getBool("descending", orElse: () => false)) {
-    return params.list.reversed;
-  } else {
-    return params.list;
-  }
-});
-
-// A method can send an error response by throwing a `json_rpc.RpcException`.
-// Any positive number may be used as an application-defined error code.
-const DIVIDE_BY_ZERO = 1;
-server.registerMethod("divide", (params) {
-  var divisor = params.getNum("divisor");
-  if (divisor == 0) {
-    throw new json_rpc.RpcException(DIVIDE_BY_ZERO, "Cannot divide by zero.");
-  }
-
-  return params.getNum("dividend") / divisor;
-});
-```
-
-Once you've registered your methods, you can handle requests with
-`Server.parseRequest`:
-
-```dart
-import 'dart:io';
-
-WebSocket.connect('ws://localhost:4321').then((socket) {
-  socket.listen((message) {
-    server.parseRequest(message).then((response) {
-      if (response != null) socket.add(response);
+    // Any string may be used as a method name. JSON-RPC 2.0 methods are
+    // case-sensitive.
+    var i = 0;
+    server.registerMethod("count", () {
+      // Just return the value to be sent as a response to the client. This can
+      // be anything JSON-serializable, or a Future that completes to something
+      // JSON-serializable.
+      return i++;
     });
-  });
-});
-```
 
-If you're communicating with objects that haven't been serialized to a string,
-you can also call `Server.handleRequest` directly:
-
-```dart
-import 'dart:isolate';
-
-var receive = new ReceivePort();
-Isolate.spawnUri('path/to/client.dart', [], receive.sendPort).then((_) {
-  receive.listen((message) {
-    server.handleRequest(message['request']).then((response) {
-      if (response != null) message['respond'].send(response);
+    // Methods can take parameters. They're presented as a [Parameters] object
+    // which makes it easy to validate that the expected parameters exist.
+    server.registerMethod("echo", (params) {
+      // If the request doesn't have a "message" parameter, this will
+      // automatically send a response notifying the client that the request
+      // was invalid.
+      return params.getNamed("message");
     });
+
+    // [Parameters] has methods for verifying argument types.
+    server.registerMethod("subtract", (params) {
+      // If "minuend" or "subtrahend" aren't numbers, this will reject the
+      // request.
+      return params.getNum("minuend") - params.getNum("subtrahend");
+    });
+
+    // [Parameters] also supports optional arguments.
+    server.registerMethod("sort", (params) {
+      var list = params.getList("list");
+      list.sort();
+      if (params.getBool("descending", orElse: () => false)) {
+        return params.list.reversed;
+      } else {
+        return params.list;
+      }
+    });
+
+    // A method can send an error response by throwing a
+    // `json_rpc.RpcException`. Any positive number may be used as an
+    // application- defined error code.
+    const DIVIDE_BY_ZERO = 1;
+    server.registerMethod("divide", (params) {
+      var divisor = params.getNum("divisor");
+      if (divisor == 0) {
+        throw new json_rpc.RpcException(
+            DIVIDE_BY_ZERO, "Cannot divide by zero.");
+      }
+
+      return params.getNum("dividend") / divisor;
+    });
+
+    // To give you time to register all your methods, the server won't actually
+    // start listening for requests until you call `listen`.
+    server.listen();
   });
-})
+}
 ```
 
 ## Client
 
-Currently this package does not contain an implementation of a JSON-RPC 2.0
-client.
+A JSON-RPC 2.0 client calls methods on a server and handles the server's
+responses to those method calls. These methods can be called using
+`Client.sendRequest`:
 
+```dart
+import "package:json_rpc_2/json_rpc_2.dart" as json_rpc;
+
+void main() {
+  WebSocket.connect('ws://localhost:4321').then((socket) {
+    // Just like the server, a client takes a Stream and a StreamSink or a
+    // single object that's both.
+    var client = new json_rpc.Client(socket);
+
+    // This calls the "count" method on the server. A Future is returned that
+    // will complete to the value contained in the server's response.
+    client.sendRequest("count").then((result) => print("Count is $result."));
+
+    // Parameters are passed as a simple Map or, for positional parameters, an
+    // Iterable. Make sure they're JSON-serializable!
+    client.sendRequest("echo", {"message": "hello"})
+        .then((echo) => print('Echo says "$echo"!'));
+
+    // A notification is a way to call a method that tells the server that no
+    // result is expected. Its return type is `void`; even if it causes an
+    // error, you won't hear back.
+    client.sendNotification("count");
+
+    // If the server sends an error response, the returned Future will complete
+    // with an RpcException. You can catch this error and inspect its error
+    // code, message, and any data that the server sent along with it.
+    client.sendRequest("divide", {"dividend": 2, "divisor": 0})
+        .catchError((error) {
+      print("RPC error ${error.code}: ${error.message}");
+    });
+
+    // The client won't subscribe to the input stream until you call `listen`.
+    client.listen();
+  });
+}
+```
+
+## Peer
+
+Although JSON-RPC 2.0 only explicitly describes clients and servers, it also
+mentions that two-way communication can be supported by making each endpoint
+both a client and a server. This package supports this directly using the `Peer`
+class, which implements both `Client` and `Server`. It supports the same methods
+as those classes, and automatically makes sure that every message from the other
+endpoint is routed and handled correctly.
diff --git a/pubspec.yaml b/pubspec.yaml
index abc05ab..bf5939c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: json_rpc_2
-version: 1.1.0
+version: 1.1.1
 author: Dart Team <misc@dartlang.org>
 description: An implementation of the JSON-RPC 2.0 spec.
 homepage: http://github.com/dart-lang/json_rpc_2