starpc 0.4.9 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Makefile +1 -0
- package/README.md +20 -10
- package/dist/echo/client-test.d.ts +1 -0
- package/dist/echo/client-test.js +20 -18
- package/dist/echo/echo.pb.d.ts +165 -12
- package/dist/echo/echo.pb.js +61 -17
- package/dist/echo/server.d.ts +8 -4
- package/dist/echo/server.js +29 -37
- package/dist/rpcstream/rpcstream.d.ts +6 -6
- package/dist/rpcstream/rpcstream.js +92 -51
- package/dist/rpcstream/rpcstream.pb.d.ts +46 -1
- package/dist/rpcstream/rpcstream.pb.js +157 -9
- package/dist/srpc/client.d.ts +3 -4
- package/dist/srpc/client.js +12 -46
- package/dist/srpc/common-rpc.d.ts +3 -2
- package/dist/srpc/common-rpc.js +12 -0
- package/dist/srpc/definition.d.ts +3 -3
- package/dist/srpc/handler.d.ts +2 -3
- package/dist/srpc/handler.js +5 -22
- package/dist/srpc/index.d.ts +1 -1
- package/dist/srpc/index.js +1 -1
- package/dist/srpc/packet.js +0 -32
- package/dist/srpc/pushable.d.ts +2 -0
- package/dist/srpc/pushable.js +13 -0
- package/dist/srpc/rpcproto.pb.d.ts +13 -6
- package/dist/srpc/rpcproto.pb.js +95 -10
- package/dist/srpc/server.d.ts +1 -0
- package/dist/srpc/server.js +7 -0
- package/dist/srpc/ts-proto-rpc.d.ts +3 -4
- package/e2e/e2e.ts +4 -3
- package/e2e/e2e_test.go +24 -1
- package/echo/client-test.ts +23 -18
- package/echo/echo.pb.go +33 -20
- package/echo/echo.pb.ts +90 -34
- package/echo/echo.proto +4 -0
- package/echo/echo_srpc.pb.go +77 -0
- package/echo/server.go +18 -0
- package/echo/server.ts +47 -41
- package/integration/integration.go +1 -2
- package/integration/integration.ts +5 -1
- package/integration/integration_srpc.pb.go +139 -0
- package/package.json +5 -3
- package/patches/ts-proto+1.115.5.patch +1339 -0
- package/srpc/client.ts +16 -50
- package/srpc/common-rpc.ts +14 -2
- package/srpc/definition.ts +3 -3
- package/srpc/handler.ts +17 -34
- package/srpc/index.ts +1 -1
- package/srpc/muxed-conn.go +2 -2
- package/srpc/packet-rw.go +4 -6
- package/srpc/packet.ts +0 -33
- package/srpc/pushable.ts +17 -0
- package/srpc/rpcproto.pb.ts +122 -12
- package/srpc/server-pipe.go +2 -2
- package/srpc/server.go +2 -2
- package/srpc/server.ts +8 -0
- package/srpc/ts-proto-rpc.ts +4 -6
- package/srpc/websocket.go +2 -2
- package/dist/echo/sever.d.ts +0 -0
- package/dist/echo/sever.js +0 -1
- package/dist/srpc/observable-source.d.ts +0 -9
- package/dist/srpc/observable-source.js +0 -25
- package/echo/sever.ts +0 -0
- package/srpc/observable-source.ts +0 -40
package/echo/echo.pb.go
CHANGED
|
@@ -10,6 +10,7 @@ import (
|
|
|
10
10
|
reflect "reflect"
|
|
11
11
|
sync "sync"
|
|
12
12
|
|
|
13
|
+
rpcstream "github.com/aperturerobotics/starpc/rpcstream"
|
|
13
14
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
|
14
15
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
|
15
16
|
)
|
|
@@ -75,22 +76,31 @@ var file_github_com_aperturerobotics_starpc_echo_echo_proto_rawDesc = []byte{
|
|
|
75
76
|
0x0a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x65,
|
|
76
77
|
0x72, 0x74, 0x75, 0x72, 0x65, 0x72, 0x6f, 0x62, 0x6f, 0x74, 0x69, 0x63, 0x73, 0x2f, 0x73, 0x74,
|
|
77
78
|
0x61, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x70,
|
|
78
|
-
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x65, 0x63, 0x68, 0x6f,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x65, 0x63, 0x68, 0x6f, 0x1a, 0x3c, 0x67, 0x69, 0x74, 0x68,
|
|
80
|
+
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x65, 0x72, 0x74, 0x75, 0x72, 0x65, 0x72,
|
|
81
|
+
0x6f, 0x62, 0x6f, 0x74, 0x69, 0x63, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x72, 0x70, 0x63, 0x2f, 0x72,
|
|
82
|
+
0x70, 0x63, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2f, 0x72, 0x70, 0x63, 0x73, 0x74, 0x72, 0x65,
|
|
83
|
+
0x61, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1d, 0x0a, 0x07, 0x45, 0x63, 0x68, 0x6f,
|
|
84
|
+
0x4d, 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
|
85
|
+
0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x32, 0x93, 0x02, 0x0a, 0x06, 0x45, 0x63, 0x68, 0x6f,
|
|
86
|
+
0x65, 0x72, 0x12, 0x24, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x12, 0x0d, 0x2e, 0x65, 0x63, 0x68,
|
|
87
|
+
0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67, 0x1a, 0x0d, 0x2e, 0x65, 0x63, 0x68, 0x6f,
|
|
88
|
+
0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67, 0x12, 0x32, 0x0a, 0x10, 0x45, 0x63, 0x68, 0x6f,
|
|
89
|
+
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x0d, 0x2e, 0x65,
|
|
82
90
|
0x63, 0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67, 0x1a, 0x0d, 0x2e, 0x65, 0x63,
|
|
83
|
-
0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67, 0x12, 0x32, 0x0a, 0x10,
|
|
84
|
-
0x68, 0x6f,
|
|
85
|
-
0x2e, 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67, 0x1a,
|
|
86
|
-
0x65, 0x63, 0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67,
|
|
87
|
-
0x0a,
|
|
91
|
+
0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x10,
|
|
92
|
+
0x45, 0x63, 0x68, 0x6f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
|
|
93
|
+
0x12, 0x0d, 0x2e, 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67, 0x1a,
|
|
94
|
+
0x0d, 0x2e, 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67, 0x28, 0x01,
|
|
95
|
+
0x12, 0x32, 0x0a, 0x0e, 0x45, 0x63, 0x68, 0x6f, 0x42, 0x69, 0x64, 0x69, 0x53, 0x74, 0x72, 0x65,
|
|
88
96
|
0x61, 0x6d, 0x12, 0x0d, 0x2e, 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73,
|
|
89
97
|
0x67, 0x1a, 0x0d, 0x2e, 0x65, 0x63, 0x68, 0x6f, 0x2e, 0x45, 0x63, 0x68, 0x6f, 0x4d, 0x73, 0x67,
|
|
90
|
-
0x28, 0x01,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
0x73,
|
|
98
|
+
0x28, 0x01, 0x30, 0x01, 0x12, 0x47, 0x0a, 0x09, 0x52, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61,
|
|
99
|
+
0x6d, 0x12, 0x1a, 0x2e, 0x72, 0x70, 0x63, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x52, 0x70,
|
|
100
|
+
0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x1a, 0x1a, 0x2e,
|
|
101
|
+
0x72, 0x70, 0x63, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x52, 0x70, 0x63, 0x53, 0x74, 0x72,
|
|
102
|
+
0x65, 0x61, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x28, 0x01, 0x30, 0x01, 0x62, 0x06, 0x70,
|
|
103
|
+
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
|
94
104
|
}
|
|
95
105
|
|
|
96
106
|
var (
|
|
@@ -107,19 +117,22 @@ func file_github_com_aperturerobotics_starpc_echo_echo_proto_rawDescGZIP() []byt
|
|
|
107
117
|
|
|
108
118
|
var file_github_com_aperturerobotics_starpc_echo_echo_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
|
109
119
|
var file_github_com_aperturerobotics_starpc_echo_echo_proto_goTypes = []interface{}{
|
|
110
|
-
(*EchoMsg)(nil),
|
|
120
|
+
(*EchoMsg)(nil), // 0: echo.EchoMsg
|
|
121
|
+
(*rpcstream.RpcStreamPacket)(nil), // 1: rpcstream.RpcStreamPacket
|
|
111
122
|
}
|
|
112
123
|
var file_github_com_aperturerobotics_starpc_echo_echo_proto_depIdxs = []int32{
|
|
113
124
|
0, // 0: echo.Echoer.Echo:input_type -> echo.EchoMsg
|
|
114
125
|
0, // 1: echo.Echoer.EchoServerStream:input_type -> echo.EchoMsg
|
|
115
126
|
0, // 2: echo.Echoer.EchoClientStream:input_type -> echo.EchoMsg
|
|
116
127
|
0, // 3: echo.Echoer.EchoBidiStream:input_type -> echo.EchoMsg
|
|
117
|
-
|
|
118
|
-
0, // 5: echo.Echoer.
|
|
119
|
-
0, // 6: echo.Echoer.
|
|
120
|
-
0, // 7: echo.Echoer.
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
1, // 4: echo.Echoer.RpcStream:input_type -> rpcstream.RpcStreamPacket
|
|
129
|
+
0, // 5: echo.Echoer.Echo:output_type -> echo.EchoMsg
|
|
130
|
+
0, // 6: echo.Echoer.EchoServerStream:output_type -> echo.EchoMsg
|
|
131
|
+
0, // 7: echo.Echoer.EchoClientStream:output_type -> echo.EchoMsg
|
|
132
|
+
0, // 8: echo.Echoer.EchoBidiStream:output_type -> echo.EchoMsg
|
|
133
|
+
1, // 9: echo.Echoer.RpcStream:output_type -> rpcstream.RpcStreamPacket
|
|
134
|
+
5, // [5:10] is the sub-list for method output_type
|
|
135
|
+
0, // [0:5] is the sub-list for method input_type
|
|
123
136
|
0, // [0:0] is the sub-list for extension type_name
|
|
124
137
|
0, // [0:0] is the sub-list for extension extendee
|
|
125
138
|
0, // [0:0] is the sub-list for field type_name
|
package/echo/echo.pb.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
import Long from 'long'
|
|
3
|
+
import { EchoMsg as EchoMsg1 } from './echo.pb.js'
|
|
4
|
+
import { RpcStreamPacket } from '../rpcstream/rpcstream.pb.js'
|
|
3
5
|
import * as _m0 from 'protobufjs/minimal'
|
|
4
|
-
import { Observable } from 'rxjs'
|
|
5
|
-
import { map } from 'rxjs/operators'
|
|
6
6
|
|
|
7
7
|
export const protobufPackage = 'echo'
|
|
8
8
|
|
|
@@ -44,6 +44,40 @@ export const EchoMsg = {
|
|
|
44
44
|
return message
|
|
45
45
|
},
|
|
46
46
|
|
|
47
|
+
// encodeTransform encodes a source of message objects.
|
|
48
|
+
// Transform<EchoMsg, Uint8Array>
|
|
49
|
+
async *encodeTransform(
|
|
50
|
+
source: AsyncIterable<EchoMsg | EchoMsg[]> | Iterable<EchoMsg | EchoMsg[]>
|
|
51
|
+
): AsyncIterable<Uint8Array> {
|
|
52
|
+
for await (const pkt of source) {
|
|
53
|
+
if (Array.isArray(pkt)) {
|
|
54
|
+
for (const p of pkt) {
|
|
55
|
+
yield* [EchoMsg.encode(p).finish()]
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
yield* [EchoMsg.encode(pkt).finish()]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
// decodeTransform decodes a source of encoded messages.
|
|
64
|
+
// Transform<Uint8Array, EchoMsg>
|
|
65
|
+
async *decodeTransform(
|
|
66
|
+
source:
|
|
67
|
+
| AsyncIterable<Uint8Array | Uint8Array[]>
|
|
68
|
+
| Iterable<Uint8Array | Uint8Array[]>
|
|
69
|
+
): AsyncIterable<EchoMsg> {
|
|
70
|
+
for await (const pkt of source) {
|
|
71
|
+
if (Array.isArray(pkt)) {
|
|
72
|
+
for (const p of pkt) {
|
|
73
|
+
yield* [EchoMsg.decode(p)]
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
yield* [EchoMsg.decode(pkt)]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
|
|
47
81
|
fromJSON(object: any): EchoMsg {
|
|
48
82
|
return {
|
|
49
83
|
body: isSet(object.body) ? String(object.body) : '',
|
|
@@ -66,13 +100,17 @@ export const EchoMsg = {
|
|
|
66
100
|
/** Echoer service returns the given message. */
|
|
67
101
|
export interface Echoer {
|
|
68
102
|
/** Echo returns the given message. */
|
|
69
|
-
Echo(request:
|
|
103
|
+
Echo(request: EchoMsg1): Promise<EchoMsg1>
|
|
70
104
|
/** EchoServerStream is an example of a server -> client one-way stream. */
|
|
71
|
-
EchoServerStream(request:
|
|
105
|
+
EchoServerStream(request: EchoMsg1): AsyncIterable<EchoMsg1>
|
|
72
106
|
/** EchoClientStream is an example of client->server one-way stream. */
|
|
73
|
-
EchoClientStream(request:
|
|
107
|
+
EchoClientStream(request: AsyncIterable<EchoMsg1>): Promise<EchoMsg1>
|
|
74
108
|
/** EchoBidiStream is an example of a two-way stream. */
|
|
75
|
-
EchoBidiStream(request:
|
|
109
|
+
EchoBidiStream(request: AsyncIterable<EchoMsg1>): AsyncIterable<EchoMsg1>
|
|
110
|
+
/** RpcStream opens a nested rpc call stream. */
|
|
111
|
+
RpcStream(
|
|
112
|
+
request: AsyncIterable<RpcStreamPacket>
|
|
113
|
+
): AsyncIterable<RpcStreamPacket>
|
|
76
114
|
}
|
|
77
115
|
|
|
78
116
|
export class EchoerClientImpl implements Echoer {
|
|
@@ -83,45 +121,54 @@ export class EchoerClientImpl implements Echoer {
|
|
|
83
121
|
this.EchoServerStream = this.EchoServerStream.bind(this)
|
|
84
122
|
this.EchoClientStream = this.EchoClientStream.bind(this)
|
|
85
123
|
this.EchoBidiStream = this.EchoBidiStream.bind(this)
|
|
124
|
+
this.RpcStream = this.RpcStream.bind(this)
|
|
86
125
|
}
|
|
87
|
-
Echo(request:
|
|
88
|
-
const data =
|
|
126
|
+
Echo(request: EchoMsg1): Promise<EchoMsg1> {
|
|
127
|
+
const data = EchoMsg1.encode(request).finish()
|
|
89
128
|
const promise = this.rpc.request('echo.Echoer', 'Echo', data)
|
|
90
|
-
return promise.then((data) =>
|
|
129
|
+
return promise.then((data) => EchoMsg1.decode(new _m0.Reader(data)))
|
|
91
130
|
}
|
|
92
131
|
|
|
93
|
-
EchoServerStream(request:
|
|
94
|
-
const data =
|
|
132
|
+
EchoServerStream(request: EchoMsg1): AsyncIterable<EchoMsg1> {
|
|
133
|
+
const data = EchoMsg1.encode(request).finish()
|
|
95
134
|
const result = this.rpc.serverStreamingRequest(
|
|
96
135
|
'echo.Echoer',
|
|
97
136
|
'EchoServerStream',
|
|
98
137
|
data
|
|
99
138
|
)
|
|
100
|
-
return
|
|
139
|
+
return EchoMsg1.decodeTransform(result)
|
|
101
140
|
}
|
|
102
141
|
|
|
103
|
-
EchoClientStream(request:
|
|
104
|
-
const data =
|
|
105
|
-
map((request) => EchoMsg.encode(request).finish())
|
|
106
|
-
)
|
|
142
|
+
EchoClientStream(request: AsyncIterable<EchoMsg1>): Promise<EchoMsg1> {
|
|
143
|
+
const data = EchoMsg1.encodeTransform(request)
|
|
107
144
|
const promise = this.rpc.clientStreamingRequest(
|
|
108
145
|
'echo.Echoer',
|
|
109
146
|
'EchoClientStream',
|
|
110
147
|
data
|
|
111
148
|
)
|
|
112
|
-
return promise.then((data) =>
|
|
149
|
+
return promise.then((data) => EchoMsg1.decode(new _m0.Reader(data)))
|
|
113
150
|
}
|
|
114
151
|
|
|
115
|
-
EchoBidiStream(request:
|
|
116
|
-
const data =
|
|
117
|
-
map((request) => EchoMsg.encode(request).finish())
|
|
118
|
-
)
|
|
152
|
+
EchoBidiStream(request: AsyncIterable<EchoMsg1>): AsyncIterable<EchoMsg1> {
|
|
153
|
+
const data = EchoMsg1.encodeTransform(request)
|
|
119
154
|
const result = this.rpc.bidirectionalStreamingRequest(
|
|
120
155
|
'echo.Echoer',
|
|
121
156
|
'EchoBidiStream',
|
|
122
157
|
data
|
|
123
158
|
)
|
|
124
|
-
return
|
|
159
|
+
return EchoMsg1.decodeTransform(result)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
RpcStream(
|
|
163
|
+
request: AsyncIterable<RpcStreamPacket>
|
|
164
|
+
): AsyncIterable<RpcStreamPacket> {
|
|
165
|
+
const data = RpcStreamPacket.encodeTransform(request)
|
|
166
|
+
const result = this.rpc.bidirectionalStreamingRequest(
|
|
167
|
+
'echo.Echoer',
|
|
168
|
+
'RpcStream',
|
|
169
|
+
data
|
|
170
|
+
)
|
|
171
|
+
return RpcStreamPacket.decodeTransform(result)
|
|
125
172
|
}
|
|
126
173
|
}
|
|
127
174
|
|
|
@@ -134,36 +181,45 @@ export const EchoerDefinition = {
|
|
|
134
181
|
/** Echo returns the given message. */
|
|
135
182
|
echo: {
|
|
136
183
|
name: 'Echo',
|
|
137
|
-
requestType:
|
|
184
|
+
requestType: EchoMsg1,
|
|
138
185
|
requestStream: false,
|
|
139
|
-
responseType:
|
|
186
|
+
responseType: EchoMsg1,
|
|
140
187
|
responseStream: false,
|
|
141
188
|
options: {},
|
|
142
189
|
},
|
|
143
190
|
/** EchoServerStream is an example of a server -> client one-way stream. */
|
|
144
191
|
echoServerStream: {
|
|
145
192
|
name: 'EchoServerStream',
|
|
146
|
-
requestType:
|
|
193
|
+
requestType: EchoMsg1,
|
|
147
194
|
requestStream: false,
|
|
148
|
-
responseType:
|
|
195
|
+
responseType: EchoMsg1,
|
|
149
196
|
responseStream: true,
|
|
150
197
|
options: {},
|
|
151
198
|
},
|
|
152
199
|
/** EchoClientStream is an example of client->server one-way stream. */
|
|
153
200
|
echoClientStream: {
|
|
154
201
|
name: 'EchoClientStream',
|
|
155
|
-
requestType:
|
|
202
|
+
requestType: EchoMsg1,
|
|
156
203
|
requestStream: true,
|
|
157
|
-
responseType:
|
|
204
|
+
responseType: EchoMsg1,
|
|
158
205
|
responseStream: false,
|
|
159
206
|
options: {},
|
|
160
207
|
},
|
|
161
208
|
/** EchoBidiStream is an example of a two-way stream. */
|
|
162
209
|
echoBidiStream: {
|
|
163
210
|
name: 'EchoBidiStream',
|
|
164
|
-
requestType:
|
|
211
|
+
requestType: EchoMsg1,
|
|
212
|
+
requestStream: true,
|
|
213
|
+
responseType: EchoMsg1,
|
|
214
|
+
responseStream: true,
|
|
215
|
+
options: {},
|
|
216
|
+
},
|
|
217
|
+
/** RpcStream opens a nested rpc call stream. */
|
|
218
|
+
rpcStream: {
|
|
219
|
+
name: 'RpcStream',
|
|
220
|
+
requestType: RpcStreamPacket,
|
|
165
221
|
requestStream: true,
|
|
166
|
-
responseType:
|
|
222
|
+
responseType: RpcStreamPacket,
|
|
167
223
|
responseStream: true,
|
|
168
224
|
options: {},
|
|
169
225
|
},
|
|
@@ -179,18 +235,18 @@ interface Rpc {
|
|
|
179
235
|
clientStreamingRequest(
|
|
180
236
|
service: string,
|
|
181
237
|
method: string,
|
|
182
|
-
data:
|
|
238
|
+
data: AsyncIterable<Uint8Array>
|
|
183
239
|
): Promise<Uint8Array>
|
|
184
240
|
serverStreamingRequest(
|
|
185
241
|
service: string,
|
|
186
242
|
method: string,
|
|
187
243
|
data: Uint8Array
|
|
188
|
-
):
|
|
244
|
+
): AsyncIterable<Uint8Array>
|
|
189
245
|
bidirectionalStreamingRequest(
|
|
190
246
|
service: string,
|
|
191
247
|
method: string,
|
|
192
|
-
data:
|
|
193
|
-
):
|
|
248
|
+
data: AsyncIterable<Uint8Array>
|
|
249
|
+
): AsyncIterable<Uint8Array>
|
|
194
250
|
}
|
|
195
251
|
|
|
196
252
|
type Builtin =
|
package/echo/echo.proto
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
syntax = "proto3";
|
|
2
2
|
package echo;
|
|
3
3
|
|
|
4
|
+
import "github.com/aperturerobotics/starpc/rpcstream/rpcstream.proto";
|
|
5
|
+
|
|
4
6
|
// Echoer service returns the given message.
|
|
5
7
|
service Echoer {
|
|
6
8
|
// Echo returns the given message.
|
|
@@ -11,6 +13,8 @@ service Echoer {
|
|
|
11
13
|
rpc EchoClientStream(stream EchoMsg) returns (EchoMsg);
|
|
12
14
|
// EchoBidiStream is an example of a two-way stream.
|
|
13
15
|
rpc EchoBidiStream(stream EchoMsg) returns (stream EchoMsg);
|
|
16
|
+
// RpcStream opens a nested rpc call stream.
|
|
17
|
+
rpc RpcStream(stream .rpcstream.RpcStreamPacket) returns (stream .rpcstream.RpcStreamPacket);
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
// EchoMsg is the message body for Echo.
|
package/echo/echo_srpc.pb.go
CHANGED
|
@@ -7,6 +7,7 @@ package echo
|
|
|
7
7
|
import (
|
|
8
8
|
context "context"
|
|
9
9
|
|
|
10
|
+
rpcstream "github.com/aperturerobotics/starpc/rpcstream"
|
|
10
11
|
srpc "github.com/aperturerobotics/starpc/srpc"
|
|
11
12
|
)
|
|
12
13
|
|
|
@@ -17,6 +18,7 @@ type SRPCEchoerClient interface {
|
|
|
17
18
|
EchoServerStream(ctx context.Context, in *EchoMsg) (SRPCEchoer_EchoServerStreamClient, error)
|
|
18
19
|
EchoClientStream(ctx context.Context) (SRPCEchoer_EchoClientStreamClient, error)
|
|
19
20
|
EchoBidiStream(ctx context.Context) (SRPCEchoer_EchoBidiStreamClient, error)
|
|
21
|
+
RpcStream(ctx context.Context) (SRPCEchoer_RpcStreamClient, error)
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
type srpcEchoerClient struct {
|
|
@@ -149,11 +151,48 @@ func (x *srpcEchoer_EchoBidiStreamClient) RecvTo(m *EchoMsg) error {
|
|
|
149
151
|
return x.MsgRecv(m)
|
|
150
152
|
}
|
|
151
153
|
|
|
154
|
+
func (c *srpcEchoerClient) RpcStream(ctx context.Context) (SRPCEchoer_RpcStreamClient, error) {
|
|
155
|
+
stream, err := c.cc.NewStream(ctx, "echo.Echoer", "RpcStream", nil)
|
|
156
|
+
if err != nil {
|
|
157
|
+
return nil, err
|
|
158
|
+
}
|
|
159
|
+
strm := &srpcEchoer_RpcStreamClient{stream}
|
|
160
|
+
return strm, nil
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
type SRPCEchoer_RpcStreamClient interface {
|
|
164
|
+
srpc.Stream
|
|
165
|
+
Send(*rpcstream.RpcStreamPacket) error
|
|
166
|
+
Recv() (*rpcstream.RpcStreamPacket, error)
|
|
167
|
+
RecvTo(*rpcstream.RpcStreamPacket) error
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
type srpcEchoer_RpcStreamClient struct {
|
|
171
|
+
srpc.Stream
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
func (x *srpcEchoer_RpcStreamClient) Send(m *rpcstream.RpcStreamPacket) error {
|
|
175
|
+
return x.MsgSend(m)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
func (x *srpcEchoer_RpcStreamClient) Recv() (*rpcstream.RpcStreamPacket, error) {
|
|
179
|
+
m := new(rpcstream.RpcStreamPacket)
|
|
180
|
+
if err := x.MsgRecv(m); err != nil {
|
|
181
|
+
return nil, err
|
|
182
|
+
}
|
|
183
|
+
return m, nil
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
func (x *srpcEchoer_RpcStreamClient) RecvTo(m *rpcstream.RpcStreamPacket) error {
|
|
187
|
+
return x.MsgRecv(m)
|
|
188
|
+
}
|
|
189
|
+
|
|
152
190
|
type SRPCEchoerServer interface {
|
|
153
191
|
Echo(context.Context, *EchoMsg) (*EchoMsg, error)
|
|
154
192
|
EchoServerStream(*EchoMsg, SRPCEchoer_EchoServerStreamStream) error
|
|
155
193
|
EchoClientStream(SRPCEchoer_EchoClientStreamStream) error
|
|
156
194
|
EchoBidiStream(SRPCEchoer_EchoBidiStreamStream) error
|
|
195
|
+
RpcStream(SRPCEchoer_RpcStreamStream) error
|
|
157
196
|
}
|
|
158
197
|
|
|
159
198
|
type SRPCEchoerUnimplementedServer struct{}
|
|
@@ -174,6 +213,10 @@ func (s *SRPCEchoerUnimplementedServer) EchoBidiStream(SRPCEchoer_EchoBidiStream
|
|
|
174
213
|
return srpc.ErrUnimplemented
|
|
175
214
|
}
|
|
176
215
|
|
|
216
|
+
func (s *SRPCEchoerUnimplementedServer) RpcStream(SRPCEchoer_RpcStreamStream) error {
|
|
217
|
+
return srpc.ErrUnimplemented
|
|
218
|
+
}
|
|
219
|
+
|
|
177
220
|
const SRPCEchoerServiceID = "echo.Echoer"
|
|
178
221
|
|
|
179
222
|
type SRPCEchoerHandler struct {
|
|
@@ -188,6 +231,7 @@ func (SRPCEchoerHandler) GetMethodIDs() []string {
|
|
|
188
231
|
"EchoServerStream",
|
|
189
232
|
"EchoClientStream",
|
|
190
233
|
"EchoBidiStream",
|
|
234
|
+
"RpcStream",
|
|
191
235
|
}
|
|
192
236
|
}
|
|
193
237
|
|
|
@@ -208,6 +252,8 @@ func (d *SRPCEchoerHandler) InvokeMethod(
|
|
|
208
252
|
return true, d.InvokeMethod_EchoClientStream(d.impl, strm)
|
|
209
253
|
case "EchoBidiStream":
|
|
210
254
|
return true, d.InvokeMethod_EchoBidiStream(d.impl, strm)
|
|
255
|
+
case "RpcStream":
|
|
256
|
+
return true, d.InvokeMethod_RpcStream(d.impl, strm)
|
|
211
257
|
default:
|
|
212
258
|
return false, nil
|
|
213
259
|
}
|
|
@@ -244,6 +290,11 @@ func (SRPCEchoerHandler) InvokeMethod_EchoBidiStream(impl SRPCEchoerServer, strm
|
|
|
244
290
|
return impl.EchoBidiStream(clientStrm)
|
|
245
291
|
}
|
|
246
292
|
|
|
293
|
+
func (SRPCEchoerHandler) InvokeMethod_RpcStream(impl SRPCEchoerServer, strm srpc.Stream) error {
|
|
294
|
+
clientStrm := &srpcEchoer_RpcStreamStream{strm}
|
|
295
|
+
return impl.RpcStream(clientStrm)
|
|
296
|
+
}
|
|
297
|
+
|
|
247
298
|
func SRPCRegisterEchoer(mux srpc.Mux, impl SRPCEchoerServer) error {
|
|
248
299
|
return mux.Register(&SRPCEchoerHandler{impl: impl})
|
|
249
300
|
}
|
|
@@ -331,3 +382,29 @@ func (x *srpcEchoer_EchoBidiStreamStream) Recv() (*EchoMsg, error) {
|
|
|
331
382
|
func (x *srpcEchoer_EchoBidiStreamStream) RecvTo(m *EchoMsg) error {
|
|
332
383
|
return x.MsgRecv(m)
|
|
333
384
|
}
|
|
385
|
+
|
|
386
|
+
type SRPCEchoer_RpcStreamStream interface {
|
|
387
|
+
srpc.Stream
|
|
388
|
+
Send(*rpcstream.RpcStreamPacket) error
|
|
389
|
+
Recv() (*rpcstream.RpcStreamPacket, error)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
type srpcEchoer_RpcStreamStream struct {
|
|
393
|
+
srpc.Stream
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
func (x *srpcEchoer_RpcStreamStream) Send(m *rpcstream.RpcStreamPacket) error {
|
|
397
|
+
return x.MsgSend(m)
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
func (x *srpcEchoer_RpcStreamStream) Recv() (*rpcstream.RpcStreamPacket, error) {
|
|
401
|
+
m := new(rpcstream.RpcStreamPacket)
|
|
402
|
+
if err := x.MsgRecv(m); err != nil {
|
|
403
|
+
return nil, err
|
|
404
|
+
}
|
|
405
|
+
return m, nil
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
func (x *srpcEchoer_RpcStreamStream) RecvTo(m *rpcstream.RpcStreamPacket) error {
|
|
409
|
+
return x.MsgRecv(m)
|
|
410
|
+
}
|
package/echo/server.go
CHANGED
|
@@ -6,11 +6,19 @@ import (
|
|
|
6
6
|
"io"
|
|
7
7
|
"time"
|
|
8
8
|
|
|
9
|
+
rpcstream "github.com/aperturerobotics/starpc/rpcstream"
|
|
10
|
+
srpc "github.com/aperturerobotics/starpc/srpc"
|
|
9
11
|
"google.golang.org/protobuf/proto"
|
|
10
12
|
)
|
|
11
13
|
|
|
12
14
|
// EchoServer implements the server side of Echo.
|
|
13
15
|
type EchoServer struct {
|
|
16
|
+
rpcStreamMux srpc.Mux
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// NewEchoServer constructs a EchoServer with a RpcStream mux.
|
|
20
|
+
func NewEchoServer(rpcStreamMux srpc.Mux) *EchoServer {
|
|
21
|
+
return &EchoServer{rpcStreamMux: rpcStreamMux}
|
|
14
22
|
}
|
|
15
23
|
|
|
16
24
|
// Echo implements echo.SRPCEchoerServer
|
|
@@ -69,5 +77,15 @@ func (s *EchoServer) EchoBidiStream(strm SRPCEchoer_EchoBidiStreamStream) error
|
|
|
69
77
|
}
|
|
70
78
|
}
|
|
71
79
|
|
|
80
|
+
// RpcStream runs a rpc stream
|
|
81
|
+
func (r *EchoServer) RpcStream(stream SRPCEchoer_RpcStreamStream) error {
|
|
82
|
+
return rpcstream.HandleRpcStream(stream, func(ctx context.Context, componentID string) (srpc.Mux, error) {
|
|
83
|
+
if r.rpcStreamMux == nil {
|
|
84
|
+
return nil, errors.New("not implemented")
|
|
85
|
+
}
|
|
86
|
+
return r.rpcStreamMux, nil
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
72
90
|
// _ is a type assertion
|
|
73
91
|
var _ SRPCEchoerServer = ((*EchoServer)(nil))
|
package/echo/server.ts
CHANGED
|
@@ -1,57 +1,63 @@
|
|
|
1
|
-
import { Observable, from as observableFrom } from 'rxjs'
|
|
2
1
|
import { Echoer, EchoMsg } from './echo.pb.js'
|
|
3
2
|
import { pushable, Pushable } from 'it-pushable'
|
|
3
|
+
import first from 'it-first'
|
|
4
|
+
import { Server } from '../srpc/server.js'
|
|
5
|
+
import { writeToPushable } from '../srpc/pushable.js'
|
|
6
|
+
import { RpcStreamPacket } from '../rpcstream/rpcstream.pb.js'
|
|
7
|
+
import { handleRpcStream } from '../rpcstream/rpcstream.js'
|
|
4
8
|
|
|
5
9
|
// EchoServer implements the Echoer server.
|
|
6
10
|
export class EchoerServer implements Echoer {
|
|
11
|
+
// proxyServer is the server used for RpcStream requests.
|
|
12
|
+
private proxyServer?: Server
|
|
13
|
+
|
|
14
|
+
constructor(proxyServer?: Server) {
|
|
15
|
+
this.proxyServer = proxyServer
|
|
16
|
+
}
|
|
17
|
+
|
|
7
18
|
public async Echo(request: EchoMsg): Promise<EchoMsg> {
|
|
8
19
|
return request
|
|
9
20
|
}
|
|
10
21
|
|
|
11
|
-
public EchoServerStream(request: EchoMsg):
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
yield request
|
|
17
|
-
await new Promise((resolve) => setTimeout(resolve, 200))
|
|
18
|
-
}
|
|
19
|
-
})()
|
|
20
|
-
)
|
|
22
|
+
public async *EchoServerStream(request: EchoMsg): AsyncIterable<EchoMsg> {
|
|
23
|
+
for (let i = 0; i < 5; i++) {
|
|
24
|
+
yield request
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, 200))
|
|
26
|
+
}
|
|
21
27
|
}
|
|
22
28
|
|
|
23
|
-
public EchoClientStream(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
complete() {
|
|
33
|
-
reject(new Error('none received'))
|
|
34
|
-
},
|
|
35
|
-
})
|
|
36
|
-
})
|
|
29
|
+
public async EchoClientStream(
|
|
30
|
+
request: AsyncIterable<EchoMsg>
|
|
31
|
+
): Promise<EchoMsg> {
|
|
32
|
+
// return the first message sent by the client.
|
|
33
|
+
const message = await first(request)
|
|
34
|
+
if (!message) {
|
|
35
|
+
throw new Error('received no messages')
|
|
36
|
+
}
|
|
37
|
+
return message
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
public EchoBidiStream(
|
|
40
|
+
public EchoBidiStream(
|
|
41
|
+
request: AsyncIterable<EchoMsg>
|
|
42
|
+
): AsyncIterable<EchoMsg> {
|
|
40
43
|
// build result observable
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
const result: Pushable<EchoMsg> = pushable({ objectMode: true })
|
|
45
|
+
result.push({ body: 'hello from server' })
|
|
46
|
+
writeToPushable(request, result)
|
|
47
|
+
return result
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public RpcStream(
|
|
51
|
+
request: AsyncIterable<RpcStreamPacket>
|
|
52
|
+
): AsyncIterable<RpcStreamPacket> {
|
|
53
|
+
return handleRpcStream(
|
|
54
|
+
request[Symbol.asyncIterator](),
|
|
55
|
+
async (_componentId: string): Promise<Server> => {
|
|
56
|
+
if (!this.proxyServer) {
|
|
57
|
+
throw new Error('rpc stream proxy server not set')
|
|
58
|
+
}
|
|
59
|
+
return this.proxyServer
|
|
60
|
+
}
|
|
61
|
+
)
|
|
56
62
|
}
|
|
57
63
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WebSocketConn } from '../srpc/websocket.js'
|
|
2
|
-
import { runClientTest } from '../echo/client-test.js'
|
|
2
|
+
import { runClientTest, runRpcStreamTest } from '../echo/client-test.js'
|
|
3
3
|
import WebSocket from 'isomorphic-ws'
|
|
4
4
|
|
|
5
5
|
async function runRPC() {
|
|
@@ -9,7 +9,11 @@ async function runRPC() {
|
|
|
9
9
|
const channel = new WebSocketConn(ws)
|
|
10
10
|
const client = channel.buildClient()
|
|
11
11
|
|
|
12
|
+
console.log('Running client test via WebSocket..')
|
|
12
13
|
await runClientTest(client)
|
|
14
|
+
|
|
15
|
+
console.log('Running RpcStream test via WebSocket..')
|
|
16
|
+
await runRpcStreamTest(client)
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
runRPC()
|