Heim  >  Artikel  >  Backend-Entwicklung  >  Wie gehe ich mit HTTP-POST-Anfragen für JSON-RPC in einem Go-Webserver um?

Wie gehe ich mit HTTP-POST-Anfragen für JSON-RPC in einem Go-Webserver um?

DDD
DDDOriginal
2024-11-20 15:49:13840Durchsuche

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

Zugriff auf HTTP JSONRPC von einer Webseite aus

Im Kontext der Go-Programmierung sind dies die Bibliotheken net/rpc und net/rpc/jsonrpc Wird häufig für die Kommunikation zwischen Prozessen verwendet. Allerdings kann die Verbindung zu einem HTTP-JSONRPC-Server nur mit den Servertools der Standardbibliothek Fragen aufwerfen.

Berücksichtigen Sie die folgende grundlegende Serverkonfiguration:

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)

Diese Konfiguration unterstützt keine nativen POST-Anfragen von eine Webseite. Der Code erwartet, dass ein HTTP-Client einen CONNECT initiiert und die JSON-RPC-Anfrage und -Antwort direkt über diese Verbindung überträgt.

Lösung: Erstellen eines benutzerdefinierten HTTP-Handlers

Zur Aktivierung Für POST-Anfragen kann ein benutzerdefinierter HTTP-Handler implementiert werden, um die HTTP-Anfrage/-Antwort an einen ServerCodec anzupassen. Hier ist ein Beispiel:

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

}

Dieser benutzerdefinierte Handler passt die HTTP-Anfrage/-Antwort in ein geeignetes Format für den JSON-RPC-Server an und ermöglicht POST-Anfragen von einer Webseite oder einem Befehlszeilen-CURL-Aufruf.

Das obige ist der detaillierte Inhalt vonWie gehe ich mit HTTP-POST-Anfragen für JSON-RPC in einem Go-Webserver um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn