Ockam là một bộ thư viện lập trình, công cụ dòng lệnh và dịch vụ đám mây được quản lý để điều phối mã hóa đầu cuối, xác thực lẫn nhau, quản lý khóa, quản lý thông tin xác thực và thực thi chính sách ủy quyền — tất cả đều ở quy mô lớn. Từ đầu đến cuối của Ockam
Một trong những tính năng chính làm cho điều này có thể là
Trong bài đăng trên blog này, chúng ta sẽ khám phá Ockam Rust API và xem cách định tuyến hoạt động trong Ockam. Chúng ta sẽ làm việc với mã Rust và xem xét một số ví dụ về mã minh họa cho trường hợp đơn giản và các trường hợp sử dụng nâng cao hơn.
Trước khi bắt đầu, chúng ta hãy nhanh chóng thảo luận về những cạm bẫy của việc sử dụng các phương pháp hiện có để bảo mật các ứng dụng. Bảo mật không phải là điều mà hầu hết chúng ta nghĩ đến khi xây dựng hệ thống và tập trung vào việc làm cho mọi thứ hoạt động và vận chuyển.
Việc triển khai giao tiếp an toàn truyền thống thường được kết hợp chặt chẽ với các giao thức truyền tải theo cách mà tất cả bảo mật của chúng được giới hạn trong độ dài và thời lượng của một kết nối truyền tải cơ bản.
Ví dụ: hầu hết các triển khai TLS đều được kết hợp chặt chẽ với kết nối TCP bên dưới. Nếu dữ liệu và yêu cầu của ứng dụng của bạn di chuyển qua hai bước nhảy kết nối TCP (TCP → TCP), thì tất cả TLS đảm bảo sẽ ngắt tại cầu nối giữa hai mạng. Sau đó, cầu nối, cổng hoặc bộ cân bằng tải này trở thành điểm yếu đối với dữ liệu ứng dụng.
Các giao thức truyền thông an toàn truyền thống cũng không thể bảo vệ dữ liệu ứng dụng của bạn nếu nó di chuyển qua nhiều giao thức truyền tải khác nhau. Họ không thể đảm bảo tính xác thực của dữ liệu hoặc tính toàn vẹn của dữ liệu nếu đường dẫn giao tiếp của ứng dụng của bạn là UDP → TCP hoặc BLE → TCP.
Nói cách khác, bằng cách sử dụng các triển khai liên lạc an toàn truyền thống, bạn có thể đang mở ra cơ hội đánh mất lòng tin vào dữ liệu mà ứng dụng của bạn đang hoạt động. Dưới đây là một số khía cạnh của ứng dụng của bạn có thể gặp rủi ro:
Ai đã gửi nó đến ứng dụng của tôi?
Nó thực sự là dữ liệu họ đã gửi cho ứng dụng của tôi?
Thiếu xác thực và tính toàn vẹn của dữ liệu.
Trong bài đăng trên blog này, chúng tôi sẽ tạo hai ví dụ về các nút Ockam giao tiếp với nhau bằng cách sử dụng định tuyến Ockam và vận chuyển Ockam. Chúng tôi sẽ sử dụng API Rust để tạo các nút Ockam này và thiết lập điều phối định tuyến Ockam. Định tuyến và vận chuyển Ockam cho phép các giao thức Ockam khác cung cấp các đảm bảo từ đầu đến cuối như độ tin cậy, bảo mật, quyền riêng tư, phân phối đáng tin cậy và đặt hàng ở lớp ứng dụng.
Định tuyến Ockam : là một giao thức dựa trên thông báo đơn giản và gọn nhẹ, cho phép trao đổi thông báo hai chiều qua nhiều cấu trúc liên kết giao tiếp khác nhau: TCP -> TCP hoặc TCP -> TCP -> TCP hoặc BLE -> UDP -> TCP hoặc BLE -> TCP -> TCP hoặc TCP -> Kafka -> TCP hoặc bất kỳ cấu trúc liên kết nào khác mà bạn có thể tưởng tượng.
Vận chuyển Ockam : điều chỉnh định tuyến Ockam với các giao thức vận chuyển khác nhau.
Nút Ockam là bất kỳ ứng dụng đang chạy nào có thể giao tiếp với các ứng dụng khác bằng các giao thức Ockam khác nhau như Định tuyến, Rơle và Cổng, Kênh bảo mật, v.v.
Nút Ockam có thể được định nghĩa là bất kỳ quy trình độc lập nào cung cấp API hỗ trợ giao thức định tuyến Ockam. Chúng ta có thể tạo các nút Ockam bằng cách sử dụngockam
) hoặc sử dụng các thư viện lập trình Ockam khác nhau như thư viện Rust và Elixir của chúng tôi. Chúng tôi sẽ sử dụng API Rust trong bài đăng trên blog này.
Khi một công nhân được bắt đầu trên một
Đối với ví dụ đầu tiên của chúng tôi, chúng tôi sẽ tạo một nút Ockam đơn giản sẽ gửi một thông báo qua một số bước nhảy (trong cùng một nút) tới một công nhân (trong cùng một nút) chỉ phản hồi lại thông báo. Không có sự vận chuyển TCP nào liên quan và tất cả các thông báo được truyền qua lại trong cùng một nút. Điều này sẽ cho chúng ta cảm giác về công nhân xây dựng và định tuyến ở mức cơ bản.
Chúng ta sẽ cần tạo một tệp nguồn Rust bằng chương trình main()
và hai tệp nguồn Rust khác với hai worker: Hopper
và Echoer
. Sau đó, chúng tôi có thể gửi một thông báo chuỗi và xem liệu chúng tôi có thể gửi lại thông báo đó không.
Trước khi chúng tôi bắt đầu, hãy xem xét định tuyến. Khi chúng tôi gửi một tin nhắn bên trong một nút, nó mang theo 2 trường siêu dữ liệu, onward_route
và return_route
, trong đó một route
chỉ đơn giản là một danh sách adresses
. Mỗi công nhân nhận được một address
trong một nút.
Vì vậy, nếu chúng tôi muốn gửi tin nhắn từ địa chỉ app
đến địa chỉ echoer
, với 3 bước nhảy ở giữa, chúng tôi có thể tạo một tuyến đường như sau.
┌───────────────────────┐ │ Node 1 │ ├───────────────────────┤ │ ┌────────────────┐ │ │ │ Address: │ │ │ │ 'app' │ │ │ └─┬────────────▲─┘ │ │ ┌─▼────────────┴─┐ │ │ │ Address: │ │ │ │ 'hopper1..3' │x3 │ │ └─┬────────────▲─┘ │ │ ┌─▼────────────┴─┐ │ │ │ Address: │ │ │ │ 'echoer' │ │ │ └────────────────┘ │ └───────────────────────┘
Đây là mã Rust để xây dựng tuyến đường này.
/// Send a message to the echoer worker via the "hopper1", "hopper2", and "hopper3" workers. let route = route!["hopper1", "hopper2", "hopper3", "echoer"];
Hãy thêm một số mã nguồn để thực hiện điều này tiếp theo. Điều đầu tiên chúng ta sẽ làm là thêm một phụ thuộc nữa vào dự án hello_ockam
trống rỗng này. Hộp colored
sẽ cung cấp cho chúng tôi đầu ra bảng điều khiển được tô màu, giúp đầu ra từ các ví dụ của chúng tôi dễ đọc và dễ hiểu hơn rất nhiều.
cargo add colored
Sau đó, chúng tôi thêm trình tạo echoer
(trong dự án hello_ockam
của chúng tôi) bằng cách tạo tệp /src/echoer.rs
mới và sao chép/dán mã sau vào đó.
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 } }
Tiếp theo, chúng tôi thêm nhân viên hopper
(trong dự án hello_ockam
của chúng tôi) bằng cách tạo tệp /src/hopper.rs
mới và sao chép/dán mã sau vào đó.
Lưu ý cách nhân viên này thao tác các trường onward_route
& return_route
của tin nhắn để gửi nó đến chặng tiếp theo. Chúng tôi sẽ thực sự thấy điều này trong đầu ra của bảng điều khiển khi chúng tôi chạy mã này sớm.
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 } }
Và cuối cùng, hãy thêm một main()
vào dự án hello_ockam
của chúng ta. Đây sẽ là điểm vào cho ví dụ của chúng tôi.
Tạo một tệp trống /examples/03-routing-many.hops.rs
(lưu ý rằng tệp này nằm trong thư mục examples/
chứ không phải thư mục src/
như các công nhân ở trên).
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()) }
Bây giờ là lúc để chạy chương trình của chúng tôi để xem những gì nó làm! 🎉
Trong ứng dụng đầu cuối của bạn, hãy chạy lệnh sau. Lưu ý rằng OCKAM_LOG=none
được sử dụng để tắt đầu ra ghi nhật ký từ thư viện Ockam. Điều này được thực hiện để làm cho đầu ra của ví dụ dễ đọc hơn.
OCKAM_LOG=none cargo run --example 03-routing-many-hops
Và bạn sẽ thấy một cái gì đó như sau. Chương trình ví dụ của chúng tôi tạo nhiều nhân viên hop (ba nhân viên hopper
) giữa app
và echoer
và định tuyến thông điệp của chúng tôi thông qua họ 🚀.
Trong ví dụ này, chúng tôi sẽ giới thiệu
Vận chuyển Ockam là một plugin cho định tuyến Ockam. Nó di chuyển các thông báo định tuyến Ockam bằng một giao thức vận chuyển cụ thể như TCP, UDP, WebSockets, Bluetooth, v.v.
Chúng tôi sẽ có ba nút:
node_initiator
: Nút đầu tiên bắt đầu gửi tin nhắn qua TCP đến nút giữa (cổng 3000
).
node_middle
: Sau đó, nút ở giữa chỉ cần chuyển tiếp thông báo này đến nút cuối cùng qua TCP một lần nữa (lần này là cổng 4000
).
node_responder
: Và cuối cùng, nút phản hồi nhận được tin nhắn và gửi phản hồi lại cho nút khởi tạo.
Sơ đồ sau đây mô tả những gì chúng ta sẽ xây dựng tiếp theo. Trong ví dụ này, tất cả các nút này nằm trên cùng một máy, nhưng chúng có thể dễ dàng chỉ là các nút trên các máy khác nhau.
┌──────────────────────┐ │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' │ │ │ └──────────────────┘ │ └──────────────────────┘
Hãy bắt đầu bằng cách tạo một tệp mới /examples/04-routing-over-two-transport-hops.rs
(trong thư mục /examples/
chứ không phải thư mục /src/
). Sau đó sao chép/dán đoạn mã sau vào tệp đó.
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()) }
Mã này sẽ không thực sự được biên dịch, vì có 3 hàm bị thiếu trong tệp nguồn này. Chúng tôi chỉ thêm tệp này trước để tạo phần còn lại của mã mà chúng tôi sẽ viết tiếp theo.
main()
này tạo ba nút như chúng ta thấy trong sơ đồ bên trên và nó cũng dừng chúng sau khi chạy xong ví dụ.
Vì vậy, trước tiên hãy viết hàm tạo nút khởi tạo. Sao chép phần sau vào tệp nguồn mà chúng tôi đã tạo trước đó ( /examples/04-routing-over-two-transport-hops.rs
) và dán nó vào bên dưới mã hiện có ở đó:
/// 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 }
Nút (người khởi xướng) này sẽ gửi một thông báo đến người phản hồi bằng cách sử dụng tuyến đường sau.
let route = route![connection_to_middle_node, "forward_to_responder", "echoer"];
Tiếp theo, hãy tạo nút giữa, nút này sẽ chạy worker Forwarder
trên địa chỉ này: forward_to_responder
.
Sao chép và dán phần sau vào tệp nguồn chúng tôi đã tạo ở trên ( /examples/04-routing-over-two-transport-hops.rs
).
Nút giữa này chỉ cần chuyển tiếp bất cứ thứ gì đi vào trình nghe TCP của nó (trên 3000
) đến cổng 4000
.
Nút này có một trình xử lý Forwarder
trên địa chỉ forward_to_responder
, vì vậy đó là cách trình khởi tạo có thể đến địa chỉ được chỉ định trong tuyến của nó khi bắt đầu ví dụ này.
/// - 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) }
Cuối cùng, chúng tôi sẽ tạo nút phản hồi. Nút này sẽ chạy worker echoer
thực sự lặp lại thông báo trở lại bộ khởi tạo. Sao chép và dán đoạn mã sau vào tệp nguồn ở trên ( /examples/04-routing-over-two-transport-hops.rs
).
Nút này có một bộ xử lý Echoer
trên echoer
địa chỉ, vì vậy đó là cách bộ khởi tạo có thể đến địa chỉ được chỉ định trong tuyến của nó khi bắt đầu ví dụ này.
/// 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) }
Hãy chạy ví dụ này để xem những gì nó làm 🎉.
Trong ứng dụng đầu cuối của bạn, hãy chạy lệnh sau. Lưu ý rằng OCKAM_LOG=none
được sử dụng để tắt đầu ra ghi nhật ký từ thư viện Ockam. Điều này được thực hiện để làm cho đầu ra của ví dụ dễ đọc hơn.
cargo run --example 04-routing-over-two-transport-hops
Điều này sẽ tạo ra đầu ra tương tự như sau. Chương trình ví dụ của chúng tôi tạo một tuyến đường đi qua nhiều nút và TCP vận chuyển từ app
đến echoer
và định tuyến thông báo của chúng tôi qua chúng 🚀.
Định tuyến và vận chuyển Ockam cực kỳ mạnh mẽ và linh hoạt. Chúng là một trong những tính năng chính cho phép triển khai Kênh bảo mật Ockam. Bằng cách xếp lớp các Kênh bảo mật Ockam và các giao thức khác qua định tuyến Ockam, chúng tôi có thể cung cấp bảo đảm từ đầu đến cuối đối với các cấu trúc liên kết vận chuyển tùy ý trải rộng trên nhiều mạng và đám mây.
Trong một bài đăng trên blog trong tương lai, chúng tôi sẽ đề cập đến các Kênh bảo mật Ockam và cách chúng có thể được sử dụng để cung cấp bảo đảm từ đầu đến cuối đối với các cấu trúc liên kết vận chuyển tùy ý. Vậy nên hãy chờ trong giây lát!
Trong thời gian chờ đợi, đây là một số điểm khởi đầu tốt để tìm hiểu thêm về Ockam:
ockam
.
Cũng được xuất bản ở đây.