message-io
adalah perpustakaan jaringan berbasis peristiwa yang cepat dan mudah digunakan. Pustaka menangani soket OS secara internal dan menawarkan API pesan peristiwa sederhana kepada pengguna. Ini juga memungkinkan Anda membuat adaptor untuk protokol transport Anda sendiri dengan mengikuti beberapa aturan, mendelegasikan asinkroni yang membosankan dan manajemen thread ke perpustakaan.
Jika Anda menemukan masalah dalam menggunakan perpustakaan atau Anda memiliki ide untuk memperbaikinya, jangan ragu untuk membuka masalah. Kontribusi apa pun dipersilakan! Dan ingat: lebih banyak kafein, lebih produktif!
Mengelola soket itu sulit karena Anda harus berjuang dengan thread, konkurensi, dupleks penuh, pengkodean, kesalahan IO yang berasal dari OS (yang sangat sulit dipahami dalam beberapa situasi), dll. Jika Anda menggunakan soket non-pemblokiran , itu menambah lapisan kompleksitas baru: menyinkronkan peristiwa yang datang secara asinkron dari Sistem Operasi.
message-io
menawarkan cara mudah untuk mengatasi semua masalah yang disebutkan di atas, menjadikannya transparan bagi Anda, pemrogram yang ingin membuat aplikasi dengan masalahnya sendiri. Untuk itu, perpustakaan memberi Anda API sederhana dengan dua konsep untuk dipahami: pesan (data yang Anda kirim dan terima), dan titik akhir (penerima data tersebut). Abstraksi ini juga menawarkan kemungkinan untuk menggunakan API yang sama secara independen dari protokol transport yang digunakan. Anda dapat mengubah pengangkutan aplikasi Anda hanya dalam satu baris.
wasm
tidak didukung tetapi direncanakan).NodeHandler
untuk mengelola semua koneksi (menghubungkan, mendengarkan, menghapus, mengirim) dan sinyal (pengatur waktu, prioritas).NodeListener
untuk memproses semua sinyal dan kejadian dari jaringan.std::io::Error
internal yang gelap saat mengirim/menerima dari jaringan.message-io
tidak memiliki transportasi yang Anda butuhkan? Tambahkan adaptor dengan mudah. Tambahkan ke Cargo.toml
Anda (semua transportasi disertakan secara default):
[ dependencies ]
message-io = " 0.18 "
Jika Anda hanya ingin menggunakan sebagian dari baterai transport yang tersedia, Anda dapat memilihnya berdasarkan fitur terkait tcp
, udp
, dan websocket
. Misalnya, untuk hanya menyertakan TCP dan UDP , tambahkan ke Cargo.toml
Anda :
[ dependencies ]
message-io = { version = " 0.18 " , default-features = false , features = [ " tcp " , " udp " ] }
Contoh berikut adalah server paling sederhana yang membaca pesan dari klien dan meresponsnya dengan pesan yang sama. Ia mampu menawarkan "layanan" untuk 3 protokol berbeda secara bersamaan.
use message_io :: node :: { self } ;
use message_io :: network :: { NetEvent , Transport } ;
fn main ( ) {
// Create a node, the main message-io entity. It is divided in 2 parts:
// The 'handler', used to make actions (connect, send messages, signals, stop the node...)
// The 'listener', used to read events from the network or signals.
let ( handler , listener ) = node :: split :: < ( ) > ( ) ;
// Listen for TCP, UDP and WebSocket messages at the same time.
handler . network ( ) . listen ( Transport :: FramedTcp , "0.0.0.0:3042" ) . unwrap ( ) ;
handler . network ( ) . listen ( Transport :: Udp , "0.0.0.0:3043" ) . unwrap ( ) ;
handler . network ( ) . listen ( Transport :: Ws , "0.0.0.0:3044" ) . unwrap ( ) ;
// Read incoming network events.
listener . for_each ( move |event| match event . network ( ) {
NetEvent :: Connected ( _ , _ ) => unreachable ! ( ) , // Used for explicit connections.
NetEvent :: Accepted ( _endpoint , _listener ) => println ! ( "Client connected" ) , // Tcp or Ws
NetEvent :: Message ( endpoint , data ) => {
println ! ( "Received: {}" , String :: from_utf8_lossy ( data ) ) ;
handler . network ( ) . send ( endpoint , data ) ;
} ,
NetEvent :: Disconnected ( _endpoint ) => println ! ( "Client disconnected" ) , //Tcp or Ws
} ) ;
}
Contoh berikut menunjukkan klien yang dapat terhubung ke server sebelumnya. Ia mengirimkan pesan setiap detik ke server dan mendengarkan respons gemanya. Mengubah Transport::FramedTcp
menjadi Udp
atau Ws
akan mengubah transport dasar yang digunakan.
use message_io :: node :: { self , NodeEvent } ;
use message_io :: network :: { NetEvent , Transport } ;
use std :: time :: Duration ;
enum Signal {
Greet ,
// Any other app event here.
}
fn main ( ) {
let ( handler , listener ) = node :: split ( ) ;
// You can change the transport to Udp or Ws (WebSocket).
let ( server , _ ) = handler . network ( ) . connect ( Transport :: FramedTcp , "127.0.0.1:3042" ) . unwrap ( ) ;
listener . for_each ( move |event| match event {
NodeEvent :: Network ( net_event ) => match net_event {
NetEvent :: Connected ( _endpoint , _ok ) => handler . signals ( ) . send ( Signal :: Greet ) ,
NetEvent :: Accepted ( _ , _ ) => unreachable ! ( ) , // Only generated by listening
NetEvent :: Message ( _endpoint , data ) => {
println ! ( "Received: {}" , String :: from_utf8_lossy ( data ) ) ;
} ,
NetEvent :: Disconnected ( _endpoint ) => ( ) ,
}
NodeEvent :: Signal ( signal ) => match signal {
Signal :: Greet => { // computed every second
handler . network ( ) . send ( server , "Hello server!" . as_bytes ( ) ) ;
handler . signals ( ) . send_with_timer ( Signal :: Greet , Duration :: from_secs ( 1 ) ) ;
}
}
} ) ;
}
Kloning repositori dan uji contoh Ping Pong (mirip dengan contoh README tetapi lebih bervitamin).
Jalankan servernya:
cargo run --example ping-pong server tcp 3456
Jalankan klien:
cargo run --example ping-pong client tcp 127.0.0.1:3456
Anda dapat memainkannya dengan mengganti transportasi, menjalankan beberapa klien, memutus sambungannya, dll. Lihat selengkapnya di sini.
message-io
? Tambahkan adaptor! message-io
menawarkan dua jenis API. API pengguna yang berkomunikasi dengan message-io
itu sendiri sebagai pengguna perpustakaan, dan API adaptor internal bagi mereka yang ingin menambahkan adaptor protokol mereka ke dalam perpustakaan.
Jika protokol transport dapat dibangun di atas mio
(sebagian besar perpustakaan protokol yang ada dapat melakukannya), maka Anda dapat menambahkannya ke message-io
dengan sangat mudah :
Tambahkan file adaptor Anda di src/adapters/<my-transport-protocol>.rs
yang mengimplementasikan sifat-sifat yang Anda temukan di sini. Ini hanya berisi 8 fungsi wajib untuk diimplementasikan (lihat templat), dan dibutuhkan sekitar 150 baris untuk mengimplementasikan adaptor.
Tambahkan bidang baru di enum Transport
yang ditemukan di src/network/transport.rs untuk mendaftarkan adaptor baru Anda.
Itu saja. Anda dapat menggunakan transport baru Anda dengan API message-io
seperti yang lainnya.
Ups! satu langkah lagi: buat Pull Request agar semua orang bisa menggunakannya :)
message-io
Apakah proyek luar biasa Anda menggunakan message-io
? Buat Permintaan Tarik dan tambahkan ke daftar!
message-io
memiliki tujuan utama untuk menjaga semuanya tetap sederhana. Ini bagus, tapi terkadang sudut pandang ini bisa membuat hal-hal yang sudah rumit menjadi lebih rumit.
Misalnya, message-io
memungkinkan penanganan peristiwa jaringan asinkron tanpa menggunakan pola async/await
. Ini mengurangi kerumitan dalam menangani pesan pendapatan dari jaringan, dan itu sangat bagus. Namun demikian, aplikasi yang membaca pesan asinkron cenderung melakukan tugas asinkron pada kejadian ini juga. Warisan asinkron ini dapat dengan mudah disebarkan ke seluruh aplikasi Anda karena sulit dipertahankan atau diskalakan tanpa pola async/menunggu. Dalam hal ini, mungkin tokio
bisa menjadi pilihan yang lebih baik. Anda perlu menangani lebih banyak hal jaringan tingkat rendah tetapi Anda mendapatkan keuntungan dalam organisasi dan manajemen thread/sumber daya.
Masalah serupa dapat terjadi terkait penggunaan node message-io
. Karena sebuah node dapat digunakan secara independen sebagai klien/server atau keduanya, Anda dapat dengan mudah mulai membuat aplikasi peer to peer. Faktanya, ini adalah salah satu maksud dari message-io
. Namun demikian, jika tujuan Anda berskala, akan muncul masalah terkait pola ini yang harus ditangani, dan perpustakaan seperti libp2p
dilengkapi dengan banyak alat untuk membantu mengarsipkan tujuan tersebut.
Tentu saja, ini bukan penyangkalan mengenai penggunaan perpustakaan (saya menggunakannya!), ini lebih tentang kejujuran tentang kemampuannya, dan untuk memandu Anda ke alat yang tepat tergantung pada apa yang Anda cari.
Untuk meringkas:
message-io
!tokio
, libp2p
, atau lainnya, untuk memiliki kontrol lebih besar terhadapnya.