+++
title = "JSON-RPC 2.0"
name = "jsonrpc2"
repository = "https://git.neonxp.ru/jsonrpc2.git"
description = "JSON-RPC 2.0 сервер на генериках"
gomod = true
+++
Реализация сервера JSON-RPC 2.0 на Go с использованием дженериков.
Требуется версия Go 1.18+
Возможности:
- [x] Транспорт HTTP/HTTPS
- [x] Транспорт TCP
- [ ] Транспорт WebSocket
## Использование (транспорт HTTP)
1. Создайте сервер JSON-RPC с параметрами:
```go
import "neonxp.ru/go/jsonrpc2/rpc"
...
s := rpc.New(
rpc.WithTransport(&transport.HTTP{
Bind: ":8000", // Порт для привязки
CORSOrigin: "*", // Источник CORS
TLS: &tls.Config{}, // Опциональный конфигурационный файл TLS (по умолчанию nil)
Parallel: true, // Разрешить параллельное выполнение пакетных методов (по умолчанию false)
}),
// Другие параметры, такие как транспорты/средства обработки промежуточного ПО...
)
```
2. Добавьте необходимые транспорты:
```go
import "neonxp.ru/go/jsonrpc2/transport"
...
s.Use(
rpc.WithTransport(&transport.TCP{Bind: ":3000"}),
//...
)
```
3. Напишите обработчики:
```go
// Этот обработчик поддерживает параметры запроса
func Multiply(ctx context.Context, args *Args) (int, error) {
return args.A * args.B, nil
}
// Этот обработчик не имеет параметров запроса
func Hello(ctx context.Context) (string, error) {
return "Мир", nil
}
```
Обработчик должен иметь контекст в качестве первого параметра и может иметь второй параметр, представляющий параметры запроса (вход любого типа, сериализуемого в JSON). Обработчик всегда возвращает ровно два значения (выход любого типа, сериализуемого в JSON, и ошибку).
4. Оберните обработчик одной из двух функций rpc.H (с поддержкой параметров запроса) или rpc.HS (без параметров) и зарегистрируйте его на сервере:
```go
// обработчик с параметрами
s.Register("multiply", rpc.H(Multiply))
// обработчик без параметров
s.Register("hello", rpc.HS(Hello))
```
5. Запустите сервер RPC:
```go
s.Run(ctx)
```
## Пользовательский транспорт
Любой транспорт должен реализовывать простой интерфейс transport.Transport:
```go
type Transport interface {
Run(ctx context.Context, resolver Resolver) error
}
```
Полный пример
```go
package main
import (
"context"
"neonxp.ru/go/jsonrpc2/rpc"
"neonxp.ru/go/jsonrpc2/rpc/middleware"
"neonxp.ru/go/jsonrpc2/transport"
)
func main() {
s := rpc.New(
rpc.WithLogger(rpc.StdLogger), // Опциональный логгер
rpc.WithTransport(&transport.HTTP{Bind: ":8000"}), // Транспорт HTTP
)
// Установите параметры после конструктора
s.Use(
rpc.WithTransport(&transport.TCP{Bind: ":3000"}), // Транспорт TCP
rpc.WithMiddleware(middleware.Logger(rpc.StdLogger)), // Логгер промежуточного ПО
)
s.Register("multiply", rpc.H(Multiply))
s.Register("divide", rpc.H(Divide))
s.Register("hello", rpc.HS(Hello))
s.Run(context.Background())
}
func Multiply(ctx context.Context, args *Args) (int, error) {
//...
}
func Divide(ctx context.Context, args *Args) (*Quotient, error) {
//...
}
func Hello(ctx context.Context) (string, error) {
// ...
}
type Args struct {
A int `json:"a"`
B int `json:"b"`
}
type Quotient struct {
Quo int `json:"quo"`
Rem int `json:"rem"`
}
```