登录
首页 >  Golang >  Go问答

golang http+jsonrpc 从网页访问

来源:Golang技术栈

时间:2023-04-11 19:15:12 478浏览 收藏

本篇文章给大家分享《golang http+jsonrpc 从网页访问》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。

问题内容

我已经使用 Gonet/rpcnet/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 服务器,我可以发布到使用好的 ol' XMLHttpRequest ?

编辑:废话 - 上面甚至没有使用 jsonrpc 的东西 - 这可能是在尝试使用 Gob,但无论如何 - 问题是一样的 - src/net/rpc/server.go 中的代码不会处理 POST,所以无论服务器编解码器如何,这条路线总体上都不会起作用。

正确答案

FWIW,我通过制作一个简单的 HTTP 处理程序来完成这项工作,该处理程序使 HTTP 请求/响应适应 ServerCodec。似乎像魅力一样工作。

这是作为测试的工作代码:

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

}

以上就是《golang http+jsonrpc 从网页访问》的详细内容,更多关于golang的资料请关注golang学习网公众号!

声明:本文转载于:Golang技术栈 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表