Maison >développement back-end >Golang >Comment gérer les requêtes HTTP POST pour JSON-RPC dans un serveur Web Go ?

Comment gérer les requêtes HTTP POST pour JSON-RPC dans un serveur Web Go ?

DDD
DDDoriginal
2024-11-20 15:49:13894parcourir

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

Accéder à HTTP JSONRPC depuis une page Web

Dans le cadre de la programmation Go, les bibliothèques net/rpc et net/rpc/jsonrpc sont couramment utilisé pour la communication inter-processus. Cependant, la connexion à un serveur HTTP JSONRPC en utilisant uniquement les outils serveur de la bibliothèque standard peut soulever des questions.

Considérez la configuration de base du serveur suivante :

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)

Cette configuration ne prend pas en charge nativement les requêtes POST de une page Internet. Le code s'attend à ce qu'un client HTTP initie un CONNECT et transmette la requête et la réponse JSON RPC directement via cette connexion.

Solution : création d'un gestionnaire HTTP personnalisé

Pour activer Requêtes POST, un gestionnaire HTTP personnalisé peut être implémenté pour adapter la requête/réponse HTTP à un ServerCodec. Voici un exemple :

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

}

Ce gestionnaire personnalisé adapte la requête/réponse HTTP dans un format approprié pour le serveur JSON RPC, autorisant les requêtes POST à ​​partir d'une page Web ou d'un appel CURL en ligne de commande.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn