Как правильно вызвать JSON-RPC в Go? - PullRequest
6 голосов
/ 19 января 2012

Я пробовал различные конфигурации, чтобы вызвать простой JSON-RPC-сервер для биткойнов в Go, но не смог никуда добраться.

В Python весь код выглядит так:

from jsonrpc import ServiceProxy
access = ServiceProxy("http://user:pass@127.0.0.1:8332")
print access.getinfo()

Но в Go я, похоже, сталкиваюсь с ошибками вроде "слишком много двоеточий в адресе" или "нет такого хоста". Я пытался использовать оба пакета rpc и rpc / jsonrpc, используя методы Dial и DialHTTP, используя различные сетевые параметры, и до сих пор не могу никуда добраться.

Итак, как правильно вызвать сервер JSON-RPC в Go?

1 Ответ

10 голосов
/ 19 января 2012

Пакет jsonrpc на данный момент не поддерживает json-rpc через HTTP. Итак, вы не можете использовать это, извините.

Но спецификация jsonrpc довольно проста и, вероятно, довольно легко написать свой собственный пакет jsonrpchttp (о, я надеюсь, вы знаете лучшее имя).

Мне удалось успешно вызвать getinfo, используя следующий (ужасный) код:

package main

import (
    "encoding/json"
    "io/ioutil"
    "log"
    "net/http"
    "strings"
)

func main() {
    data, err := json.Marshal(map[string]interface{}{
        "method": "getinfo",
        "id":     1,
        "params": []interface{}{},
    })
    if err != nil {
        log.Fatalf("Marshal: %v", err)
    }
    resp, err := http.Post("http://bob:secret@127.0.0.1:8332",
        "application/json", strings.NewReader(string(data)))
    if err != nil {
        log.Fatalf("Post: %v", err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalf("ReadAll: %v", err)
    }
    result := make(map[string]interface{})
    err = json.Unmarshal(body, &result)
    if err != nil {
        log.Fatalf("Unmarshal: %v", err)
    }
    log.Println(result)
}

Может быть, вы можете немного его очистить, реализовав интерфейс rpc.ClientCodec (см. Пример jsonrpc / client.go ). Тогда вы можете воспользоваться пакетом Go rpc .

...