使用Gorilla RPC在Go中批量处理JSON-RPC请求。

huangapple go评论74阅读模式
英文:

Batch JSON-RPCs in Go with Gorilla RPC

问题

好的,我会为你翻译这段代码。以下是翻译的结果:

好的,所以我正在开发一个服务器。它提供网页服务和其他服务。

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/rpc"
	"github.com/gorilla/rpc/json"
)

type Service struct {
	Name string
}

type ServiceArgs struct {
	Str string
	Val float64
}

type ServiceReply struct {
	Message string
}

func (e *Service) DoSomething(request *http.Request, args *ServiceArgs, reply *ServiceReply) error {
	fmt.Println("DoSomething called remotely!")
	reply.Message = "OMG. It works."

	return nil
}

func main() {
	rpcHandler := rpc.NewServer()
	rpcHandler.RegisterCodec(json.NewCodec(), "application/json")
	rpcHandler.RegisterService(new(Service), "")

	http.Handle("/rpc", rpcHandler)

	http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("."))))

	fmt.Println("Listening on port 8080.")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatalln(err)
	}
}

我在服务器端有一个API,我希望普通客户端能够访问它。为此,我开始学习更多关于JSON-RPC的知识。这是我如何从Web浏览器中调用Service.DoSomething的方法。

var log = document.getElementById("log");
var request = new XMLHttpRequest();

var command = {
    "jsonrpc":"2.0",
    "method":"Service.DoSomething",
    "params":[{
        "Str":"pie",
        "Val":3.14
    }],
    "id":1
};

request.onreadystatechange = function() {
    if (request.readyState == 4 && request.status == 200) {
        var response = JSON.parse(request.responseText).result;
        log.textContent += response["Message"];
    } else {
        console.log(request.statusText);
    }
};

request.open("POST", "/rpc", true);
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.send(JSON.stringify(command));

这个方法可以正常工作。当我运行这段JavaScript代码时,在浏览器中看到了"OMG. It works."。接下来,我想运行多个方法调用。我发现有一种方法可以向服务器发送一个"批处理"的调用。所以我尝试了以下JavaScript代码。

var command = [
    {"jsonrpc":"2.0","method":"Service.DoSomething","params":[{"Str":"pie","Val":3.14}],"id":1},
    {"jsonrpc":"2.0","method":"Service.DoSomething","params":[{"Str":"pie","Val":3.14}],"id":2}
];

request.send(JSON.stringify(command));

然而,这给我返回了一个400 (Bad Request)的错误。我在语法上搞错了吗?还是这是gorilla/rpc的问题?

英文:

Okay, so I'm working a server. It serves webpages and provides other services.

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/rpc"
	"github.com/gorilla/rpc/json"
)

type Service struct {
	Name string
}

type ServiceArgs struct {
	Str string
	Val float64
}

type ServiceReply struct {
	Message string
}

func (e *Service) DoSomething(request *http.Request, args *ServiceArgs, reply *ServiceReply) error {
	fmt.Println("DoSomething called remotely!")
	reply.Message = "OMG. It works."

	return nil
}

func main() {
	rpcHandler := rpc.NewServer()
	rpcHandler.RegisterCodec(json.NewCodec(), "application/json")
	rpcHandler.RegisterService(new(Service), "")
	http.Handle("/rpc", rpcHandler)

	http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("."))))

	fmt.Println("Listening on port 8080.")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatalln(err)
	}
}

I have an API on the server side that I want normal clients to be able to access. For this, I started learning more about JSON-RPC. This is how I call Service.DoSomething from a web browser.

var log = document.getElementById("log");
var request = new XMLHttpRequest();

var command = {
    "jsonrpc":"2.0",
    "method":"Service.DoSomething",
    "params":[{
        "Str":"pie",
        "Val":3.14
    }],
    "id":1
};

request.onreadystatechange = function() {
    if (request.readyState == 4 && request.status == 200) {
        var response = JSON.parse(request.responseText).result;
        log.textContent += response["Message"];
    } else {
        console.log(request.statusText);
    }
};

request.open("POST", "/rpc", true);
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.send(JSON.stringify(command));

This works fine. I see "OMG. It works." in my browser when I run that JavaScript. Next, I wanted to run multiple method calls. I found that there is a way to send a "batch" of calls to the server. So I tried this from JavaScript.

var command = [
    {"jsonrpc":"2.0","method":"Service.DoSomething","params":[{"Str":"pie","Val":3.14}],"id":1},
    {"jsonrpc":"2.0","method":"Service.DoSomething","params":[{"Str":"pie","Val":3.14}],"id":2}
];

request.send(JSON.stringify(command));

However, this gives me a 400 (Bad Request). Did I screw up the syntax somewhere? Or is this a problem with gorilla/rpc?

答案1

得分: 2

根据The Gorilla Toolkit JSON-RPC概述

该包遵循JSON-RPC 1.0规范:

根据JSON-RPC规范JSON-RPC Google讨论组,“batch”是JSON-RPC 2.0的一个特性。

看起来Gorilla JSON-RPC不支持批量查询。

英文:

According to The Gorilla Toolkit JSON-RPC overview:

>This package follows the JSON-RPC 1.0 specification:

According to The JSON-RPC spec, and the JSON-RPC Google group discussion, 'batch' is a JSON-RPC 2.0 feature.

It looks like Gorilla JSON-RPC doesn't understand the batched queries.

huangapple
  • 本文由 发表于 2014年8月1日 08:32:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/25071128.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定