Skip to content

Commit 6d79a47

Browse files
committed
Improved reverse rpc.
1 parent 70d5d3c commit 6d79a47

11 files changed

+132
-81
lines changed

lib/src/rpc/codec/jsonrpc_service_codec.dart

+1-9
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,12 @@ class JsonRpcServiceCodec implements ServiceCodec {
121121
if (method.hasNamedArguments) {
122122
n = ppl + 1;
123123
}
124-
if (count > n) {
125-
args.length = n;
126-
}
127124
if (method.contextInPositionalArguments) {
128125
ppl--;
129126
n--;
130127
}
131128
n = min(count, n);
129+
args.length = n;
132130
for (var i = 0; i < n; ++i) {
133131
if (i < ppl) {
134132
args[i] = Formatter.deserialize(Formatter.serialize(args[i]),
@@ -152,15 +150,9 @@ class JsonRpcServiceCodec implements ServiceCodec {
152150
namedArgs[Symbol(key)] = value;
153151
}
154152
}
155-
if (method.contextInNamedArguments) {
156-
namedArgs[Symbol('context')] = context;
157-
}
158153
args[i] = namedArgs;
159154
}
160155
}
161-
if (method.contextInPositionalArguments) {
162-
args[ppl] = context;
163-
}
164156
}
165157
return RequestInfo(name, args);
166158
}

lib/src/rpc/core/client.dart

+11-11
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,27 @@ class _Proxy {
4141
}
4242

4343
@override
44-
dynamic noSuchMethod(Invocation mirror) {
45-
var name = _namespace + _getName(mirror.memberName);
46-
if (mirror.isGetter) {
44+
dynamic noSuchMethod(Invocation invocation) {
45+
var name = _namespace + _getName(invocation.memberName);
46+
if (invocation.isGetter) {
4747
return _Proxy(_client, name);
4848
}
49-
if (mirror.isMethod) {
49+
if (invocation.isMethod) {
5050
var type = dynamic;
51-
if (mirror.typeArguments.isNotEmpty) {
52-
type = mirror.typeArguments.first;
51+
if (invocation.typeArguments.isNotEmpty) {
52+
type = invocation.typeArguments.first;
5353
}
5454
ClientContext context;
5555
var args = [];
56-
if (mirror.positionalArguments.isNotEmpty) {
57-
args.addAll(mirror.positionalArguments);
56+
if (invocation.positionalArguments.isNotEmpty) {
57+
args.addAll(invocation.positionalArguments);
5858
if (args.last is Context) {
5959
context = args.removeLast();
6060
}
6161
}
62-
if (mirror.namedArguments.isNotEmpty) {
62+
if (invocation.namedArguments.isNotEmpty) {
6363
var namedArgs = <String, dynamic>{};
64-
mirror.namedArguments.forEach((name, value) {
64+
invocation.namedArguments.forEach((name, value) {
6565
namedArgs[_getName(name)] = value;
6666
});
6767
if (namedArgs.containsKey('context') &&
@@ -76,7 +76,7 @@ class _Proxy {
7676
context.returnType = type;
7777
return _client.invoke(name, args, context);
7878
}
79-
super.noSuchMethod(mirror);
79+
super.noSuchMethod(invocation);
8080
}
8181
}
8282

lib/src/rpc/core/client_context.dart

+12-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
| |
99
| ClientContext for Dart. |
1010
| |
11-
| LastModified: Mar 28, 2019 |
11+
| LastModified: Mar 28, 2020 |
1212
| Author: Ma Bingyao <[email protected]> |
1313
| |
1414
\*________________________________________________________*/
@@ -41,16 +41,20 @@ class ClientContext extends Context {
4141
requestHeaders.addAll(client.requestHeaders);
4242
}
4343

44+
@override
45+
void copyTo(Context context) {
46+
super.copyTo(context);
47+
final clientContext = context as ClientContext;
48+
clientContext.client = client;
49+
clientContext.uri = uri;
50+
clientContext.returnType = returnType;
51+
clientContext.timeout = timeout;
52+
}
53+
4454
@override
4555
Context clone() {
4656
final context = ClientContext();
47-
context.client = client;
48-
context.uri = uri;
49-
context.returnType = returnType;
50-
context.timeout = timeout;
51-
context.items.addAll(items);
52-
context.requestHeaders.addAll(requestHeaders);
53-
context.responseHeaders.addAll(responseHeaders);
57+
copyTo(context);
5458
return context;
5559
}
5660
}

lib/src/rpc/core/context.dart

+7-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
| |
99
| hprose Context for Dart. |
1010
| |
11-
| LastModified: Dec 31, 2019 |
11+
| LastModified: Mar 28, 2020 |
1212
| Author: Ma Bingyao <[email protected]> |
1313
| |
1414
\*________________________________________________________*/
@@ -38,11 +38,15 @@ class Context {
3838
}
3939
}
4040

41-
Context clone() {
42-
final context = Context();
41+
void copyTo(Context context) {
4342
context.items.addAll(items);
4443
context.requestHeaders.addAll(requestHeaders);
4544
context.responseHeaders.addAll(responseHeaders);
45+
}
46+
47+
Context clone() {
48+
final context = Context();
49+
copyTo(context);
4650
return context;
4751
}
4852
}

lib/src/rpc/core/method.dart

+10-5
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,21 @@
88
| |
99
| Method for Dart. |
1010
| |
11-
| LastModified: Mar 20, 2020 |
11+
| LastModified: Mar 28, 2020 |
1212
| Author: Ma Bingyao <[email protected]> |
1313
| |
1414
\*________________________________________________________*/
1515

1616
part of hprose.rpc.core;
1717

1818
class Method {
19+
static final List<String> _contextTypes = ['Context', 'ServiceContext'];
20+
static registerContextType(String contextType) {
21+
if (!_contextTypes.contains(contextType)) {
22+
_contextTypes.add(contextType);
23+
}
24+
}
25+
1926
final Function method;
2027
String name;
2128
final List<String> positionalParameterTypes = [];
@@ -41,13 +48,11 @@ class Method {
4148
_parseParameters(method);
4249
if (!hasOptionalArguments && !hasNamedArguments) {
4350
if (positionalParameterTypes.isNotEmpty &&
44-
(positionalParameterTypes.last == 'Context' ||
45-
positionalParameterTypes.last == 'ServiceContext')) {
51+
_contextTypes.contains(positionalParameterTypes.last)) {
4652
passContext = true;
4753
contextInPositionalArguments = true;
4854
}
49-
} else if (namedParameterTypes['context'] == 'Context' ||
50-
namedParameterTypes['context'] == 'ServiceContext') {
55+
} else if (_contextTypes.contains(namedParameterTypes['context'])) {
5156
passContext = true;
5257
contextInNamedArguments = true;
5358
}

lib/src/rpc/core/service.dart

+6
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,15 @@ class Service {
109109
return Function.apply(method.method, [name, args]);
110110
}
111111
if (method.namedParameterTypes.isEmpty) {
112+
if (method.contextInPositionalArguments) {
113+
args.add(context);
114+
}
112115
return Function.apply(method.method, args);
113116
}
114117
final namedArguments = args.removeLast();
118+
if (method.contextInNamedArguments) {
119+
namedArguments[Symbol('context')] = context;
120+
}
115121
return Function.apply(method.method, args, namedArguments);
116122
}
117123

lib/src/rpc/core/service_codec.dart

+1-7
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ class DefaultServiceCodec extends ServiceCodec {
9898
if (method.hasNamedArguments) {
9999
n = ppl + 1;
100100
}
101-
var args = List<dynamic>.filled(n, null, growable: true);
102101
if (method.contextInPositionalArguments) {
103102
ppl--;
104103
n--;
105104
}
105+
var args = List<dynamic>.filled(n, null, growable: true);
106106
n = min(count, n);
107107
for (var i = 0; i < n; ++i) {
108108
if (i < ppl) {
@@ -132,15 +132,9 @@ class DefaultServiceCodec extends ServiceCodec {
132132
}
133133
}
134134
stream.readByte();
135-
if (method.contextInNamedArguments) {
136-
namedArgs[Symbol('context')] = context;
137-
}
138135
args[i] = namedArgs;
139136
}
140137
}
141-
if (method.contextInPositionalArguments) {
142-
args[ppl] = context;
143-
}
144138
return args;
145139
}
146140

lib/src/rpc/core/service_context.dart

+11-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
| |
99
| ServiceContext for Dart. |
1010
| |
11-
| LastModified: Dec 31, 2019 |
11+
| LastModified: Mar 28, 2020 |
1212
| Author: Ma Bingyao <[email protected]> |
1313
| |
1414
\*________________________________________________________*/
@@ -22,15 +22,19 @@ class ServiceContext extends Context {
2222
dynamic handler;
2323
ServiceContext(this.service);
2424

25+
@override
26+
void copyTo(Context context) {
27+
super.copyTo(context);
28+
final serviceContext = context as ServiceContext;
29+
serviceContext.method = method;
30+
serviceContext.host = host;
31+
serviceContext.handler = handler;
32+
}
33+
2534
@override
2635
Context clone() {
2736
final context = service.createContext();
28-
context.method = method;
29-
context.host = host;
30-
context.handler = handler;
31-
context.items.addAll(items);
32-
context.requestHeaders.addAll(requestHeaders);
33-
context.responseHeaders.addAll(responseHeaders);
37+
copyTo(context);
3438
return context;
3539
}
3640
}

lib/src/rpc/plugins/reverse.dart

+33-23
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class Provider {
4040
}
4141

4242
Provider(this.client, [String id]) {
43+
Method.registerContextType('ProviderContext');
4344
_invokeManager = InvokeManager(_execute);
4445
if (id != null && id.isNotEmpty) this.id = id;
4546
addMethod(_methodManager.getNames, '~');
@@ -53,9 +54,15 @@ class Provider {
5354
return Function.apply(method.method, [name, args]);
5455
}
5556
if (method.namedParameterTypes.isEmpty) {
57+
if (method.contextInPositionalArguments) {
58+
args.add(context);
59+
}
5660
return Function.apply(method.method, args);
5761
}
5862
final namedArguments = args.removeLast();
63+
if (method.contextInNamedArguments) {
64+
namedArguments[Symbol('context')] = context;
65+
}
5966
return Function.apply(method.method, args, namedArguments);
6067
}
6168

@@ -87,14 +94,12 @@ class Provider {
8794
if (method.hasNamedArguments) {
8895
n = ppl + 1;
8996
}
90-
if (count > n) {
91-
args.length = n;
92-
}
9397
if (method.contextInPositionalArguments) {
9498
ppl--;
9599
n--;
96100
}
97101
n = min(count, n);
102+
args.length = n;
98103
for (var i = 0; i < n; ++i) {
99104
if (i < ppl) {
100105
args[i] = Formatter.deserialize(Formatter.serialize(args[i]),
@@ -119,15 +124,9 @@ class Provider {
119124
namedArgs[Symbol(name)] = value;
120125
}
121126
}
122-
if (method.contextInNamedArguments) {
123-
namedArgs[Symbol('context')] = context;
124-
}
125127
args[i] = namedArgs;
126128
}
127129
}
128-
if (method.contextInPositionalArguments) {
129-
args[ppl] = context;
130-
}
131130
}
132131
return [index, await _invokeManager.handler(name, args, context), null];
133132
} on Error catch (e) {
@@ -202,23 +201,23 @@ class _Proxy {
202201
}
203202

204203
@override
205-
dynamic noSuchMethod(Invocation mirror) {
206-
var name = _namespace + _getName(mirror.memberName);
207-
if (mirror.isGetter) {
204+
dynamic noSuchMethod(Invocation invocation) {
205+
var name = _namespace + _getName(invocation.memberName);
206+
if (invocation.isGetter) {
208207
return _Proxy(_caller, _id, name);
209208
}
210-
if (mirror.isMethod) {
209+
if (invocation.isMethod) {
211210
var type = dynamic;
212-
if (mirror.typeArguments.isNotEmpty) {
213-
type = mirror.typeArguments.first;
211+
if (invocation.typeArguments.isNotEmpty) {
212+
type = invocation.typeArguments.first;
214213
}
215214
var args = [];
216-
if (mirror.positionalArguments.isNotEmpty) {
217-
args.addAll(mirror.positionalArguments);
215+
if (invocation.positionalArguments.isNotEmpty) {
216+
args.addAll(invocation.positionalArguments);
218217
}
219-
if (mirror.namedArguments.isNotEmpty) {
218+
if (invocation.namedArguments.isNotEmpty) {
220219
var namedArgs = <String, dynamic>{};
221-
mirror.namedArguments.forEach((name, value) {
220+
invocation.namedArguments.forEach((name, value) {
222221
namedArgs[_getName(name)] = value;
223222
});
224223
if (namedArgs.isNotEmpty) {
@@ -227,7 +226,19 @@ class _Proxy {
227226
}
228227
return _caller._invoke(_id, name, args, type);
229228
}
230-
super.noSuchMethod(mirror);
229+
super.noSuchMethod(invocation);
230+
}
231+
}
232+
233+
class CallerContext extends ServiceContext {
234+
final Caller caller;
235+
dynamic proxy;
236+
CallerContext(this.caller, ServiceContext context) : super(context.service) {
237+
context.copyTo(this);
238+
proxy = caller.useService(caller._getId(this));
239+
}
240+
invoke<T>(String name, [List args]) {
241+
caller.invoke<T>(caller._getId(this), name, args);
231242
}
232243
}
233244

@@ -241,6 +252,7 @@ class Caller {
241252
var heartbeat = const Duration(minutes: 2);
242253
var timeout = const Duration(seconds: 30);
243254
Caller(this.service) {
255+
Method.registerContextType('CallerContext');
244256
service
245257
..addMethod(_close, '!!')
246258
..addMethod(_begin, '!')
@@ -386,8 +398,6 @@ class Caller {
386398

387399
Future _handler(
388400
String name, List args, Context context, NextInvokeHandler next) {
389-
context['invoke'] = <T>(String name, [List args]) =>
390-
invoke<T>(_getId(context as ServiceContext), name, args);
391-
return next(name, args, context);
401+
return next(name, args, new CallerContext(this, context as ServiceContext));
392402
}
393403
}

0 commit comments

Comments
 (0)