【问题标题】:JSON RPC request in Golang with Gorilla/rpcGolang 中的 JSON RPC 请求与 Gorilla/rpc
【发布时间】:2012-10-02 19:11:04
【问题描述】:

我正在尝试使用 Gorilla/rpc 包来设置 RPC 以接收请求并回复响应(显然)。

首先我尝试使用Gorilla/rpc 提供的示例

这是我的代码:

type HelloArgs struct {
    Who string
}

type HelloReply struct {
    Message string
}

type HelloService struct{}

func (h *HelloService) Say(r *http.Request, args *HelloArgs, reply *HelloReply) error {
    reply.Message = "Hello, " + args.Who + "!"
    return nil
}

func main() {
    r := mux.NewRouter()

    jsonRPC := rpc.NewServer()
    jsonCodec := json.NewCodec()
    jsonRPC.RegisterCodec(jsonCodec, "application/json")
    jsonRPC.RegisterCodec(jsonCodec, "application/json; charset=UTF-8") // For firefox 11 and other browsers which append the charset=UTF-8
    jsonRPC.RegisterService(new(HelloService), "")
    r.Handle("/api", jsonRPC)

    http.ListenAndServe(":"+port, nil)
}

我有几个问题:

  1. 我不确定如何设置 Access-Control-Allow-Origin 标头,就像我通常在 http.ResponseWriter(使用常规网络服务器)上针对跨域请求一样,因为这不需要 http.ResponseWriter作为论据。

  2. 为了访问HelloService.Say 方法,我实际上会发送什么?我试过{ method: "HelloService.Say", params:[{Who: "Me"}]},但得到405 (Method Not Allowed)(不确定这是不是因为我无法发出x域请求?)

非常感谢任何见解。

【问题讨论】:

  • 尝试在数据中添加引号:{"method":"HelloService.Say","params":[{"Who":"Me"}]}

标签: json go rpc json-rpc


【解决方案1】:

我知道这是一个很老的问题,但实际上有一种更简单的方法可以实现这一点。

感谢rs/corsjustinas/alice 几行软件包,您可以做到这一点。

func main() {
    chain := alice.New(cors.Default().Handler)

    server := rpc.NewServer()
    server.RegisterCodec(json2.NewCodec(), "application/json")
    server.RegisterService(new(HelloService), "")

    http.Handle("/rpc", chain.Then(server))

    http.ListenAndServe(":8081", nil)
}

【讨论】:

    【解决方案2】:

    已编辑:修复错误使用“类型同义词”

    对于 1 号:

    Gorilla/rpc/json's CodecRequest.WriteResponse(实现Gorilla/rpc's CodecRequest)是代码接触http.ResponseWriterone place

    这意味着我们必须有自己的 CodecRequest 实现,它设置 CORS 标头。

    服务器使用的每一个CodecRequest实际上都是由一个Codec生成的; Codecs 是制造CodecRequests 的工厂,换句话说。

    这意味着我们必须创建一个Codec 来生成我们的CodecRequests 来设置CORS 标头。

    Go 的伟大之处在于,编写这种额外的行为真的很容易!

    试试这个:

    package cors_codec
    import (
        "Gorilla/rpc"
        "net/http"
        "strings"
    )
    //interface: ain't nobody dope like me I feel so fresh and clean
    func CodecWithCors([]string corsDomains, unpimped rpc.Codec) rpc.Codec {
        return corsCodecRequest{corsDomains, unpimped}
    }
    
    
    type corsCodecRequest struct {
        corsDomains []string
        underlyingCodecRequest rpc.CodecRequest
    }
    
    //override exactly one method of the underlying anonymous field and delegate to it.
    func (ccr corsCodecRequest) WriteResponse(w http.ResponseWriter, reply interface{}, methodErr error) error {
        w.Header().add("Access-Control-Allow-Origin", strings.join(ccr.corsDomains, " "))
        return ccr.underlyingCodecRequest.WriteResponse(w, reply, error)
    }
    
    type corsCodec struct {
        corsDomains []string
        underlyingCodec rpc.Codec
    }
    
    //override exactly one method of the underlying anonymous field and delegate to it.
    func (cc corsCodec) NewRequest(req *http.Request) rpc.CodecRequest {
      return corsCodecRequest{cc.corsDomains, cc.underlyingCodec.NewRequest(req)}
    }
    

    这是一个有趣的练习!

    【讨论】:

      猜你喜欢
      • 2013-07-01
      • 2014-09-24
      • 2017-03-04
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多