Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Commit

Permalink
Update the README to match the current API.
Browse files Browse the repository at this point in the history
R=rnystrom@google.com
Closes #2

Review URL: https://codereview.chromium.org//899093003
  • Loading branch information
nex3 committed Feb 6, 2015
1 parent 809dba9 commit 8bf9eca
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 72 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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`.
Expand Down
171 changes: 100 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,89 +10,118 @@ These methods can be registered using `Server.registerMethod`:
```dart
import "package:json_rpc_2/json_rpc_2.dart" as json_rpc;
var server = new json_rpc.Server();
// 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;
});
```
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++;
});
Once you've registered your methods, you can handle requests with
`Server.parseRequest`:
// 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");
});
```dart
import 'dart:io';
// [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;
}
});
WebSocket.connect('ws://localhost:4321').then((socket) {
socket.listen((message) {
server.parseRequest(message).then((response) {
if (response != null) socket.add(response);
// 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();
});
});
}
```

If you're communicating with objects that haven't been serialized to a string,
you can also call `Server.handleRequest` directly:
## 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 'dart:isolate';
import "package:json_rpc_2/json_rpc_2.dart" as json_rpc;
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);
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();
});
})
}
```

## Client

Currently this package does not contain an implementation of a JSON-RPC 2.0
client.
## 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.
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit 8bf9eca

Please sign in to comment.