Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(428)

Side by Side Diff: pkg/json_rpc_2/lib/src/peer.dart

Issue 707063002: Add a Peer class to json_rpc_2. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/json_rpc_2/lib/src/client.dart ('k') | pkg/json_rpc_2/lib/src/server.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library json_rpc_2.peer;
6
7 import 'dart:async';
8
9 import '../error_code.dart' as error_code;
10 import 'client.dart';
11 import 'exception.dart';
12 import 'parameters.dart';
13 import 'server.dart';
14 import 'two_way_stream.dart';
15
16 /// A JSON-RPC 2.0 client *and* server.
17 ///
18 /// This supports bidirectional peer-to-peer communication with another JSON-RPC
19 /// 2.0 endpoint. It sends both requests and responses across the same
20 /// communication channel and expects to connect to a peer that does the same.
21 class Peer implements Client, Server {
22 TwoWayStream _streams;
23
24 /// The underlying client that handles request-sending and response-receiving
25 /// logic.
26 Client _client;
27
28 /// The underlying server that handles request-receiving and response-sending
29 /// logic.
30 Server _server;
31
32 /// A stream controller that forwards incoming messages to [_server] if
33 /// they're requests.
34 final _serverIncomingForwarder = new StreamController(sync: true);
35
36 /// A stream controller that forwards incoming messages to [_client] if
37 /// they're responses.
38 final _clientIncomingForwarder = new StreamController(sync: true);
39
40 /// A stream controller that forwards outgoing messages from both [_server]
41 /// and [_client].
42 final _outgoingForwarder = new StreamController(sync: true);
43
44 /// Creates a [Peer] that reads incoming messages from [incoming] and writes
45 /// outgoing messages to [outgoing].
46 ///
47 /// If [incoming] is a [StreamSink] as well as a [Stream] (for example, a
48 /// `WebSocket`), [outgoing] may be omitted.
49 ///
50 /// Note that the peer won't begin listening to [incoming] until [Peer.listen]
51 /// is called.
52 Peer(Stream<String> incoming, [StreamSink<String> outgoing]) {
53 _streams = new TwoWayStream("Peer", incoming, "incoming",
54 outgoing, "outgoing", onInvalidInput: (message, error) {
55 _streams.add(new RpcException(error_code.PARSE_ERROR,
56 'Invalid JSON: ${error.message}').serialize(message));
57 });
58
59 _outgoingForwarder.stream.listen(_streams.add);
60 _server = new Server.withoutJson(
61 _serverIncomingForwarder.stream, _outgoingForwarder);
62 _client = new Client.withoutJson(
63 _clientIncomingForwarder.stream, _outgoingForwarder);
64 }
65
66 /// Creates a [Peer] that reads incoming decoded messages from [incoming] and
67 /// writes outgoing decoded messages to [outgoing].
68 ///
69 /// Unlike [new Peer], this doesn't read or write JSON strings. Instead, it
70 /// reads and writes decoded maps or lists.
71 ///
72 /// If [incoming] is a [StreamSink] as well as a [Stream], [outgoing] may be
73 /// omitted.
74 ///
75 /// Note that the peer won't begin listening to [incoming] until
76 /// [Peer.listen] is called.
77 Peer.withoutJson(Stream incoming, [StreamSink outgoing]) {
78 _streams = new TwoWayStream.withoutJson("Peer", incoming, "incoming",
79 outgoing, "outgoing");
80
81 _outgoingForwarder.stream.listen(_streams.add);
82 _server = new Server.withoutJson(
83 _serverIncomingForwarder.stream, _outgoingForwarder);
84 _client = new Client.withoutJson(
85 _clientIncomingForwarder.stream, _outgoingForwarder);
86 }
87
88 // Client methods.
89
90 Future sendRequest(String method, [parameters]) =>
91 _client.sendRequest(method, parameters);
92
93 void sendNotification(String method, [parameters]) =>
94 _client.sendNotification(method, parameters);
95
96 withBatch(callback()) => _client.withBatch(callback);
97
98 // Server methods.
99
100 void registerMethod(String name, Function callback) =>
101 _server.registerMethod(name, callback);
102
103 void registerFallback(callback(Parameters parameters)) =>
104 _server.registerFallback(callback);
105
106 // Shared methods.
107
108 Future listen() {
109 _client.listen();
110 _server.listen();
111 return _streams.listen((message) {
112 if (message is Map) {
113 if (message.containsKey('result') || message.containsKey('error')) {
114 _clientIncomingForwarder.add(message);
115 } else {
116 _serverIncomingForwarder.add(message);
117 }
118 } else if (message is List && message.isNotEmpty &&
119 message.first is Map) {
120 if (message.first.containsKey('result') ||
121 message.first.containsKey('error')) {
122 _clientIncomingForwarder.add(message);
123 } else {
124 _serverIncomingForwarder.add(message);
125 }
126 } else {
127 // Non-Map and -List messages are ill-formed, so we pass them to the
128 // server since it knows how to send error responses.
129 _serverIncomingForwarder.add(message);
130 }
131 });
132 }
133
134 Future close() =>
135 Future.wait([_client.close(), _server.close(), _streams.close()]);
136 }
OLDNEW
« no previous file with comments | « pkg/json_rpc_2/lib/src/client.dart ('k') | pkg/json_rpc_2/lib/src/server.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698