golang http jsonrpc从网页访问

我已经使用Go的net / rpc和net / 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服务器,我可以使用好的’XMLHttpRequest来POST?

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

FWIW,我通过制作一个简单的HTTP处理程序来调整服务器IDC的程序.似乎像魅力一样工作.

这是作为测试的工作代码

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,":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))

}

相关文章

程序目录结构 简单实现,用户登录后返回一个jwt的token,下次请求带上token请求用户信息接口并返回信息...
本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简...
简介 默克尔树(MerkleTree)是一种典型的二叉树结构,其主要特点为: 最下面的叶节点包含存储数据或其...
接下来学习并发编程, 并发编程是go语言最有特色的地方, go对并发编程是原生支持. goroutine是go中最近本...
先普及一下, 什么是广度优先搜索 广度优先搜索类似于树的层次遍历。从图中的某一顶点出发,遍历每一个顶...
第一天: 接口的定义和实现 第二天: 一. go语言是面向接口编程. 在学习继承的时候说过, go语言只有封装,...