eRPC — это эффективный, масштабируемый и простой в использовании фреймворк RPC.
Подходит для использования в областях RPC, микросервисов, долгоживущих соединений типа Point-to-Point, IM и игр.
### Установка
GO111MODULE=on go get -u -v -insecure github.com/andeya/erpc/v7
import "github.com/andeya/erpc/v7"
Header
и Body
Header
включает метаданные такого же формата, как HTTP-заголовкиBody
поддерживает пользовательские кодеки, аналогичные Content-Type, реализованы следующие:
rawproto
— по умолчанию высокопроизводительный двоичный протоколjsonproto
— протокол сообщений JSONpbproto
— протокол сообщений Protobufthriftproto
— протокол сообщений Thrifthttproto
— протокол сообщений HTTPtcp
tcp4
tcp6
unix
unixpacket
kcp
quic
websocket
evio
Окружение | Частота транзакций | Средняя задержка | Задержка P99 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
func main() { defer erpc.FlushLogger() // грациозное завершение go erpc.GraceSignal()
// серверный узел
srv := erpc.NewPeer(erpc.PeerConfig{
CountTime: true,
ListenPort: 9090,
PrintDetail: true,
})
// srv.SetTLSConfig(erpc.GenerateTLSConfigForServer())
// маршрутизатор
srv.RouteCall(new(Math))
// широковещательная рассылка каждые 5 секунд
go func() {
for {
time.Sleep(time.Second * 5)
srv.RangeSession(func(sess erpc.Session) bool {
sess.Push(
"/push/status",
fmt.Sprintf("это широковещательное сообщение, время сервера: %v", time.Now()),
)
return true
})
}
}()
// прослушивание и обслуживание
srv.ListenAndServe()
}
// Обработчик математических операций type Math struct { erpc.CallCtx }
// Add обрабатывает запрос на сложение func (m *Math) Add(arg *[]int) (int, *erpc.Status) { // тест метаданных erpc.Infof("автор: %s", m.PeekMeta("author"))
// суммирование
var r int
for _, a := range *arg {
r += a
}
// ответ
return r, nil
}
### Клиент
```go
package main
import (
"time"
"github.com/andeya/erpc/v7"
)
func main() {
defer erpc.SetLoggerLevel("ERROR")()
cli := erpc.NewPeer(erpc.PeerConfig{})
defer cli.Close()
// cli.SetTLSConfig(&tls.Config{InsecureSkipVerify: true})
cli.RoutePush(new(Push))
sess, stat := cli.Dial(":9090")
if !stat.OK() {
erpc.Fatalf("%v", stat)
}
var result int
stat = sess.Call("/math/add",
[]int{1, 2, 3, 4, 5},
&result,
erpc.WithAddMeta("author", "andeya"),
).Status()
if !stat.OK() {
erpc.Fatalf("%v", stat)
}
erpc.Printf("результат: %d", result)
erpc.Printf("Ожидание получения push в течение 10 секунд... ")
time.Sleep(time.Second * 10)
}
// Обработчик push
type Push struct {
erpc.PushCtx
}
// Push обрабатывает сообщение '/push/status'
func (p *Push) Status(arg *string) *erpc.Status {
erpc.Printf("%s", *arg)
return nil
}
```[Дополнительные примеры](https://github.com/andeya/erpc/blob/master/examples)
## Использование
**ЗАМЕЧАНИЕ:**
- Лучше всего установить ограничение размера пакета при чтении: `SetReadLimit`.
- По умолчанию ограничение размера пакета при чтении составляет 1 ГБ.
### Пример конечной точки Peer (сервер или клиент)
```go
// Запуск сервера
var peer1 = erpc.NewPeer(erpc.PeerConfig{
ListenPort: 9090, // для роли сервера
})
peer1.Listen()
// Запуск клиента
var peer2 = erpc.NewPeer(erpc.PeerConfig{})
var sess, err = peer2.Dial("127.0.0.1:8080")
AaBb
-> /aa_bb
ABcXYz
-> /abc_xyz
Aa__Bb
-> /aa_bb
aa__bb
-> /aa_bb
ABC__XYZ
-> /abc_xyz
Aa_Bb
-> /aa/bb
aa_bb
-> /aa/bb
ABC_XYZ
-> /abc/xyz
erpc.SetServiceMethodMapper(erpc.HTTPServiceMethodMapper)
- `AaBb` -> `AaBb`
- `ABcXYz` -> `ABcXYz`
- `Aa__Bb` -> `Aa_Bb`
- `aa__bb` -> `aa_bb`
- `ABC__XYZ` -> `ABC_XYZ`
- `Aa_Bb` -> `Aa.Bb`
- `aa_bb` -> `aa.bb`
- `ABC_XYZ` -> `ABC.XYZ`
erpc.SetServiceMethodMapper(erpc.RPCServiceMethodMapper)
type Aaa struct {
erpc.CallCtx
}
func (x *Aaa) XxZz(arg *<T>) (<T>, *erpc.Status) {
...
return r, nil
}
// регистрация вызова маршрута
// HTTP отображение: /aaa/xx_zz
// RPC отображение: Aaa.XxZz
peer.RouteCall(new(Aaa))
// или регистрация вызова маршрута
// HTTP отображение: /xx_zz
// RPC отображение: XxZz
peer.RouteCallFunc((*Aaa).XxZz)
```### Шаблон call-function интерфейса
```go
func XxZz(ctx erpc.CallCtx, arg *<T>) (<T>, *erpc.Status) {
...
return r, nil
}
// регистрация вызова маршрута
// HTTP отображение: /xx_zz
// RPC отображение: XxZz
peer.RouteCallFunc(XxZz)
type Bbb struct {
erpc.PushCtx
}
func (b *Bbb) YyZz(arg *<T>) *erpc.Status {
...
return nil
}
// регистрация обработчика отправки
// HTTP отображение: /bbb/yy_zz
// RPC отображение: Bbb.YyZz
peer.RoutePush(new(Bbb))
// или регистрация обработчика отправки
// HTTP отображение: /yy_zz
// RPC отображение: YyZz
peer.RoutePushFunc((*Bbb).YyZz)
// YyZz регистрация обработчика
func YyZz(ctx erpc.PushCtx, arg *<T>) *erpc.Status {
...
return nil
}
// регистрация обработчика отправки
// HTTP отображение: /yy_zz
// RPC отображение: YyZz
peer.RoutePushFunc(YyZz)
func XxxUnknownCall(ctx erpc.UnknownCallCtx) (interface{}, *erpc.Status) {
...
return r, nil
}
// регистрация маршрута неизвестного вызова: /*
peer.SetUnknownCall(XxxUnknownCall)
func XxxUnknownPush(ctx erpc.UnknownPushCtx) *erpc.Status {
...
return nil
}
// регистрация маршрута неизвестной отправки: /* peer.SetUnknownPush(XxxUnknownPush)
### Пример плагинов
```go
// NewIgnoreCase возвращает плагин игнорирующего регистра.
func NewIgnoreCase() *ignoreCase {
return &ignoreCase{}
}
type ignoreCase struct{}
var (
_ erpc.PostReadCallHeaderPlugin = new(ignoreCase)
_ erpc.PostReadPushHeaderPlugin = new(ignoreCase)
)
func (i *ignoreCase) Name() string {
return "ignoreCase"
}
func (i *ignoreCase) PostReadCallHeader(ctx erpc.ReadCtx) *erpc.Status {
// Динамическое преобразование пути в нижний регистр
ctx.UriObject().Path = strings.ToLower(ctx.UriObject().Path)
return nil
}
func (i *ignoreCase) PostReadPushHeader(ctx erpc.ReadCtx) *erpc.Status {
// Динамическое преобразование пути в нижний регистр
ctx.UriObject().Path = strings.ToLower(ctx.UriObject().Path)
return nil
}
// добавление группы маршрутов
group := peer.SubRoute("test")
// регистрация в группе тест
group.RouteCall(new(Aaa), NewIgnoreCase())
peer.RouteCallFunc(XxZz, NewIgnoreCase())
group.RoutePush(new(Bbb))
peer.RoutePushFunc(YyZz)
peer.SetUnknownCall(XxxUnknownCall)
peer.SetUnknownPush(XxxUnknownPush)
type PeerConfig struct {
Network string `yaml:"network" ini:"network" comment:"Сеть; tcp, tcp4, tcp6, unix, unixpacket, kcp или quic"`
LocalIP string `yaml:"local_ip" ini:"local_ip" comment:"Локальный IP"`
ListenPort uint16 `yaml:"listen_port" ini:"listen_port" comment:"Порт прослушивания; для роли сервера"`
DialTimeout time.Duration `yaml:"dial_timeout" ini:"dial_timeout" comment:"По умолчанию максимальное время ожидания соединения; для роли клиента; ns, µs, ms, s, m, h"`
}
``````markdown
RedialTimes int32 `yaml:"redial_times" ini:"redial_times" comment:"Максимальное количество попыток повторной установки соединения после его непредвиденного разрыва; без ограничений при отрицательном значении; для роли клиента"`
RedialInterval time.Duration `yaml:"redial_interval" ini:"redial_interval" comment:"Интервал между попытками повторной установки соединения; по умолчанию 100 мс; для роли клиента; ns, µs, ms, s, m, h"`
DefaultBodyCodec string `yaml:"default_body_codec" ini:"default_body_codec" comment:"ID типа дефолтного кодека для тела сообщения"`
DefaultSessionAge time.Duration `yaml:"default_session_age" ini:"default_session_age" comment:"Длительность сессии по умолчанию"`
}
```Продолжительность `yaml:"default_session_age" ini:"default_session_age" comment:"Максимальный срок действия сессии по умолчанию, если меньше либо равно 0, то нет ограничения времени; ns, µs, ms, s, m, h"`
DefaultContextAge time.Duration `yaml:"default_context_age" ini:"default_context_age" comment:"Максимальный срок действия контекста запроса по умолчанию, если меньше либо равно 0, то нет ограничения времени; ns, µs, ms, s, m, h"`
SlowCometDuration time.Duration `yaml:"slow_comet_duration" ini:"slow_comet_duration" comment:"Пороговое значение для оповещения о медленной операции; ns, µs, ms, s..."`
PrintDetail bool `yaml:"print_detail" ini:"print_detail" comment:"Отображение содержимого и метаданных или нет"`
CountTime bool `yaml:"count_time" ini:"count_time" comment:"Подсчет затраченного времени или нет"`
}
```### Оптимизация связи
- **SetMessageSizeLimit** Установка верхнего предела размера сообщения,
если `max_size` ≤ 0, верхний предел по умолчанию равен максимальному значению `uint32`
```go
func SetMessageSizeLimit(max_message_size uint32)
```
- **SetSocketKeepAlive** Разрешение отправки пакетов keepalive TCP системой
```go
func SetSocketKeepAlive(keep_alive bool)
```
- **SetSocketKeepAlivePeriod** Установка частоты отправки пакетов keepalive TCP системой
```go
func SetSocketKeepAlivePeriod(duration time.Duration)
```
- **SetSocketNoDelay** Отключение алгоритма Nagle; отключение позволяет не объединять небольшие данные в один пакет передачи; по умолчанию отключено
```go
func SetSocketNoDelay(no_delay bool)
```
- **SetSocketReadBuffer** Установка размера буфера чтения TCP системы
```go
func SetSocketReadBuffer(size int)
```
- **SetSocketWriteBuffer** Установка размера буфера записи TCP системы
```go
func SetSocketWriteBuffer(size int)
```## Расширяемые пакеты
### Кодеки
| пакет | импорт | описание |
| ---------------------------------------- | ---------------------------------------- | ----------------------------- |
| [json](https://github.com/andeya/erpc/blob/master/codec/json_codec.go) | `"github.com/andeya/erpc/v7/codec"` | JSON кодек (собственный erpc)|
| [protobuf](https://github.com/andeya/erpc/blob/master/codec/protobuf_codec.go) | `"github.com/andeya/erpc/v7/codec"` | Protobuf кодек (собственный erpc)|
| [thrift](https://github.com/andeya/erpc/blob/master/codec/thrift_codec.go) | `"github.com/andeya/erpc/v7/codec"` | Thrift кодек (собственный erpc)|
| [url](https://github.com/andeya/erpc/blob/master/codec/url_codec.go) | `"github.com/andeya/erpc/v7/codec"` | Кодек для URL-кодировки |
| [xml](https://github.com/andeya/erpc/blob/master/codec/xml_codec.go) | `"github.com/andeya/erpc/v7/codec"` | XML-кодек |
| [plain](https://github.com/andeya/erpc/blob/master/codec/plain_codec.go) | `"github.com/和deya/erpc/v7/codec"` | Кодек для обычного текста |
| [form](https://github.com/andeya/erpc/blob/master/codec/form_codec.go) | `"github.com/andeya/erpc/v7/codec"` | Кодек для формы с URL-кодировкой |
Замечено, что в последней строке есть некорректно переведенный текст `和deya`, который следует заменить на `andeya`.### плагины
| пакет | импорт | описание |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| [auth](https://github.com/andeya/erpc/tree/master/plugin/auth) | `"github.com/andeya/erpc/v7/plugin/auth"` | Плагин аутентификации для проверки соединений при первом обращении |
| [binder](https://github.com/andeya/erpc/tree/master/plugin/binder) | `"github.com/andeya/erpc/v7/plugin/binder"` | Плагин проверки привязки параметров для обработчика структур |
| [heartbeat](https://github.com/andeya/erpc/tree/master/plugin/heartbeat) | `"github.com/andeya/erpc/v7/plugin/heartbeat"` | Универсальный плагин для отправки сигналов жизнедеятельности |
| [proxy](https://github.com/andeya/erpc/tree/master/plugin/proxy) | `"github.com/andeya/erpc/v7/plugin/proxy"` | Прокси-плагин для обработки неизвестных вызовов или отправок |
| [secure](https://github.com/andeya/erpc/tree/master/plugin/secure) | `"github.com/andeya/erpc/v7/plugin/secure"` | Плагин шифрования/расшифровки сообщений |
| [overloader](https://github.com/andeya/erpc/tree/master/plugin/overloader) | `"github.com/andeya/erpc/v7/plugin/overloader"` | Плагин защиты от перегрузки |### протоколы
| пакет | импорт | описание |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| [rawproto](https://github.com/andeya/erpc/tree/master/proto/rawproto) | `"github.com/andeya/erpc/v7/proto/rawproto"` | Высокоэффективный протокол связи (по умолчанию в erpc) |
| [jsonproto](https://github.com/andeya/erpc/tree/master/proto/jsonproto) | `"github.com/andeya/erpc/v7/proto/jsonproto"` | Протокол связи в формате JSON |
| [pbproto] | пакет | импорт | описание |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| [pbproto](https://github.com/andeya/erpc/tree/master/proto/pbproto) | `"github.com/andeya/erpc/v7/proto/pbproto"` | Канал связи в формате Protocol Buffers |
| [thriftproto](https://github.com/andeya/erpc/tree/master/proto/thriftproto) | `"github.com/andeya/erpc/v7/proto/thriftproto"` | Канал связи в формате Apache Thrift |
| [httproto](https://github.com/andeya/erpc/tree/master/proto/httproto) | `"github.com/andeya/erpc/v7/proto/httproto"` | Канал связи в формате HTTP |
### Протоколы
| Пакет | Импорт | Описание |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| [rawproto](https://github.com/andeya/erpc/tree/master/proto/rawproto) | `"github.com/andeya/erpc/v7/proto/rawproto"` | Высокоэффективный протокол связи (по умолчанию в erpc) |
| [jsonproto](https://github.com/andeya/erpc/tree/master/proto/jsonproto) | `"github.com/edneya/erpc/v7/proto/jsonproto"` | Протокол связи в формате JSON |
| [pbproto] | Пакет | Импорт | Описание |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| [pbproto](https://github.com/andeya/erpc/tree/master/proto/pbproto) | `"github.com/andeya/erpc/v7/proto/pbproto"` | Канал связи в формате Protocol Buffers |
| [thriftproto](https://github.com/andeya/erpc/tree/master/proto/thriftproto) | `"github.com/andeya/erpc/v7/proto/thriftproto"` | Канал связи в формате Apache Thrift |
| [httproto](https://github.com/andeya/erpc/tree/master/proto/httproto) | `"github.com/andeya/erpc/v7/proto/httproto"` | Канал связи в формате HTTP |### Транспортные фильтры
| пакет | импорт | описание |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| [gzip](https://github.com/andeya/erpc/tree/master/xfer/gzip) | `"github.com/andeya/erpc/v7/xfer/gzip"` | Фильтр сжатия данных GZIP (собственный) |
| [md5](https://github.com/andeya/erpc/tree/master/xfer/md5) | `"github.com/andeya/erpc/v7/xfer/md5"` | Фильтр проверки целостности данных MD5 |
### Другие модули
| пакет | импорт | описание |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| [multiclient](https://github.com/andeya/erpc/tree/master/mixer/multiclient) | `"github.com/andeya/erpc/v7/mixer/multiclient"` | Буфер соединений клиента высокой пропускной способности при передаче больших сообщений (например, загрузке файлов) |
| [websocket](https://github.com/andeya/erpc/tree/master/mixer/websocket) | `"github.com/andeya/erpc/v7/mixer/websocket"` | Интеграция eRPC с протоколом WebSocket согласно спецификации RFC 6455 |
| [evio](https://github.com/andeya/erpc/tree/master/mixer/evio) | `"github.com/andeya/erpc/v7/mixer/evio"` | Быстрый сетевой фреймворк событийного цикла, использующий слой API eRPC |
| [html](https://github.com/xiaoenai/tp-micro/tree/master/helper/mod-html) | `html "github.com/xiaoenai/tp-micro/helper/mod-html"` | Генерация HTML для HTTP клиентов |## Проекты на основе eRPC
| проект | описание |
| ---------------------------------------- | ---------------------------------------- |
| [TP-Micro](https://github.com/xiaoenai/tp-micro) | TP-Micro — это минималистичный и мощный микросервисный фреймворк, основанный на eRPC. |
| [Pholcus](https://github.com/andeya/pholcus) | Pholcus (Паучок) — это мощный веб-скрейпер, написанный на чистом Go и поддерживающий распределённую архитектуру с высокой пропускной способностью. Программа направлена на сбор данных с интернета и предоставляет пользователям с навыками программирования на Go или JavaScript мощный инструмент для создания собственных правил. |
## Корпоративные пользователи
<a href="http://www.xiaoenai.com"><img src="https://raw.githubusercontent.com/andeya/imgs-repo/master/xiaoenai.png" height="50" alt="Shenzhen Mengzhiduo Information Technology Co., Ltd."/></a>
<a href="https://tech.pingan.com/index.html"><img src="http://pa-tech.hirede.com/templates/pa-tech/Images/logo.png" height="50" alt="Ping An Technology"/></a>
<br/>
<a href="http://www.fun.tv"><img src="http://static.funshion.com/open/static/img/logo.gif" height="70" alt="Beijing FengXing Online Technology Co., Ltd."/></a>
<a href="http://www.kejishidai.cn"><img src="http://simg.ktvms.com/picture/logo.png" height="70" alt="Beijing Keji Shidai Network Company"/></a>
<a href="https://www.kuaishou.com/"><img src="https://inews.gtimg.com/newsapp_bt/0/4400789257/1000" height="70" alt="KuaiShou Short Video Platform"/></a>
## Лицензионное соглашение
Проект eRPC использует лицензию Apache 2.0, которая является дружественной для коммерческого использования. [Apache2.0](https://github.com/andeya/erpc/raw/master/LICENSE)
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )