gRPC — это высокопроизводительная платформа с открытым исходным кодом для создания API удаленного вызова процедур (RPC). Он использует буферы протокола (Protobuf) в качестве формата сериализации данных по умолчанию и поддерживает двунаправленную потоковую передачу, что делает его идеальным выбором для создания приложений реального времени.

В этом уроке мы рассмотрим, как использовать gRPC и Protobuf для потоковой передачи данных в Golang. Мы создадим простое приложение для чата, которое позволит клиентам присоединяться к чату и отправлять сообщения друг другу в режиме реального времени с использованием двунаправленной потоковой передачи.

Предпосылка

Вам необходимо установить пакеты gRPC и Protobuf для Golang. Вы можете сделать это, выполнив следующую команду:

go get -u google.golang.org/grpc
go get -u github.com/golang/protobuf/protoc-gen-go

Шаг 1: Определите сообщение Protobuf

Далее вам необходимо определить службу и сообщения gRPC в файле .proto. Вот пример:

syntax = "proto3";
option go_package = "./;pb";

service ChatService {
  rpc JoinChat (stream JoinRequest) returns (stream ChatMessage);
}

message JoinRequest {
  string username = 1;
}

message ChatMessage {
  string username = 1;
  string message = 2;
}

Здесь определяется ChatService с методом JoinChat, который принимает поток JoinRequest сообщений и возвращает поток ChatMessage сообщений.

Шаг 2. Сгенерируйте код Go

После того как вы определили типы сообщений, вам необходимо сгенерировать код Go из файла .proto.

Вот пример команды:

protoc --go_out=. \
       --go_opt=paths=source_relative \
       --go-grpc_out=. \
       --go-grpc_opt=paths=source_relative \
       path/to/your.proto

Это создаст два файла: message.pb.go и message_grpc.pb.go.

Шаг 3. Создайте службу gRPC.

Теперь вы можете реализовать свой gRPC-сервер.

package main

import (
 "fmt"
 "log"
 "net"

 "google.golang.org/grpc"

 pb "github.com/grpc-streaming/pb"
)

type server struct {
 pb.UnimplementedChatServiceServer
}

func (s *server) JoinChat(stream pb.ChatService_JoinChatServer) error…