ओकाम प्रोग्रामिंग लाइब्रेरीज़, कमांड लाइन टूल्स और प्रबंधित क्लाउड सेवाओं का एक सूट है जो एंड-टू-एंड एन्क्रिप्शन, पारस्परिक प्रमाणीकरण, कुंजी प्रबंधन, क्रेडेंशियल प्रबंधन और प्राधिकरण नीति प्रवर्तन को बड़े पैमाने पर व्यवस्थित करता है। ओकाम का अंत-से-अंत
इसे संभव बनाने वाली प्रमुख विशेषताओं में से एक है
इस ब्लॉग पोस्ट में, हम ओकैम रस्ट एपीआई का पता लगाएंगे और देखेंगे कि ओकैम में रूटिंग कैसे काम करती है। हम रस्ट कोड के साथ काम करेंगे और कुछ कोड उदाहरण देखेंगे जो सरल केस और अधिक उन्नत उपयोग के मामलों को प्रदर्शित करते हैं।
आरंभ करने से पहले, आइए सुरक्षित अनुप्रयोगों के लिए मौजूदा दृष्टिकोणों का उपयोग करने के नुकसानों पर शीघ्रता से चर्चा करें। सुरक्षा कोई ऐसी चीज़ नहीं है जिसके बारे में हममें से अधिकांश लोग तब सोचते हैं जब हम सिस्टम का निर्माण कर रहे होते हैं और काम करने और शिपिंग पर ध्यान केंद्रित करते हैं।
पारंपरिक सुरक्षित संचार कार्यान्वयन आमतौर पर परिवहन प्रोटोकॉल के साथ इस तरह से कसकर जुड़े होते हैं कि उनकी सभी सुरक्षा एक अंतर्निहित परिवहन कनेक्शन की लंबाई और अवधि तक सीमित होती है।
उदाहरण के लिए, अधिकांश टीएलएस कार्यान्वयन अंतर्निहित टीसीपी कनेक्शन के साथ मजबूती से जुड़े हुए हैं। यदि आपके एप्लिकेशन का डेटा और अनुरोध दो टीसीपी कनेक्शन हॉप्स (टीसीपी → टीसीपी) पर यात्रा करते हैं, तो सभी टीएलएस दोनों नेटवर्क के बीच पुल टूटने की गारंटी देते हैं। यह ब्रिज, गेटवे या लोड बैलेंसर एप्लिकेशन डेटा के लिए कमजोरी का बिंदु बन जाता है।
पारंपरिक सुरक्षित संचार प्रोटोकॉल भी आपके एप्लिकेशन के डेटा की सुरक्षा करने में असमर्थ हैं यदि यह कई अलग-अलग परिवहन प्रोटोकॉल पर यात्रा करता है। यदि आपके एप्लिकेशन का संचार पथ यूडीपी → टीसीपी या बीएलई → टीसीपी है तो वे डेटा प्रामाणिकता या डेटा अखंडता की गारंटी नहीं दे सकते।
दूसरे शब्दों में, पारंपरिक सुरक्षित संचार कार्यान्वयन का उपयोग करके आप उस डेटा पर विश्वास खोने के द्वार खोल रहे हैं जिस पर आपके ऐप्स काम कर रहे हैं। यहां आपके ऐप्स के कुछ पहलू दिए गए हैं जो जोखिम में हो सकते हैं:
इसे मेरे ऐप पर किसने भेजा?
क्या यह वास्तव में वही डेटा है जो उन्होंने मेरे ऐप पर भेजा था?
प्रमाणीकरण और डेटा अखंडता गुम है.
इस ब्लॉग पोस्ट में, हम ओकैम रूटिंग और ओकैम ट्रांसपोर्ट्स का उपयोग करके एक दूसरे के साथ संचार करने वाले ओकैम नोड्स के दो उदाहरण बनाएंगे। हम इन ओकाम नोड्स को बनाने और ओकैम रूटिंग ऑर्केस्ट्रेशन को सेट करने के लिए रस्ट एपीआई का उपयोग करेंगे। ओकैम रूटिंग और ट्रांसपोर्ट अन्य ओकैम प्रोटोकॉल को एप्लिकेशन स्तर पर विश्वास, सुरक्षा, गोपनीयता, विश्वसनीय डिलीवरी और ऑर्डरिंग जैसी एंड-टू-एंड गारंटी प्रदान करने में सक्षम बनाते हैं।
ओकाम रूटिंग : एक सरल और हल्का संदेश-आधारित प्रोटोकॉल है जो विभिन्न प्रकार की संचार टोपोलॉजी पर संदेशों का द्विदिश आदान-प्रदान करना संभव बनाता है: टीसीपी -> टीसीपी या टीसीपी -> टीसीपी -> टीसीपी या बीएलई -> यूडीपी -> टीसीपी या बीएलई -> टीसीपी -> टीसीपी या टीसीपी -> काफ्का -> टीसीपी या कोई अन्य टोपोलॉजी जिसकी आप कल्पना कर सकते हैं।
ओक्कम परिवहन : विभिन्न परिवहन प्रोटोकॉल के लिए ओकाम रूटिंग को अनुकूलित करें।
ओकैम नोड कोई भी चालू एप्लिकेशन है जो विभिन्न ओकैम प्रोटोकॉल जैसे रूटिंग, रिले और पोर्टल्स, सिक्योर चैनल इत्यादि का उपयोग करके अन्य एप्लिकेशन के साथ संचार कर सकता है।
ओकैम नोड को किसी भी स्वतंत्र प्रक्रिया के रूप में परिभाषित किया जा सकता है जो ओकैम रूटिंग प्रोटोकॉल का समर्थन करने वाला एपीआई प्रदान करता है। हम इसका उपयोग करके ओकाम नोड्स बना सकते हैंockam
कमांड) या हमारे रस्ट और एलिक्सिर लाइब्रेरी जैसे विभिन्न ओकैम प्रोग्रामिंग लाइब्रेरी का उपयोग कर रहे हैं। हम इस ब्लॉग पोस्ट में रस्ट एपीआई का उपयोग करेंगे।
जब एक कार्यकर्ता को शुरू किया जाता है
हमारे पहले उदाहरण के लिए, हम एक सरल ओकाम नोड बनाएंगे जो एक कार्यकर्ता को (उसी नोड में) कुछ हॉप्स पर एक संदेश भेजेगा जो संदेश को वापस प्रतिध्वनित करता है। इसमें कोई टीसीपी ट्रांसपोर्ट शामिल नहीं है और सभी संदेश एक ही नोड के अंदर आगे और पीछे भेजे जा रहे हैं। इससे हमें बुनियादी स्तर पर निर्माण श्रमिकों और रूटिंग का अनुभव मिलेगा।
हमें एक main()
प्रोग्राम के साथ एक रस्ट स्रोत फ़ाइल और दो श्रमिकों के साथ दो अन्य रस्ट स्रोत फ़ाइलें बनाने की आवश्यकता होगी: Hopper
और Echoer
। फिर हम एक स्ट्रिंग संदेश भेज सकते हैं और देख सकते हैं कि क्या हम इसे वापस प्रतिध्वनित कर सकते हैं।
शुरू करने से पहले आइए रूटिंग पर विचार करें। जब हम एक नोड के अंदर एक संदेश भेजते हैं तो यह अपने साथ 2 मेटाडेटा फ़ील्ड, onward_route
और return_route
ले जाता है, जहां एक route
केवल adresses
की एक सूची है। प्रत्येक कार्यकर्ता को एक नोड में एक address
मिलता है।
इसलिए, यदि हम बीच में 3 हॉप्स के साथ app
पते से echoer
पते पर एक संदेश भेजना चाहते हैं, तो हम निम्नलिखित की तरह एक रूट बना सकते हैं।
┌───────────────────────┐ │ Node 1 │ ├───────────────────────┤ │ ┌────────────────┐ │ │ │ Address: │ │ │ │ 'app' │ │ │ └─┬────────────▲─┘ │ │ ┌─▼────────────┴─┐ │ │ │ Address: │ │ │ │ 'hopper1..3' │x3 │ │ └─┬────────────▲─┘ │ │ ┌─▼────────────┴─┐ │ │ │ Address: │ │ │ │ 'echoer' │ │ │ └────────────────┘ │ └───────────────────────┘
इस मार्ग को बनाने के लिए रस्ट कोड यहां दिया गया है।
/// Send a message to the echoer worker via the "hopper1", "hopper2", and "hopper3" workers. let route = route!["hopper1", "hopper2", "hopper3", "echoer"];
आइए आगे ऐसा करने के लिए कुछ स्रोत कोड जोड़ें। पहली चीज़ जो हम करेंगे वह इस खाली hello_ockam
प्रोजेक्ट में एक और निर्भरता जोड़ देंगे। colored
टोकरा हमें रंगीन कंसोल आउटपुट देगा जो हमारे उदाहरणों से आउटपुट को पढ़ने और समझने में बहुत आसान बना देगा।
cargo add colored
फिर हम एक नई /src/echoer.rs
फ़ाइल बनाकर और उसमें निम्नलिखित कोड को कॉपी/पेस्ट करके echoer
वर्कर को जोड़ते हैं (हमारे hello_ockam
प्रोजेक्ट में)।
use colored::Colorize; use ockam::{Context, Result, Routed, Worker}; pub struct Echoer; /// When a worker is started on a node, it is given one or more addresses. The node /// maintains a mailbox for each address and whenever a message arrives for a specific /// address it delivers that message to the corresponding registered worker. /// /// Workers can handle messages from other workers running on the same or a different /// node. In response to a message, an worker can: make local decisions, change its /// internal state, create more workers, or send more messages to other workers running on /// the same or a different node. #[ockam::worker] impl Worker for Echoer { type Context = Context; type Message = String; async fn handle_message(&mut self, ctx: &mut Context, msg: Routed<String>) -> Result<()> { // Echo the message body back on its return_route. let addr_str = ctx.address().to_string(); let msg_str = msg.as_body().to_string(); let new_msg_str = format!("👈 echo back: {}", msg); // Formatting stdout output. let lines = [ format!("📣 'echoer' worker → Address: {}", addr_str.bright_yellow()), format!(" Received: '{}'", msg_str.green()), format!(" Sent: '{}'", new_msg_str.cyan()), ]; lines .iter() .for_each(|line| println!("{}", line.white().on_black())); ctx.send(msg.return_route(), new_msg_str).await } }
इसके बाद, हम एक नई /src/hopper.rs
फ़ाइल बनाकर और उसमें निम्नलिखित कोड को कॉपी/पेस्ट करके hopper
वर्कर (हमारे hello_ockam
प्रोजेक्ट में) जोड़ते हैं।
ध्यान दें कि यह कार्यकर्ता संदेश को अगले हॉप पर भेजने के लिए onward_route
और return_route
फ़ील्ड में कैसे हेरफेर करता है। जब हम जल्द ही इस कोड को चलाएंगे तो हम वास्तव में इसे कंसोल आउटपुट में देखेंगे।
use colored::Colorize; use ockam::{Any, Context, Result, Routed, Worker}; pub struct Hopper; #[ockam::worker] impl Worker for Hopper { type Context = Context; type Message = Any; /// This handle function takes any incoming message and forwards. it to the next hop /// in it's onward route. async fn handle_message(&mut self, ctx: &mut Context, msg: Routed<Any>) -> Result<()> { // Cast the msg to a Routed<String> let msg: Routed<String> = msg.cast()?; let msg_str = msg.to_string().white().on_bright_black(); let addr_str = ctx.address().to_string().white().on_bright_black(); // Some type conversion. let mut message = msg.into_local_message(); let transport_message = message.transport_mut(); // Remove my address from the onward_route. let removed_address = transport_message.onward_route.step()?; let removed_addr_str = removed_address .to_string() .white() .on_bright_black() .strikethrough(); // Formatting stdout output. let lines = [ format!("🐇 'hopper' worker → Addr: '{}'", addr_str), format!(" Received: '{}'", msg_str), format!(" onward_route -> remove: '{}'", removed_addr_str), format!(" return_route -> prepend: '{}'", addr_str), ]; lines .iter() .for_each(|line| println!("{}", line.black().on_yellow())); // Insert my address at the beginning return_route. transport_message .return_route .modify() .prepend(ctx.address()); // Send the message on its onward_route. ctx.forward(message).await } }
और अंत में, आइए अपने hello_ockam
प्रोजेक्ट में एक main()
जोड़ें। यह हमारे उदाहरण के लिए प्रवेश बिंदु होगा।
एक खाली फ़ाइल /examples/03-routing-many.hops.rs
बनाएं (ध्यान दें कि यह examples/
फ़ोल्डर में है, न कि उपरोक्त कार्यकर्ताओं की तरह src/
फ़ोल्डर में)।
use colored::Colorize; use hello_ockam::{Echoer, Hopper}; use ockam::{node, route, Context, Result}; #[rustfmt::skip] const HELP_TEXT: &str =r#" ┌───────────────────────┐ │ Node 1 │ ├───────────────────────┤ │ ┌────────────────┐ │ │ │ Address: │ │ │ │ 'app' │ │ │ └─┬────────────▲─┘ │ │ ┌─▼────────────┴─┐ │ │ │ Address: │ │ │ │ 'hopper1..3' │x3 │ │ └─┬────────────▲─┘ │ │ ┌─▼────────────┴─┐ │ │ │ Address: │ │ │ │ 'echoer' │ │ │ └────────────────┘ │ └───────────────────────┘ "#; /// This node routes a message through many hops. #[ockam::node] async fn main(ctx: Context) -> Result<()> { println!("{}", HELP_TEXT.green()); print_title(vec![ "Run a node w/ 'app', 'echoer' and 'hopper1', 'hopper2', 'hopper3' workers", "then send a message over 3 hops", "finally stop the node", ]); // Create a node with default implementations. let mut node = node(ctx); // Start an Echoer worker at address "echoer". node.start_worker("echoer", Echoer).await?; // Start 3 hop workers at addresses "hopper1", "hopper2" and "hopper3". node.start_worker("hopper1", Hopper).await?; node.start_worker("hopper2", Hopper).await?; node.start_worker("hopper3", Hopper).await?; // Send a message to the echoer worker via the "hopper1", "hopper2", and "hopper3" workers. let route = route!["hopper1", "hopper2", "hopper3", "echoer"]; let route_msg = format!("{:?}", route); let msg = "Hello Ockam!"; node.send(route, msg.to_string()).await?; // Wait to receive a reply and print it. let reply = node.receive::<String>().await?; // Formatting stdout output. let lines = [ "🏃 Node 1 →".to_string(), format!(" sending: {}", msg.green()), format!(" over route: {}", route_msg.blue()), format!(" and receiving: '{}'", reply.purple()), // Should print "👈 echo back: Hello Ockam!" format!(" then {}", "stopping".bold().red()), ]; lines .iter() .for_each(|line| println!("{}", line.black().on_white())); // Stop all workers, stop the node, cleanup and return. node.stop().await } fn print_title(title: Vec<&str>) { let line = format!("🚀 {}", title.join("\n → ").white()); println!("{}", line.black().on_bright_black()) }
अब हमारे प्रोग्राम को चलाने का समय आ गया है कि यह क्या करता है! 🎉
अपने टर्मिनल ऐप में, निम्न कमांड चलाएँ। ध्यान दें कि OCKAM_LOG=none
का उपयोग ओक्कम लाइब्रेरी से लॉगिंग आउटपुट को अक्षम करने के लिए किया जाता है। उदाहरण के आउटपुट को पढ़ने में आसान बनाने के लिए ऐसा किया जाता है।
OCKAM_LOG=none cargo run --example 03-routing-many-hops
और आपको निम्नलिखित जैसा कुछ देखना चाहिए. हमारा उदाहरण प्रोग्राम app
और echoer
के बीच कई हॉप वर्कर (तीन hopper
वर्कर) बनाता है और उनके माध्यम से हमारे संदेश को रूट करता है।
इस उदाहरण में, हम परिचय देंगे
ओकैम ट्रांसपोर्ट ओकैम रूटिंग के लिए एक प्लगइन है। यह टीसीपी, यूडीपी, वेबसॉकेट, ब्लूटूथ इत्यादि जैसे विशिष्ट परिवहन प्रोटोकॉल का उपयोग करके ओकैम रूटिंग संदेशों को स्थानांतरित करता है।
हमारे पास तीन नोड होंगे:
node_initiator
: पहला नोड टीसीपी पर संदेश को मध्य नोड (पोर्ट 3000
) पर भेजना शुरू करता है।
node_middle
: फिर मध्य नोड बस इस संदेश को फिर से टीसीपी पर अंतिम नोड पर अग्रेषित करता है (इस बार पोर्ट 4000
)।
node_responder
: और अंत में, उत्तरदाता नोड संदेश प्राप्त करता है और आरंभकर्ता नोड को उत्तर भेजता है।
निम्नलिखित चित्र दर्शाता है कि हम आगे क्या बनाएंगे। इस उदाहरण में, ये सभी नोड एक ही मशीन पर हैं, लेकिन वे आसानी से अलग-अलग मशीनों पर नोड हो सकते हैं।
┌──────────────────────┐ │node_initiator │ ├──────────────────────┤ │ ┌──────────────────┐ │ │ │Address: │ │ ┌───────────────────────────┐ │ │'app' │ │ │node_middle │ │ └──┬────────────▲──┘ │ ├───────────────────────────┤ │ ┌──▼────────────┴──┐ │ │ ┌──────────────────┐ │ │ │TCP transport └─┼─────┼─►TCP transport │ │ │ │connect to 3000 ◄─┼─────┼─┐listening on 3000 │ │ │ └──────────────────┘ │ │ └──┬────────────▲──┘ │ └──────────────────────┘ │ ┌──▼────────────┴───────┐ │ │ │Address: │ │ ┌──────────────────────┐ │ │'forward_to_responder' │ │ │node_responder │ │ └──┬────────────▲───────┘ │ ├──────────────────────┤ │ ┌──▼────────────┴──┐ │ │ ┌──────────────────┐ │ │ │TCP transport └──────┼───┼─►TCP transport │ │ │ │connect to 4000 ◄──────┼───┼─┐listening on 4000 │ │ │ └──────────────────┘ │ │ └──┬────────────▲──┘ │ └───────────────────────────┘ │ ┌──▼────────────┴──┐ │ │ │Address: │ │ │ │'echoer' │ │ │ └──────────────────┘ │ └──────────────────────┘
आइए एक नई फ़ाइल /examples/04-routing-over-two-transport-hops.rs
( /examples/
फ़ोल्डर में, न कि /src/
फ़ोल्डर में) बनाकर शुरुआत करें। फिर उस फ़ाइल में निम्नलिखित कोड को कॉपी/पेस्ट करें।
use colored::Colorize; use hello_ockam::{Echoer, Forwarder}; use ockam::{ node, route, AsyncTryClone, Context, Result, TcpConnectionOptions, TcpListenerOptions, TcpTransportExtension, }; #[rustfmt::skip] const HELP_TEXT: &str =r#" ┌──────────────────────┐ │node_initiator │ ├──────────────────────┤ │ ┌──────────────────┐ │ │ │Address: │ │ ┌───────────────────────────┐ │ │'app' │ │ │node_middle │ │ └──┬────────────▲──┘ │ ├───────────────────────────┤ │ ┌──▼────────────┴──┐ │ │ ┌──────────────────┐ │ │ │TCP transport └─┼─────┼─►TCP transport │ │ │ │connect to 3000 ◄─┼─────┼─┐listening on 3000 │ │ │ └──────────────────┘ │ │ └──┬────────────▲──┘ │ └──────────────────────┘ │ ┌──▼────────────┴───────┐ │ │ │Address: │ │ ┌──────────────────────┐ │ │'forward_to_responder' │ │ │node_responder │ │ └──┬────────────▲───────┘ │ ├──────────────────────┤ │ ┌──▼────────────┴──┐ │ │ ┌──────────────────┐ │ │ │TCP transport └──────┼───┼─►TCP transport │ │ │ │connect to 4000 ◄──────┼───┼─┐listening on 4000 │ │ │ └──────────────────┘ │ │ └──┬────────────▲──┘ │ └───────────────────────────┘ │ ┌──▼────────────┴──┐ │ │ │Address: │ │ │ │'echoer' │ │ │ └──────────────────┘ │ └──────────────────────┘ "#; #[ockam::node] async fn main(ctx: Context) -> Result<()> { println!("{}", HELP_TEXT.green()); let ctx_clone = ctx.async_try_clone().await?; let ctx_clone_2 = ctx.async_try_clone().await?; let mut node_responder = create_responder_node(ctx).await.unwrap(); let mut node_middle = create_middle_node(ctx_clone).await.unwrap(); create_initiator_node(ctx_clone_2).await.unwrap(); node_responder.stop().await.ok(); node_middle.stop().await.ok(); println!( "{}", "App finished, stopping node_responder & node_middle".red() ); Ok(()) } fn print_title(title: Vec<&str>) { let line = format!("🚀 {}", title.join("\n → ").white()); println!("{}", line.black().on_bright_black()) }
यह कोड वास्तव में संकलित नहीं होगा, क्योंकि इस स्रोत फ़ाइल में 3 फ़ंक्शन गायब हैं। हम बाकी कोड को चरणबद्ध करने के लिए पहले इस फ़ाइल को जोड़ रहे हैं जिसे हम आगे लिखेंगे।
यह main()
फ़ंक्शन तीन नोड्स बनाता है जैसा कि हम ऊपर चित्र में देखते हैं, और उदाहरण चलने के बाद यह उन्हें रोक भी देता है।
तो आइए पहले उस फ़ंक्शन को लिखें जो आरंभकर्ता नोड बनाता है। निम्नलिखित को उस स्रोत फ़ाइल में कॉपी करें जिसे हमने पहले बनाया था ( /examples/04-routing-over-two-transport-hops.rs
), और इसे वहां मौजूदा कोड के नीचे पेस्ट करें:
/// This node routes a message, to a worker on a different node, over two TCP transport /// hops. async fn create_initiator_node(ctx: Context) -> Result<()> { print_title(vec![ "Create node_initiator that routes a message, over 2 TCP transport hops, to 'echoer' worker on node_responder", "stop", ]); // Create a node with default implementations. let mut node = node(ctx); // Initialize the TCP transport. let tcp_transport = node.create_tcp_transport().await?; // Create a TCP connection to the middle node. let connection_to_middle_node = tcp_transport .connect("localhost:3000", TcpConnectionOptions::new()) .await?; // Send a message to the "echoer" worker, on a different node, over two TCP hops. Wait // to receive a reply and print it. let route = route![connection_to_middle_node, "forward_to_responder", "echoer"]; let route_str = format!("{:?}", route); let msg = "Hello Ockam!"; let reply = node .send_and_receive::<String>(route, msg.to_string()) .await?; // Formatting stdout output. let lines = [ "🏃 node_initiator →".to_string(), format!(" sending: {}", msg.green()), format!(" over route: '{}'", route_str.blue()), format!(" and received: '{}'", reply.purple()), // Should print "👈 echo back: Hello Ockam!" format!(" then {}", "stopping".bold().red()), ]; lines .iter() .for_each(|line| println!("{}", line.black().on_white())); // Stop all workers, stop the node, cleanup and return. node.stop().await }
यह (आरंभकर्ता) नोड निम्नलिखित मार्ग का उपयोग करके उत्तरदाता को एक संदेश भेजेगा।
let route = route![connection_to_middle_node, "forward_to_responder", "echoer"];
आइए आगे मध्य नोड बनाएं, जो इस पते पर वर्कर Forwarder
चलाएगा: forward_to_responder
।
निम्नलिखित को हमारे द्वारा ऊपर बनाई गई स्रोत फ़ाइल ( /examples/04-routing-over-two-transport-hops.rs
) में कॉपी और पेस्ट करें।
यह मध्य नोड अपने टीसीपी श्रोता ( 3000
पर) में जो कुछ भी आता है उसे पोर्ट 4000
पर भेज देता है।
इस नोड में forward_to_responder
पते पर एक Forwarder
कार्यकर्ता है, इसलिए इस प्रकार आरंभकर्ता इस उदाहरण के प्रारंभ में अपने रूट में निर्दिष्ट पते तक पहुंच सकता है।
/// - Starts a TCP listener at 127.0.0.1:3000. /// - This node creates a TCP connection to a node at 127.0.0.1:4000. /// - Starts a forwarder worker to forward messages to 127.0.0.1:4000. /// - Then runs forever waiting to route messages. async fn create_middle_node(ctx: Context) -> Result<ockam::Node> { print_title(vec![ "Create node_middle that listens on 3000 and forwards to 4000", "wait for messages until stopped", ]); // Create a node with default implementations. let node = node(ctx); // Initialize the TCP transport. let tcp_transport = node.create_tcp_transport().await?; // Create a TCP connection to the responder node. let connection_to_responder = tcp_transport .connect("127.0.0.1:4000", TcpConnectionOptions::new()) .await?; // Create a Forwarder worker. node.start_worker( "forward_to_responder", Forwarder { address: connection_to_responder.into(), }, ) .await?; // Create a TCP listener and wait for incoming connections. let listener = tcp_transport .listen("127.0.0.1:3000", TcpListenerOptions::new()) .await?; // Allow access to the Forwarder via TCP connections from the TCP listener. node.flow_controls() .add_consumer("forward_to_responder", listener.flow_control_id()); // Don't call node.stop() here so this node runs forever. Ok(node) }
अंत में, हम रिस्पॉन्डर नोड बनाएंगे। यह नोड वर्कर echoer
चलाएगा जो वास्तव में संदेश को आरंभकर्ता तक प्रतिध्वनित करता है। उपरोक्त स्रोत फ़ाइल में निम्नलिखित को कॉपी और पेस्ट करें ( /examples/04-routing-over-two-transport-hops.rs
)।
इस नोड में पता echoer
पर एक Echoer
कार्यकर्ता है, इसलिए इस प्रकार आरंभकर्ता इस उदाहरण के प्रारंभ में अपने मार्ग में निर्दिष्ट पते तक पहुंच सकता है।
/// This node starts a TCP listener and an echoer worker. It then runs forever waiting for /// messages. async fn create_responder_node(ctx: Context) -> Result<ockam::Node> { print_title(vec![ "Create node_responder that runs tcp listener on 4000 and 'echoer' worker", "wait for messages until stopped", ]); // Create a node with default implementations. let node = node(ctx); // Initialize the TCP transport. let tcp_transport = node.create_tcp_transport().await?; // Create an echoer worker. node.start_worker("echoer", Echoer).await?; // Create a TCP listener and wait for incoming connections. let listener = tcp_transport .listen("127.0.0.1:4000", TcpListenerOptions::new()) .await?; // Allow access to the Echoer via TCP connections from the TCP listener. node.flow_controls() .add_consumer("echoer", listener.flow_control_id()); Ok(node) }
आइए यह उदाहरण चलाकर देखें कि यह क्या करता है 🎉।
अपने टर्मिनल ऐप में, निम्न कमांड चलाएँ। ध्यान दें कि OCKAM_LOG=none
का उपयोग ओक्कम लाइब्रेरी से लॉगिंग आउटपुट को अक्षम करने के लिए किया जाता है। उदाहरण के आउटपुट को पढ़ने में आसान बनाने के लिए ऐसा किया जाता है।
cargo run --example 04-routing-over-two-transport-hops
इसे निम्नलिखित के समान आउटपुट उत्पन्न करना चाहिए। हमारा उदाहरण प्रोग्राम एक रूट बनाता है जो कई नोड्स को पार करता है और टीसीपी app
से echoer
तक ट्रांसपोर्ट करता है और हमारे संदेश को उनके माध्यम से रूट करता है 🚀।
ओकाम रूटिंग और ट्रांसपोर्ट बेहद शक्तिशाली और लचीले हैं। वे प्रमुख विशेषताओं में से एक हैं जो ओकैम सिक्योर चैनल्स को लागू करने में सक्षम बनाती हैं। ओकैम रूटिंग पर ओक्कम सिक्योर चैनल्स और अन्य प्रोटोकॉल को लेयर करके, हम कई नेटवर्क और क्लाउड तक फैले मनमाने ट्रांसपोर्ट टोपोलॉजी पर एंड-टू-एंड गारंटी प्रदान कर सकते हैं।
भविष्य के ब्लॉग पोस्ट में, हम ओकम सिक्योर चैनलों को कवर करेंगे और उनका उपयोग मनमाने परिवहन टोपोलॉजी पर एंड-टू-एंड गारंटी प्रदान करने के लिए कैसे किया जा सकता है। तो मिले रहें!
इस बीच ओकाम के बारे में अधिक जानने के लिए यहां कुछ अच्छे शुरुआती बिंदु दिए गए हैं:
ockam
रेपो.