2

我正在尝试使用该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(使用常规网络服务器)上为跨域请求设置标头一样,因为这不以 ahttp.ResponseWriter作为参数。

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

任何见解都非常感谢。

4

2 回答 2

2

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

对于 1 号:

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

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

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

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

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

那是一个有趣的练习!

于 2012-10-12T05:19:04.600 回答
0

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

rs/cors你可以通过几行justinas/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)
}
于 2020-11-13T16:04:26.287 回答