/
streaming-rpc.js
86 lines (75 loc) · 2.2 KB
/
streaming-rpc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
var protobuf = require("..");
var root = protobuf.Root.fromJSON({
nested: {
Greeter: {
methods: {
"SayHello": {
requestType: 'Hello',
requestStream: true,
responseType: 'World',
responseStream: true
}
}
},
Hello: {
fields: {
name: {
type: "string",
id: 1
}
}
},
World: {
fields: {
message: {
type: "string",
id: 1
}
}
}
}
});
var Greeter = root.lookup("Greeter"),
Hello = root.lookup("Hello"),
World = root.lookup("World");
var ended = false;
// Implement: Stream-aware RPC implementation
function rpcImpl(method, requestData, callback) {
if (ended)
return;
if (!requestData) {
console.log("rpc ended client-side.");
ended = true;
return;
}
setTimeout(function() {
try {
// <exemplary server side code>
var hello = Hello.decodeDelimited(requestData);
var responseData = World.encodeDelimited({ message: 'Hello ' + hello.name + ' !' }).finish();
// </exemplary server side code>
callback(null, responseData);
} catch (err) {
callback(err);
}
}, Math.random() * 500);
}
var greeter = Greeter.create(rpcImpl, true, true);
greeter.on("data", function(response, method) {
console.log("data:", response.message);
});
greeter.on("end", function(method) {
console.log("ended.");
});
greeter.on("error", function(err, method) {
console.log("error:", err);
});
greeter.sayHello({ name: 'protocol' });
greeter.sayHello({ name: 'buffers' });
greeter.sayHello({ name: 'for' });
setTimeout(function() {
greeter.end();
// ^ Signals rpcImpl that the service has been ended client-side by calling it with a null buffer.
// Likewise, rpcImpl can end the stream by calling its callback with an explicit null buffer.
greeter.sayHello({ name: 'javascript' }); // does nothing
}, 1000);