3.0.1 • Published 5 years ago

@techteamer/wsrpc v3.0.1

Weekly downloads
6
License
BSD-3-Clause
Repository
github
Last release
5 years ago

wsrpc

Original package: wsrpc

Node.js/browser protobuf rpc over binary websockets.

Key features:

  • Send binary data over websockets
  • RPC
  • Broadcasting
  • Customizable reconnect logic on client side
  • Supports multiple protobuf services on same port

Installation

yarn add @techteamer/wsrpc

Usage examples

Single service usage

my-service.proto

service MyService {
    rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

message HelloRequest {
    required string name = 1;
}

message HelloResponse {
    required string text = 1;
}

server.js

const wsrpc = require('@techteamer/wsrpc')
const protobuf = require('protobufjs')

const proto = protobuf.loadSync('my-service.proto')

const server = new wsrpc.Server(proto.lookupService('MyService'), { port: 4242 })

server.implement('sayHello', async (request) => {
    return {text: `Hello ${ request.name }!`}
})

client.js

const wsrpc = require('@techteamer/wsrpc')
const protobuf = require('protobufjs')

const proto = protobuf.loadSync('my-service.proto')

const client = new wsrpc.Client('ws://localhost:4242', proto.lookupService('MyService'))

const response = await client.service.sayHello({name: 'world'})
console.log(response) // Hello world!

Multi service usage

You can use a single server to implement multiple rpc services. The services can be in a single or multiple separate .proto files.

WARNING: Service names must be unique!

NOTE: The same message or rpc method names can be used in multiple services. To avoid collisions between them across different services you should use a unique package identifier in every .proto file.

service1.proto

package service1

service Service1 {
    rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

message HelloRequest {
    required string name = 1;
}

message HelloResponse {
    required string text = 1;
}

service2.proto

package service2

service Service2 {
    rpc SayHello (HelloRequest) returns (HelloResponse) {}
    rpc SayHi (HelloRequest) returns (HelloResponse) {}
}

message HelloRequest {
    required string to = 1;
}

message HelloResponse {
    required string text = 1;
    required string from = 2;
    required string to = 3;
}

server.js

const wsrpc = require('@techteamer/wsrpc')
const protobuf = require('protobufjs')

const proto = protobuf.loadSync(['service1.proto', 'service2.proto'])

const service1 = proto.lookupService('Service1')
const service2 = proto.lookupService('Service2')

const services = [
    service1,
    service2
]

const server = new wsrpc.Server(services, { port: 4242 })

// If the method is a string you have to specify the service!
server.implement('Service1', 'sayHello', async (request) => {
    return {text: `Hello ${ request.name } from Service1!`}
})

server.implement(service2, 'sayHello', async (request) => {
    return {text: `Hello ${ request.to } from Service2!`}
})

// If you pass in a Method instance the service will be resolved automatically
server.implement(service2.methods.SayHi, async (request) => {
    return {text: `Hi ${ request.to }!`, from: 'Service2', to: request.name}
})

client.js

const wsrpc = require('@techteamer/wsrpc')
const protobuf = require('protobufjs')

const proto = protobuf.loadSync(['service1.proto', 'service2.proto'])

const service1 = proto.lookupService('Service1')
const service2 = proto.lookupService('Service2')

const services = [
    service1,
    service2
]

const client = new wsrpc.Client('ws://localhost:4242', services)
let response

response = await client.services.Service1.sayHello({name: 'world1'})
console.log(response.text) // Hello world1 from Service1!

response = await client.services.Service2.sayHello({to: 'world2'})
console.log(response.text) // Hello world2 from Service2!

response = await client.services.Service2.sayHi({to: 'world3'})
console.log(response.text) // Hi world3!
console.log(response.from) // Service2
console.log(response.to) // world3