diff options
Diffstat (limited to 'content/go/jsonrpc2.md')
-rw-r--r-- | content/go/jsonrpc2.md | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/content/go/jsonrpc2.md b/content/go/jsonrpc2.md new file mode 100644 index 0000000..471c4c9 --- /dev/null +++ b/content/go/jsonrpc2.md @@ -0,0 +1,130 @@ ++++ +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"` +} +```
\ No newline at end of file |