我已经使用Go的net / rpc和net / rpc / jsonrpc包来执行Go进程之间的连接,但是我想知道是否有一种方法只使用标准库中的服务器工具连接到HTTP JSONRPC服务器(不是我写自己的问题,如果我不需要,就不想这样做).
这是我的基本服务器设置:
arith := new(server.Arith) server := rpc.NewServer() server.Register(arith) server.HandleHTTP(rpc.DefaultRPCPath,rpc.DefaultDebugPath) listener,e := net.Listen("tcp",":4321") if e != nil { log.Fatal("listen error:",e) } defer listener.Close() http.Serve(listener,http.DefaultServeMux)
我希望能够通过网页或简单的命令行CURL调用来实现这一点 – 只需要常规POST.
但是,此行:http://golang.org/src/net/rpc/server.go?s=20445:20475#L670似乎表明它希望HTTP客户端发出CONNECT,然后直接将JSON RPC请求写入流并以相同的方式接收回复.我不知道这是否可能来自浏览器,但它肯定不像简单的POST那样常见或兼容.
有没有办法启动一个JSON RPC服务器,我可以使用好的’XMLHttpRequest来POST?
编辑:废话 – 上面甚至没有使用jsonrpc的东西 – 这可能是尝试使用Gob,但无论如何 – 问题是相同的 – src / net / rpc / server.go中的代码不会处理POST,所以无论服务器编解码器如何,这条路线总体上都无法运行.
FWIW,我通过制作一个简单的HTTP处理程序来调整服务器IDC的程序.似乎像魅力一样工作.
这是作为测试的工作代码:
import ( "bytes" "fmt" "io" "io/IoUtil" "log" "net" "net/http" "net/rpc" "net/rpc/jsonrpc" "testing" ) // adapt HTTP connection to ReadWriteCloser type HttpConn struct { in io.Reader out io.Writer } func (c *HttpConn) Read(p []byte) (n int,err error) { return c.in.Read(p) } func (c *HttpConn) Write(d []byte) (n int,err error) { return c.out.Write(d) } func (c *HttpConn) Close() error { return nil } // our service type CakeBaker struct{} func (cb *CakeBaker) BakeIt(n int,msg *string) error { *msg = fmt.Sprintf("your cake has been bacon (%d)",n) return nil } func TestHTTPServer(t *testing.T) { fmt.Printf("TestHTTPServer\n") cb := &CakeBaker{} server := rpc.NewServer() server.Register(cb) listener,":4321") if e != nil { log.Fatal("listen error:",e) } defer listener.Close() go http.Serve(listener,http.HandlerFunc(func(w http.ResponseWriter,r *http.Request) { if r.URL.Path == "/bake-me-a-cake" { serverCodec := jsonrpc.NewServerCodec(&HttpConn{in: r.Body,out: w}) w.Header().Set("Content-type","application/json") w.WriteHeader(200) err := server.ServeRequest(serverCodec) if err != nil { log.Printf("Error while serving JSON request: %v",err) http.Error(w,"Error while serving JSON request,details have been logged.",500) return } } })) resp,err := http.Post("http://localhost:4321/bake-me-a-cake","application/json",bytes.NewBufferString( `{"jsonrpc":"2.0","id":1,"method":"CakeBaker.BakeIt","params":[10]}`,)) if err != nil { panic(err) } defer resp.Body.Close() b,err := IoUtil.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Printf("returned JSON: %s\n",string(b)) }