aboutsummaryrefslogtreecommitdiff
path: root/content/go/jsonrpc2.md
diff options
context:
space:
mode:
authorAlexander Neonxp Kiryukhin <i@neonxp.ru>2024-12-11 01:21:22 +0300
committerAlexander Neonxp Kiryukhin <i@neonxp.ru>2024-12-11 01:21:22 +0300
commita79499018bed35bab05f888ce0103b37655e2852 (patch)
treed182886009aeafffb247a68ff425c740b3cb6a31 /content/go/jsonrpc2.md
parent418eac8c0b978089644f48e27a0fbdd20e18ac91 (diff)
Auto-commit 2024-12-11
Diffstat (limited to 'content/go/jsonrpc2.md')
-rw-r--r--content/go/jsonrpc2.md130
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