1. परिचय
इस कोडलैब में, gRPC-Go का इस्तेमाल करके एक क्लाइंट और सर्वर बनाया जाएगा. ये दोनों, Go में लिखे गए रूट-मैपिंग ऐप्लिकेशन की बुनियादी ज़रूरतें पूरी करते हैं.
ट्यूटोरियल के आखिर तक, आपके पास एक ऐसा क्लाइंट होगा जो gRPC का इस्तेमाल करके, रिमोट सर्वर से कनेक्ट होता है. इससे आपको मैप पर किसी खास जगह के नाम या पते की जानकारी मिलती है. कोई ऐप्लिकेशन, इस क्लाइंट-सर्वर डिज़ाइन का इस्तेमाल करके किसी रास्ते पर मौजूद लोकप्रिय जगहों की सूची बना सकता है या उनके बारे में खास जानकारी दे सकता है.
सेवा को प्रोटोकॉल बफ़र फ़ाइल में तय किया जाता है. इसका इस्तेमाल क्लाइंट और सर्वर के लिए बॉयलरप्लेट कोड जनरेट करने के लिए किया जाएगा, ताकि वे एक-दूसरे से कम्यूनिकेट कर सकें. इससे आपको इस सुविधा को लागू करने में समय और मेहनत नहीं करनी पड़ेगी.
जनरेट किया गया यह कोड, सर्वर और क्लाइंट के बीच कम्यूनिकेशन की जटिलताओं के साथ-साथ डेटा के क्रमबद्ध और क्रम से हटाने की प्रोसेस को भी मैनेज करता है.
आपको क्या सीखने को मिलेगा
- किसी सेवा के एपीआई को तय करने के लिए, प्रोटोकॉल बफ़र का इस्तेमाल कैसे करें.
- ऑटोमेटेड कोड जनरेशन का इस्तेमाल करके, प्रोटोकॉल बफ़र की परिभाषा से 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 सेवा, उसके RPC तरीके, और अनुरोध और जवाब के मैसेज टाइप तय करने होंगे. आपकी सेवा से ये सुविधाएं मिलेंगी:
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, string फ़ील्ड का इस्तेमाल करता है. इससे Point में बताई गई जगह पर मौजूद किसी चीज़ का नाम या डाक पता पता चलता है:
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 ऑब्जेक्ट भरें. इसके बाद, nil गड़बड़ी के साथ इसे return करें, ताकि gRPC को यह पता चल सके कि आपने आरपीसी को प्रोसेस कर लिया है और Feature ऑब्जेक्ट को क्लाइंट को वापस भेजा जा सकता है.
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 क्रेडेंशियल, तो क्लाइंट DialOptions ऑब्जेक्ट को grpc.NewClient में पैरामीटर के तौर पर पास कर सकता है. इसमें ज़रूरी क्रेडेंशियल शामिल होते हैं. 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 में, आरपीसी, ब्लॉकिंग/सिंक्रोनस मोड में काम करती हैं. इसका मतलब है कि आरपीसी कॉल, सर्वर के जवाब का इंतज़ार करता है. इसके बाद, यह या तो जवाब देगा या गड़बड़ी दिखाएगा.
सिंपल आरपीसी
सिंपल आरपीसी 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 कैसे काम करता है
- बुनियादी बातों वाला ट्यूटोरियल देखें
- एपीआई के बारे में जानकारी देखें