Go 中的 net/rpc 和 net/rpc/jsonrpc 包提供了一种使用 JSON 在 Go 进程之间进行通信的方法-RPC。但是,不直接支持仅使用标准库从网页连接到 JSON-RPC 服务器。虽然服务器期望 HTTP 客户端发出 CONNECT 请求,但 Web 浏览器和 cURL 等命令行工具通常使用 POST 请求。
要解决此问题,您可以创建一个自定义 HTTP 适配器,用于处理 HTTP 请求和响应之间的转换,以及一个由 JSON-RPC 服务器使用的 ServerCodec。
以下是自定义 HTTP 适配器和测试服务的示例:
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, e := net.Listen("tcp", ":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)) }
通过使用此适配器,您可以创建一个接受 POST 请求并使用以下命令处理它们的 JSON-RPC 服务器标准 JSON-RPC 协议。
以上是如何使用 Go 的 net/rpc 包从网页发出 JSON-RPC 请求?的详细内容。更多信息请关注PHP中文网其他相关文章!