繁体   English   中英

Golang 中的 JSON RPC 请求与 Gorilla/rpc

[英]JSON RPC request in Golang with Gorilla/rpc

我正在尝试使用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. 我不确定如何像往常一样在http.ResponseWriter (带有常规网络服务器)上设置Access-Control-Allow-Origin标头以进行跨域请求,因为这不会将http.ResponseWriter作为争论。

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

任何见解都非常感谢。

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

对于数字 1:

Gorilla/rpc/jsonCodecRequest.WriteResponse (它实现Gorilla/rpcCodecRequest )是一个位置,其中所述代码的接触http.ResponseWriter

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

服务器使用的每一个CodecRequest实际上都是由一个Codec生成的; Codec是制作CodecRequests工厂, CodecRequests

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

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

那是一个有趣的练习!

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

多亏了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)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM