gRPC للغة Go (Golang): المكتبات والأمثلة
gRPC هو إطار عمل عالي الأداء لاستدعاء الإجراءات عن بُعد (RPC) من Google، يعتمد على HTTP/2 و Protocol Buffers (protobuf). للغة Go، يوجد تطبيق رسمي هو grpc-go، والذي يسمح بإنشاء خدمات مصغرة فعالة مع دعم البث ثنائي الاتجاه، تشفير TLS، والمعترضات (interceptors). في هذه المقالة ستجد وصفًا كاملاً للأدوات، أمثلة للخادم والعميل، بالإضافة إلى توصيات عملية.
المكتبات الأساسية لـ gRPC في Go
- google.golang.org/grpc — المكتبة الرئيسية لـ gRPC في Go. تتضمن أجزاء الخادم والعميل، دعم البث، البيانات الوصفية، وتوازن التحميل.
- google.golang.org/protobuf — حزمة للعمل مع رسائل protobuf: التجميع، التسلسل، إلغاء التسلسل.
- github.com/golang/protobuf/protoc-gen-go — إضافة لمترجم
protoc، تولد كود Go من ملفات.proto. - github.com/grpc-ecosystem/grpc-gateway — أداة لإنشاء وكيل REST فوق gRPC (مفيد للتوافق مع المتصفحات).
التثبيت والإعداد
قبل البدء، قم بتثبيت مترجم protobuf والإضافات:
# تثبيت protoc (Linux/macOS)sudo apt install protobuf-compiler # Ubuntu/Debianbrew install protobuf # macOS
# تثبيت الإضافات لـ Gogo install google.golang.org/protobuf/cmd/protoc-gen-go@latestgo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latestبعد التثبيت، قم بتحديث PATH بإضافة $GOPATH/bin.
تعريف الخدمة عبر ملف .proto
أنشئ ملفًا باسم hello.proto:
syntax = "proto3";
package hello;
option go_package = "example.com/grpc-demo/hello";
service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); rpc SayHelloStream (HelloRequest) returns (stream HelloReply);}
message HelloRequest { string name = 1;}
message HelloReply { string message = 1;}قم بتوليد كود Go باستخدام الأمر:
protoc --go_out=. --go-grpc_out=. hello.protoستظهر الملفات hello.pb.go (الرسائل) و hello_grpc.pb.go (الخدمة).
مثال لخادم بلغة Go
package main
import ( "log" "net"
pb "example.com/grpc-demo/hello" "google.golang.org/grpc")
type server struct { pb.UnimplementedGreeterServer}
func (s *server) SayHello(req *pb.HelloRequest, stream pb.Greeter_SayHelloServer) error { // RPC عادي return stream.Send(&pb.HelloReply{Message: "Hello, " + req.Name})}
func (s *server) SayHelloStream(req *pb.HelloRequest, stream pb.Greeter_SayHelloServer) error { // استجابة بث for i := 0; i < 5; i++ { if err := stream.Send(&pb.HelloReply{Message: "Hello " + req.Name + " #" + string(rune(i))}); err != nil { return err } } return nil}
func main() { lis, _ := net.Listen("tcp", ":50051") s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) log.Println("Server listening on :50051") if err := s.Serve(lis); err != nil { log.Fatalf("Failed to serve: %v", err) }}مثال لعميل بلغة Go
package main
import ( "context" "log" "time"
pb "example.com/grpc-demo/hello" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure")
func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close()
client := pb.NewGreeterClient(conn) ctx, ca