Skip to content
Please note that GitHub no longer supports Internet Explorer.

We recommend upgrading to the latest Microsoft Edge, Google Chrome, or Firefox.

Learn more
Remote Procedure Call Server and Client for Crystal. Implements msgpack-rpc protocall.
Crystal Ruby Shell
Branch: master
Clone or download
Cannot retrieve the latest commit at this time.
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bench
examples
rb
spec
src
.editorconfig
.gitignore
.travis.yml
LICENSE
README.md
build-bench.sh
msgpack-rpc.md
shard.yml

README.md

simple_rpc

Build Status

Remote Procedure Call Server and Client for Crystal. Implements msgpack-rpc protocall. Designed to be reliable and stable (catch every possible protocall/socket errors).

Installation

Add this to your application's shard.yml:

dependencies:
  simple_rpc:
    github: kostya/simple_rpc

Usage

require "simple_rpc"

# Example run server and client.

class MyRpc
  # When including SimpleRpc::Proto, all public instance methods inside class,
  # would be exposed to external rpc call.
  # Each method should define type for each argument, and also return type.
  # (Types of arguments should supports MessagePack::Serializable).
  # Instance of this class created on server for each call.
  include SimpleRpc::Proto

  def bla(x : Int32, y : String) : Float64
    x * y.to_f
  end
end

spawn do
  # running RPC server on 9000 port in background fiber
  MyRpc::Server.new("127.0.0.1", 9000).run
end

# wait until server up
sleep 0.1

# create rpc client
client = MyRpc::Client.new("127.0.0.1", 9000)
result = client.bla(3, "5.5")

if result.ok?
  p result.value! + 1 # => 17.5
else
  p result.message!
end

When client code have no access to server proto, you can call raw requests:

require "simple_rpc"

client = SimpleRpc::Client.new("127.0.0.1", 9000)
result = client.request(Float64, :bla, 3, "5.5") # no raises if error

if result.ok?
  p result.value! # => 16.5
else
  p result.message!
end

When you dont want to check errors, and ok with raise on problem:

require "simple_rpc"

client = SimpleRpc::Client.new("127.0.0.1", 9000)
result = client.request!(Float64, :bla, 3, "5.5") # here can raise SimpleRpc::Errors
p result # => 16.5

If you dont know what return type is, use MessagePack::Type:

require "simple_rpc"

client = SimpleRpc::Client.new("127.0.0.1", 9000)
result = client.request!(MessagePack::Type, :bla, 3, "5.5")
p result.class # => Float64
p typeof(result) # => (Array(MessagePack::Type) | Bool | Float64 | Hash(MessagePack::Type, MessagePack::Type) | Int16 | Int32 | Int64 | Int8 | String | UInt16 | UInt32 | UInt64 | UInt8 | Nil)
p result # => 16.5

If you want to exchange complex data types, you should include MessagePack::Serializable

require "simple_rpc"

record Result, a : Int32, b : String { include MessagePack::Serializable }

class MyData
  include MessagePack::Serializable

  property a : Int32
  property b : Hash(String, String)?

  @[MessagePack::Field(ignore: true)]
  property c : Int32?
end

class MyRpc 
  include SimpleRpc::Proto

  def complex(data : MyData) : Result
    # ...
  end
end

Example calling from Ruby, with gem msgpack-rpc

require 'msgpack/rpc'

client = MessagePack::RPC::Client.new('127.0.0.1', 9000)
result = client.call(:bla, 3, "5.5")
p result # => 16.5
You can’t perform that action at this time.