1. परिचय
इस कोडलैब में, gRPC-Go का इस्तेमाल करके एक क्लाइंट और सर्वर बनाया जाएगा. ये दोनों, Go में लिखे गए रूट-मैपिंग ऐप्लिकेशन की बुनियादी संरचना तैयार करते हैं.
ट्यूटोरियल के आखिर तक, आपके पास एक ऐसा क्लाइंट होगा जो gRPC का इस्तेमाल करके, रिमोट सर्वर से कनेक्ट होता है. इससे आपको मैप पर किसी खास जगह के नाम या पते की जानकारी मिलती है. कोई ऐप्लिकेशन, इस क्लाइंट-सर्वर डिज़ाइन का इस्तेमाल करके किसी रास्ते पर मौजूद लोकप्रिय जगहों की सूची बना सकता है या उनके बारे में खास जानकारी दे सकता है.
सेवा को प्रोटोकॉल बफ़र फ़ाइल में तय किया जाता है. इसका इस्तेमाल क्लाइंट और सर्वर के लिए बॉयलरप्लेट कोड जनरेट करने के लिए किया जाएगा, ताकि वे एक-दूसरे से कम्यूनिकेट कर सकें. इससे आपको इस सुविधा को लागू करने में समय और मेहनत नहीं करनी पड़ेगी.
जनरेट किया गया यह कोड, सर्वर और क्लाइंट के बीच कम्यूनिकेशन की जटिलताओं के साथ-साथ डेटा के क्रमबद्ध और क्रम से हटाने की प्रोसेस को भी मैनेज करता है.
आपको क्या सीखने को मिलेगा
- किसी सेवा के एपीआई को तय करने के लिए, प्रोटोकॉल बफ़र का इस्तेमाल कैसे करें.
- ऑटोमेटेड कोड जनरेशन का इस्तेमाल करके, Protocol Buffers की परिभाषा से gRPC पर आधारित क्लाइंट और सर्वर बनाने का तरीका.
- gRPC के साथ क्लाइंट-सर्वर कम्यूनिकेशन के बारे में जानकारी.
यह कोडलैब, Go डेवलपर के लिए है. यह उन डेवलपर के लिए भी है जो gRPC का इस्तेमाल पहली बार कर रहे हैं या gRPC के बारे में फिर से जानकारी पाना चाहते हैं. इसके अलावा, यह उन लोगों के लिए भी है जिनकी दिलचस्पी डिस्ट्रिब्यूटेड सिस्टम बनाने में है. इसके लिए, gRPC का अनुभव होना ज़रूरी नहीं है.
2. शुरू करने से पहले
ज़रूरी शर्तें
पक्का करें कि आपने ये इंस्टॉल किए हों:
- Go टूलचेन का वर्शन 1.24.5 या उसके बाद का वर्शन. इंस्टॉल करने के निर्देशों के लिए, Go की शुरू करें गाइड देखें.
- प्रोटोकॉल बफ़र कंपाइलर,
protoc
, वर्शन 3.27.1 या उसके बाद का वर्शन. इंस्टॉल करने के निर्देशों के लिए, कंपाइलर की इंस्टॉलेशन गाइड देखें. - Go और gRPC के लिए प्रोटोकॉल बफ़र कंपाइलर प्लगिन. इन प्लगिन को इंस्टॉल करने के लिए, ये कमांड चलाएं:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
अपने PATH
वैरिएबल को अपडेट करें, ताकि प्रोटोकॉल बफ़र कंपाइलर प्लग इन ढूंढ सके:
export PATH="$PATH:$(go env GOPATH)/bin"
कोड प्राप्त करें
इसलिए, आपको शुरू से काम न करना पड़े, इस कोडलैब में ऐप्लिकेशन के सोर्स कोड का एक स्केफ़ोल्ड दिया गया है. आपको इसे पूरा करना होगा. यहां दिए गए तरीके से, ऐप्लिकेशन को पूरा करने का तरीका जानें. इसमें, बॉयलरप्लेट gRPC कोड जनरेट करने के लिए, प्रोटोकॉल बफ़र कंपाइलर प्लगिन का इस्तेमाल करने का तरीका भी शामिल है.
इस सोर्स कोड को .ZIP आर्काइव के तौर पर GitHub से डाउनलोड करें और इसके कॉन्टेंट को अनपैक करें.
इसके अलावा, अगर आपको लागू करने के लिए टाइप नहीं करना है, तो पूरा सोर्स कोड GitHub पर उपलब्ध है.
3. सेवा के बारे में जानकारी देना
सबसे पहले, आपको प्रोटोकॉल बफ़र का इस्तेमाल करके, ऐप्लिकेशन की gRPC सेवा, उसके आरपीसी तरीके, और उसके अनुरोध और जवाब के मैसेज टाइप तय करने होंगे. आपकी सेवा से ये सुविधाएं मिलेंगी:
GetFeature
नाम की एक आरपीसी विधि, जिसे सर्वर लागू करता है और क्लाइंट कॉल करता है.Point
औरFeature
मैसेज टाइप, डेटा स्ट्रक्चर होते हैं.GetFeature
तरीके का इस्तेमाल करते समय, क्लाइंट और सर्वर के बीच इनका आदान-प्रदान होता है. क्लाइंट, सर्वर कोGetFeature
अनुरोध में मैप के कोऑर्डिनेटPoint
के तौर पर देता है. इसके जवाब में सर्वर, उन कोऑर्डिनेट पर मौजूद जानकारी के साथFeature
भेजता है.
इस आरपीसी तरीके और इसके मैसेज टाइप को, दिए गए सोर्स कोड की routeguide/route_guide.proto
फ़ाइल में तय किया जाएगा.
प्रोटोकॉल बफ़र को आम तौर पर, protobufs के नाम से जाना जाता है. gRPC की शब्दावली के बारे में ज़्यादा जानने के लिए, gRPC के मुख्य कॉन्सेप्ट, आर्किटेक्चर, और लाइफ़साइकल देखें.
मैसेज के टाइप
सोर्स कोड की routeguide/route_guide.proto
फ़ाइल में, सबसे पहले Point
मैसेज टाइप तय करें. Point
, मैप पर अक्षांश-देशांतर के निर्देशांकों के जोड़े को दिखाता है. इस कोडलैब के लिए, पूर्णांकों का इस्तेमाल करें:
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
1
और 2
नंबर, message
स्ट्रक्चर में मौजूद हर फ़ील्ड के लिए यूनीक आईडी नंबर होते हैं.
इसके बाद, Feature
मैसेज टाइप तय करें. Feature
, Point
में बताई गई जगह पर मौजूद किसी चीज़ के नाम या डाक पते के लिए string
फ़ील्ड का इस्तेमाल करता है:
message Feature {
// The name or address of the feature.
string name = 1;
// The point where the feature is located.
Point location = 2;
}
सेवा का तरीका
route_guide.proto
फ़ाइल में service
स्ट्रक्चर होता है, जिसका नाम RouteGuide
होता है. यह ऐप्लिकेशन की सेवा के ज़रिए उपलब्ध कराए गए एक या उससे ज़्यादा तरीकों के बारे में बताता है.
RouteGuide
की परिभाषा में rpc
तरीका GetFeature
जोड़ें. जैसा कि पहले बताया गया है, यह तरीका निर्देशांकों के दिए गए सेट से किसी जगह का नाम या पता ढूंढता है. इसलिए, दिए गए Point
के लिए GetFeature
को Feature
वापस लाने के लिए कहें:
service RouteGuide {
// Definition of the service goes here
// Obtains the feature at a given position.
rpc GetFeature(Point) returns (Feature) {}
}
यह एक यूनेरी आरपीसी तरीका है: एक सिंपल आरपीसी, जिसमें क्लाइंट सर्वर को अनुरोध भेजता है और जवाब मिलने का इंतज़ार करता है. यह लोकल फ़ंक्शन कॉल की तरह होता है.
4. क्लाइंट और सर्वर कोड जनरेट करना
इसके बाद, प्रोटोकॉल बफ़र कंपाइलर का इस्तेमाल करके, .proto
फ़ाइल से क्लाइंट और सर्वर, दोनों के लिए बॉयलरप्लेट gRPC कोड जनरेट करें. routeguide
डायरेक्ट्री में जाकर, यह कमांड चलाएं:
protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ route_guide.proto
इस कमांड से ये फ़ाइलें जनरेट होती हैं:
route_guide.pb.go
, जिसमें ऐप्लिकेशन के मैसेज टाइप बनाने और उनके डेटा को ऐक्सेस करने के फ़ंक्शन शामिल होते हैं.route_guide_grpc.pb.go
, जिसमें क्लाइंट के लिए फ़ंक्शन होते हैं. इनका इस्तेमाल करके, क्लाइंट सेवा के रिमोट gRPC तरीके को कॉल करता है. साथ ही, इसमें सर्वर के लिए फ़ंक्शन होते हैं. इनका इस्तेमाल करके, सर्वर रिमोट सेवा उपलब्ध कराता है.
इसके बाद, हम सर्वर साइड पर GetFeature
तरीके को लागू करेंगे, ताकि जब क्लाइंट कोई अनुरोध भेजे, तो सर्वर उसका जवाब दे सके.
5. सेवा लागू करना
सर्वर साइड पर मौजूद GetFeature
फ़ंक्शन, मुख्य काम करता है: यह क्लाइंट से Point
मैसेज लेता है और Feature
मैसेज में, जानी-पहचानी जगहों की सूची से जगह की जानकारी दिखाता है. यहां server/server.go
में फ़ंक्शन को लागू करने का तरीका बताया गया है:
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
for _, feature := range s.savedFeatures {
if proto.Equal(feature.Location, point) {
return feature, nil
}
}
// No feature was found, return an unnamed feature
return &pb.Feature{Location: point}, nil
}
जब किसी रिमोट क्लाइंट के अनुरोध के बाद इस तरीके को शुरू किया जाता है, तो फ़ंक्शन को Context
ऑब्जेक्ट पास किया जाता है. यह ऑब्जेक्ट, आरपीसी कॉल के बारे में बताता है. साथ ही, उस क्लाइंट के अनुरोध से Point
प्रोटोकॉल बफ़र ऑब्जेक्ट भी पास किया जाता है. यह फ़ंक्शन, खोजी गई जगह के लिए Feature
प्रोटोकॉल बफ़र ऑब्जेक्ट और ज़रूरत के मुताबिक error
दिखाता है.
इस तरीके में, दिए गए Point
के लिए सही जानकारी के साथ Feature
ऑब्जेक्ट भरें. इसके बाद, gRPC को यह बताने के लिए कि आपने आरपीसी को प्रोसेस कर लिया है और Feature
ऑब्जेक्ट को क्लाइंट को वापस भेजा जा सकता है, इसे nil
गड़बड़ी के साथ return
करें.
GetFeature
तरीके के लिए, routeGuideServer
ऑब्जेक्ट बनाना और रजिस्टर करना ज़रूरी है, ताकि जगह की जानकारी ढूंढने के लिए क्लाइंट से मिले अनुरोधों को उस फ़ंक्शन पर भेजा जा सके. यह काम main()
में किया जाता है:
func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
var opts []grpc.ServerOption
grpcServer := grpc.NewServer(opts...)
s := &routeGuideServer{}
s.loadFeatures()
pb.RegisterRouteGuideServer(grpcServer, s)
grpcServer.Serve(lis)
}
यहां सिलसिलेवार तरीके से बताया गया है कि main()
में क्या हो रहा है:
lis, err := net.Listen(...)
का इस्तेमाल करके, रिमोट क्लाइंट के अनुरोधों को सुनने के लिए टीसीपी पोर्ट तय करें. डिफ़ॉल्ट रूप से, ऐप्लिकेशन टीसीपी पोर्ट50051
का इस्तेमाल करता है. इसे वैरिएबलport
में तय किया जाता है. इसके अलावा, सर्वर चलाते समय कमांड लाइन पर--port
स्विच पास करके भी इसे तय किया जा सकता है. अगर टीसीपी पोर्ट नहीं खोला जा सकता, तो ऐप्लिकेशन बंद हो जाता है और गंभीर गड़बड़ी का मैसेज दिखता है.grpc.NewServer(...)
का इस्तेमाल करके gRPC सर्वर का एक इंस्टेंस बनाएं. इस इंस्टेंस का नामgrpcServer
रखें.routeGuideServer
के लिए एक पॉइंटर बनाएं. यह ऐप्लिकेशन की एपीआई सेवा को दिखाता है. पॉइंटर का नामs.
रखेंs.loadFeatures()
का इस्तेमाल करके,s.savedFeatures
ऐरे में उन जगहों की जानकारी डालें जिन्हेंGetFeature
की मदद से खोजा जा सकता है.- एपीआई सेवा को gRPC सर्वर के साथ रजिस्टर करें, ताकि
GetFeature
पर किए गए आरपीसी कॉल को सही फ़ंक्शन पर भेजा जा सके. - क्लाइंट के अनुरोधों को ब्लॉक करने के लिए, सर्वर पर
Serve()
को कॉल करें. यह तब तक जारी रहता है, जब तक प्रोसेस बंद नहीं हो जाती याStop()
को कॉल नहीं किया जाता.
loadFeatures()
फ़ंक्शन, निर्देशांकों से जगह की जानकारी पाने के लिए server/testdata.go
से मैपिंग करता है.
6. क्लाइंट बनाना
अब client/client.go
में बदलाव करें. यहीं पर आपको क्लाइंट कोड लागू करना होगा.
रिमोट सेवा के तरीकों को कॉल करने के लिए, हमें सबसे पहले सर्वर के साथ कम्यूनिकेट करने के लिए, gRPC चैनल बनाना होगा. हम इसे सर्वर के टारगेट यूआरआई स्ट्रिंग को क्लाइंट के main()
फ़ंक्शन में grpc.NewClient()
के तौर पर पास करके बनाते हैं. इस मामले में, यह सिर्फ़ पता और पोर्ट नंबर है. ऐसा इस तरह किया जाता है:
conn, err := grpc.NewClient("dns:///"+*serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("fail to dial: %v", err)
}
defer conn.Close()
सर्वर का पता, serverAddr
वैरिएबल से तय किया जाता है. यह डिफ़ॉल्ट रूप से localhost:50051
होता है. क्लाइंट चलाते समय, कमांड लाइन पर --addr
स्विच का इस्तेमाल करके इसे बदला जा सकता है.
अगर क्लाइंट को ऐसी सेवा से कनेक्ट करना है जिसके लिए पुष्टि करने वाले क्रेडेंशियल की ज़रूरत होती है, जैसे कि टीएलएस या JWT क्रेडेंशियल, तो क्लाइंट grpc.NewClient
में पैरामीटर के तौर पर DialOptions
ऑब्जेक्ट पास कर सकता है. इसमें ज़रूरी क्रेडेंशियल शामिल होते हैं. RouteGuide
सेवा के लिए किसी क्रेडेंशियल की ज़रूरत नहीं होती.
gRPC चैनल सेट अप करने के बाद, हमें Go फ़ंक्शन कॉल के ज़रिए आरपीसी करने के लिए, क्लाइंट स्टब की ज़रूरत होती है. हमें स्टब, ऐप्लिकेशन की .proto
फ़ाइल से जनरेट हुई route_guide_grpc.pb.go
फ़ाइल से मिले NewRouteGuideClient
तरीके का इस्तेमाल करके मिलता है.
import (pb "github.com/grpc-ecosystem/codelabs/getting_started_unary/routeguide")
client := pb.NewRouteGuideClient(conn)
कॉल सेवा के तरीके
gRPC-Go में, आरपीसी, ब्लॉकिंग/सिंक्रोनस मोड में काम करती हैं. इसका मतलब है कि आरपीसी कॉल, सर्वर के जवाब का इंतज़ार करता है. इसके बाद, यह या तो जवाब देगा या गड़बड़ी दिखाएगा.
Simple RPC
सिंपल आरपीसी GetFeature
को कॉल करना, लोकल तरीके client.GetFeature
को कॉल करने जितना ही आसान है:
point := &pb.Point{Latitude: 409146138, Longitude: -746188906}
log.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)
// Call GetFeature method on the client.
feature, err := client.GetFeature(context.TODO(), point)
if err != nil {
log.Fatalf("client.GetFeature failed: %v", err)
}
क्लाइंट, पहले बनाए गए स्टब पर मौजूद तरीके को कॉल करता है. तरीके के पैरामीटर के लिए, क्लाइंट Point
अनुरोध प्रोटोकॉल बफ़र ऑब्जेक्ट बनाता है और उसे भरता है. इसके अलावा, context.Context
ऑब्जेक्ट भी पास किया जाता है. इससे हमें ज़रूरत पड़ने पर, अपने आरपीसी के व्यवहार में बदलाव करने की अनुमति मिलती है. जैसे, कॉल के लिए समयसीमा तय करना या फ़्लाइट में आरपीसी को रद्द करना. अगर कॉल से कोई गड़बड़ी नहीं होती है, तो क्लाइंट, सर्वर से मिले रिस्पॉन्स की जानकारी को पहली रिटर्न वैल्यू से पढ़ सकता है:
log.Println(feature)
कुल मिलाकर, क्लाइंट का main()
फ़ंक्शन ऐसा दिखना चाहिए:
func main() {
flag.Parse()
// Set up a connection to the gRPC server.
conn, err := grpc.NewClient("dns:///"+*serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("fail to dial: %v", err)
}
defer conn.Close()
// Create a new RouteGuide stub.
client := pb.NewRouteGuideClient(conn)
point := &pb.Point{Latitude: 409146138, Longitude: -746188906}
log.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)
// Call GetFeature method on the client.
feature, err := client.GetFeature(context.TODO(), point)
if err != nil {
log.Fatalf("client.GetFeature failed: %v", err)
}
log.Println(feature)
}
7. इसे आज़माएं
पुष्टि करें कि सर्वर और क्लाइंट एक-दूसरे के साथ सही तरीके से काम कर रहे हैं. इसके लिए, ऐप्लिकेशन की वर्किंग डायरेक्ट्री में ये कमांड चलाएं:
- सर्वर को एक टर्मिनल में चलाएं:
cd server go run .
- क्लाइंट को किसी दूसरे टर्मिनल से चलाएं:
cd client go run .
आपको इस तरह का आउटपुट दिखेगा. इसमें टाइमस्टैंप को हटा दिया गया है, ताकि जानकारी साफ़ तौर पर दिख सके:
Getting feature for point (409146138, -746188906)
name:"Berkshire Valley Management Area Trail, Jefferson, NJ, USA" location:<latitude:409146138 longitude:-746188906 >
Getting feature for point (0, 0)
location:<>
8. आगे क्या करना है
- gRPC का परिचय और मुख्य सिद्धांत में जाकर, जानें कि gRPC कैसे काम करता है
- बुनियादी बातों वाला ट्यूटोरियल देखें
- एपीआई के बारे में जानकारी देखें