├── LICENSE ├── README.md └── main.go /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jsonrpc-server 2 | 3 | jsonrpc-server demonstrates how to serve [Golang](http://golang.org) RPC methods over HTTP using the [JSON-RPC](http://golang.org/pkg/net/rpc/jsonrpc/) encoding. 4 | 5 | ## Usage 6 | 7 | ### Install 8 | 9 | ``` 10 | go install github.com/kelseyhightower/jsonrpc-server 11 | ``` 12 | 13 | Start the jsonrpc server: 14 | 15 | ``` 16 | jsonrpc-server 17 | ``` 18 | 19 | ### Make RPC calls using curl 20 | 21 | ``` 22 | curl -d '{"method":"Arith.Divide","params":[{"A": 10, "B":2}], "id": 0}' http://localhost:8080 23 | ``` 24 | 25 | ``` 26 | {"id":0,"result":{"Quo":5,"Rem":0},"error":null} 27 | ``` 28 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Copyright 2015 Kelsey Hightower. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package main 7 | 8 | import ( 9 | "bytes" 10 | "errors" 11 | "io" 12 | "log" 13 | "net/http" 14 | "net/rpc" 15 | "net/rpc/jsonrpc" 16 | ) 17 | 18 | type Args struct { 19 | A, B int 20 | } 21 | 22 | type Quotient struct { 23 | Quo, Rem int 24 | } 25 | 26 | type Arith int 27 | 28 | func (t *Arith) Multiply(args *Args, reply *int) error { 29 | *reply = args.A * args.B 30 | return nil 31 | } 32 | 33 | func (t *Arith) Divide(args *Args, quo *Quotient) error { 34 | if args.B == 0 { 35 | return errors.New("divide by zero") 36 | } 37 | quo.Quo = args.A / args.B 38 | quo.Rem = args.A % args.B 39 | return nil 40 | } 41 | 42 | // rpcRequest represents a RPC request. 43 | // rpcRequest implements the io.ReadWriteCloser interface. 44 | type rpcRequest struct { 45 | r io.Reader // holds the JSON formated RPC request 46 | rw io.ReadWriter // holds the JSON formated RPC response 47 | done chan bool // signals then end of the RPC request 48 | } 49 | 50 | // NewRPCRequest returns a new rpcRequest. 51 | func NewRPCRequest(r io.Reader) *rpcRequest { 52 | var buf bytes.Buffer 53 | done := make(chan bool) 54 | return &rpcRequest{r, &buf, done} 55 | } 56 | 57 | // Read implements the io.ReadWriteCloser Read method. 58 | func (r *rpcRequest) Read(p []byte) (n int, err error) { 59 | return r.r.Read(p) 60 | } 61 | 62 | // Write implements the io.ReadWriteCloser Write method. 63 | func (r *rpcRequest) Write(p []byte) (n int, err error) { 64 | return r.rw.Write(p) 65 | } 66 | 67 | // Close implements the io.ReadWriteCloser Close method. 68 | func (r *rpcRequest) Close() error { 69 | r.done <- true 70 | return nil 71 | } 72 | 73 | // Call invokes the RPC request, waits for it to complete, and returns the results. 74 | func (r *rpcRequest) Call() io.Reader { 75 | go jsonrpc.ServeConn(r) 76 | <-r.done 77 | return r.rw 78 | } 79 | 80 | func main() { 81 | arith := new(Arith) 82 | rpc.Register(arith) 83 | http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 84 | defer req.Body.Close() 85 | w.Header().Set("Content-Type", "application/json") 86 | res := NewRPCRequest(req.Body).Call() 87 | io.Copy(w, res) 88 | }) 89 | log.Fatal(http.ListenAndServe(":8080", nil)) 90 | } 91 | --------------------------------------------------------------------------------