2015-07-14 03:03

从网页访问golang http + jsonrpc


I've used Go's net/rpc and net/rpc/jsonrpc packages a bit to perform connections between Go processes, however I'm wondering if there is a way to connect to an HTTP JSONRPC server using only the server tooling from the standard library (not that I have a problem writing my own, just don't want to do it if I don't have to).

This is the basic server setup I have:

arith := new(server.Arith)

server := rpc.NewServer()

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)

And I'd like to be able to be hitting this from a web page or a simple command line CURL call - just a regular POST.

However, this line: http://golang.org/src/net/rpc/server.go?s=20445:20475#L670 appears to indicate that it expects an HTTP client to issue a CONNECT and then directly write the JSON RPC request to the stream and receive the reply back the same way. I don't know if this is even possible from a browser, but it certainly is not as common or compatible as a simple POST.

Is there a way to start a JSON RPC server that I can just POST to using good ol' XMLHttpRequest ?

EDIT: Crap - the above is not even using the jsonrpc stuff - this is probably trying to use Gob, but whatever - the problem is the same - the code in src/net/rpc/server.go is not going to handle POSTs, so this route overall isn't going to work regardless of server codec.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答


  • duanqinjiao5244 duanqinjiao5244 6年前

    FWIW, I got this working by making a simple HTTP handler that adapts the HTTP request/response to a ServerCodec. Seems to work like a charm.

    Here's the working code as a test:

    import (
    // 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) {
        cb := &CakeBaker{}
        server := rpc.NewServer()
        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")
                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)
        resp, err := http.Post("http://localhost:4321/bake-me-a-cake", "application/json", bytes.NewBufferString(
        if err != nil {
        defer resp.Body.Close()
        b, err := ioutil.ReadAll(resp.Body)
        if err != nil {
        fmt.Printf("returned JSON: %s
    ", string(b))
    点赞 评论 复制链接分享
  • duanbushi1867 duanbushi1867 6年前

    a RPC framework shoud have language supports list, I not used json-rpc, but it should support javascript language by this link. you need add one of the javascript client sdk listed there.

    点赞 评论 复制链接分享