ホームページ >バックエンド開発 >Golang >Go Web サーバーで JSON-RPC の HTTP POST リクエストを処理する方法は?

Go Web サーバーで JSON-RPC の HTTP POST リクエストを処理する方法は?

DDD
DDDオリジナル
2024-11-20 15:49:13895ブラウズ

How to Handle HTTP POST Requests for JSON-RPC in a Go Web Server?

Web ページから HTTP JSONRPC にアクセスする

Go プログラミングのコンテキストでは、ライブラリ net/rpc および net/rpc/jsonrpc は次のとおりです。プロセス間通信に一般的に使用されます。ただし、標準ライブラリのサーバー ツールのみを使用して 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)

この設定では、からの POST リクエストはネイティブにサポートされていません。ウェブページ。このコードでは、HTTP クライアントが CONNECT を開始し、その接続を介して JSON RPC リクエストとレスポンスを直接送信することを想定しています。

解決策: カスタム HTTP ハンドラーの作成

有効にするにはPOST リクエストでは、カスタム HTTP ハンドラーを実装して、HTTP リクエスト/レスポンスを ServerCodec に適応させることができます。以下に例を示します。

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 }

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) {

    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))

}

このカスタム ハンドラーは、HTTP リクエスト/レスポンスを JSON RPC サーバーに適した形式に調整し、Web ページまたはコマンドライン CURL 呼び出しからの POST リクエストを許可します。

以上がGo Web サーバーで JSON-RPC の HTTP POST リクエストを処理する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。