Stream RPC
starpc implements Proto3 services in both TypeScript and Go.
Supports client-to-server streaming RPCs in the web browser, currently not
supported by any of the major RPC libraries.
The rpcproto file describes the protocol.
Can use any Stream multiplexer: defaults to libp2p-mplex over a WebSocket.
Note: the server has not yet been implemented in TypeScript.
Usage
Starting with the protobuf-project repository on the "starpc" branch.
Use "git add" to add your new .proto files, then yarn gen
to generate the
TypeScript and Go code for them.
Examples
See the protobuf-project template on the "starpc" branch.
The demo/boilerplate project implements the Echo example below.
Protobuf
The following examples use the echo protobuf sample.
syntax = "proto3";
package echo;
// Echoer service returns the given message.
service Echoer {
// Echo returns the given message.
rpc Echo(EchoMsg) returns (EchoMsg);
// EchoServerStream is an example of a server -> client one-way stream.
rpc EchoServerStream(EchoMsg) returns (stream EchoMsg);
// EchoClientStream is an example of client->server one-way stream.
rpc EchoClientStream(stream EchoMsg) returns (EchoMsg);
// EchoBidiStream is an example of a two-way stream.
rpc EchoBidiStream(stream EchoMsg) returns (stream EchoMsg);
}
// EchoMsg is the message body for Echo.
message EchoMsg {
string body = 1;
}
Go: Server & Client
A basic example can be found in the e2e test:
// construct the server
echoServer := &echo.EchoServer{}
mux := srpc.NewMux()
if err := echo.SRPCRegisterEchoer(mux, echoServer); err != nil {
t.Fatal(err.Error())
}
server := srpc.NewServer(mux)
// create an in-memory connection to the server
openStream := srpc.NewServerPipe(server)
// construct the client
client := srpc.NewClient(openStream)
// construct the client rpc interface
clientEcho := echo.NewSRPCEchoerClient(client)
ctx := context.Background()
bodyTxt := "hello world"
out, err := clientEcho.Echo(ctx, &echo.EchoMsg{
Body: bodyTxt,
})
if err != nil {
t.Fatal(err.Error())
}
if out.GetBody() != bodyTxt {
t.Fatalf("expected %q got %q", bodyTxt, out.GetBody())
}
TypeScript
See the ts-proto README to generate the TypeScript for your protobufs.
Also check out the integration test.
Supports any AsyncIterable communication channel with an included implementation
for WebSockets.
This repository uses protowrap, see the Makefile.
WebSocketConn
uses js-libp2p-mplex to multiplex streams over the WebSocket.
Server
import { WebSocketConn, Server, createMux } from '../srpc'
import { EchoerClientImpl } from '../echo/echo'
const mux = createMux()
mux.register(TODO)
const server = new Server(mux)
// TODO: accept a WebSocket-like object.
const ws = TODO
const channel = new WebSocketConn(ws, server)
// incoming streams will be handled by server.
Client
import { WebSocketConn } from '../srpc'
import { EchoerClientImpl } from '../echo/echo'
const ws = new WebSocket('ws://localhost:5000/demo')
const channel = new WebSocketConn(ws)
const client = channel.buildClient()
const demoServiceClient = new EchoerClientImpl(client)
const result = await demoServiceClient.Echo({
body: "Hello world!"
})
console.log('output', result.body)
const clientRequestStream = new Observable<EchoMsg>(subscriber => {
subscriber.next({body: 'Hello world from streaming request.'})
subscriber.complete()
})
console.log('Calling EchoClientStream: client -> server...')
result = await demoServiceClient.EchoClientStream(clientRequestStream)
console.log('success: output', result.body)
Attribution
protoc-gen-go-starpc
is a heavily modified version of protoc-gen-go-drpc
.
Be sure to check out drpc as well: it's compatible with grpc, twirp, and more.
Uses vtprotobuf to generate Protobuf marshal / unmarshal code.
Support
Starpc is built & supported by Aperture Robotics, LLC.
Community contributions and discussion are welcomed!
Please open a GitHub issue with any questions / issues.
... or feel free to reach out on Matrix Chat or Discord.