Skip to content

Instantly share code, notes, and snippets.

@dthtvwls
Last active August 3, 2017 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dthtvwls/5180c726ab55f5843ff0e60d9c10b165 to your computer and use it in GitHub Desktop.
Save dthtvwls/5180c726ab55f5843ff0e60d9c10b165 to your computer and use it in GitHub Desktop.
rpc_engine
package main

import (
	"encoding/json"
	"fmt"
	"rpc_engine"
)

func main() {
	a := rpc_engine.New()
	a.Methods = map[string]interface{}{
		"add": func(args ...interface{}) interface{} {
			return args[0].(float64) + args[1].(float64)
		},
	}

	b := rpc_engine.New()
	b.Methods = map[string]interface{}{
		"hello": func(args ...interface{}) interface{} {
			return "world"
		},
	}

	b.Send = a.OnMessage
	a.Send = b.OnMessage

	deserialize := func(message []byte) (interface{}, error) {
		requonse := rpc_engine.Requonse{}
		if err := json.Unmarshal(message, &requonse); err != nil {
			return nil, err
		} else {
			return requonse, nil
		}
	}

	a.Serialize = json.Marshal
	a.Deserialize = deserialize
	b.Serialize = json.Marshal
	b.Deserialize = deserialize

	a.Call("hello", []interface{}{}, func(answer interface{}) {
		fmt.Println(answer) // => world
	})

	b.Call("add", []interface{}{1, 1336}, func(result interface{}) {
		fmt.Println(result) // => 1337
	})
}
package rpc_engine
type engine struct {
Methods map[string]interface{}
Send func(message []byte)
Serialize func(message interface{}) ([]byte, error)
Deserialize func(message []byte) (interface{}, error)
id int
callbacks []func(interface{})
}
type Requonse struct {
Method string
Params []interface{}
Result interface{}
Id int
}
type lambda func(...interface{}) interface{}
type callback func(interface{})
func New() *engine {
return &engine{}
}
func (e *engine) Call(method string, params []interface{}, cb func(interface{})) {
request, _ := e.Serialize(Requonse{
Method: method,
Params: params,
Id: e.id,
})
e.callbacks = append(e.callbacks, cb)
e.id++
e.Send(request)
}
func (e *engine) OnMessage(message []byte) {
m, _ := e.Deserialize(message)
r := m.(Requonse)
if r.Method != "" {
method := e.Methods[r.Method].(func(...interface{}) interface{})
response, _ := e.Serialize(Requonse{
Result: lambda(method)(r.Params...),
Id: r.Id,
})
e.Send(response)
} else if r.Result != nil {
callback(e.callbacks[r.Id])(r.Result)
e.callbacks[r.Id] = nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment