package main import ( "errors" "fmt" "io" "net/http" "net/rpc" "net/rpc/jsonrpc" "os" "time" log "github.com/sirupsen/logrus" ) type JSONRPCServer struct { *rpc.Server } func NewJSONRPCServer() *JSONRPCServer { return &JSONRPCServer{rpc.NewServer()} } func (s *JSONRPCServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { log.Println("rpc server got a request") conn, _, err := w.(http.Hijacker).Hijack() if err != nil { log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error()) return } io.WriteString(conn, "HTTP/1.0 200 Connected to Go JSON-RPC\n\n") codec := jsonrpc.NewServerCodec(conn) log.Println("ServeCodec") s.Server.ServeCodec(codec) log.Println("finished serving request") } type Args struct { A, B int } type Quotient struct { Quo, Rem int } type Arith int func (t *Arith) Multiply(args *Args, reply *int) error { *reply = args.A * args.B return nil } func (t *Arith) Divide(args *Args, quo *Quotient) error { if args.B == 0 { return errors.New("divide by zero") } quo.Quo = args.A / args.B quo.Rem = args.A % args.B return nil } func main() { //log.SetFormatter(&log.JSONFormatter{}) // Output to stdout instead of the default stderr // Can be any io.Writer, see below for File example log.SetOutput(os.Stdout) // Only log the warning severity or above. //log.SetLevel(log.WarnLevel) log.Infof("starting up") go runHttpServer() running := true for running { time.Sleep(1 * time.Second) } } func runHttpServer() { js := NewJSONRPCServer() arith := new(Arith) js.Register(arith) port := 8080 listenaddr := fmt.Sprintf("0.0.0.0:%d", port) s := &http.Server{ Addr: listenaddr, Handler: js, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } log.Infof("starting up http server %s", listenaddr) log.Fatal(s.ListenAndServe()) }