선적 서류 비치
Rust로 프로토콜을 쉽게 정의할 수 있습니다.
이 크레이트는 유형에 추가할 수 있는 사용자 정의 파생 항목을 추가하여 모든 IO 스트림에서 구조화된 데이터를 보내고 받을 수 있도록 합니다.
네트워킹이 내장되어 있으며 TCP 및 UDP에 대한 특별 지원이 제공됩니다.
정의한 프로토콜은 네트워킹 외부에서도 사용할 수 있습니다. Parcel::from_raw_bytes
및 Parcel::raw_bytes
메소드를 참조하세요.
이 상자에는 다음도 제공됩니다.
Parcel
를 쉽게 보내고 받을 수 있는 TCP 및 UDP 모듈사용법은 예제 폴더를 확인하세요.
이것을 Cargo.toml
에 추가하세요:
[ dependencies ]
protocol = { version = " 3.4 " , features = [ " derive " ] }
그런 다음 #[derive(protocol::Protocol)]
속성을 사용하여 유형을 정의합니다.
# [ derive ( protocol :: Protocol ) ]
struct Hello {
pub a : String ,
pub b : u32 ,
}
여기서 가장 흥미로운 부분은 protocol::Parcel
특성입니다. 이 특성을 구현하는 모든 유형은 바이트 스트림과 직렬화될 수 있습니다. 모든 기본 유형, 표준 컬렉션, 튜플 및 배열은 이 특성을 구현합니다.
이 상자는 자신만의 Parcel
유형을 정의할 때 특히 유용합니다. 이를 수행하려면 #[derive(protocol::Protocol)]
사용할 수 있습니다. 유형이 Parcel
구현하려면 Clone
, Debug
및 PartialEq
도 구현해야 합니다.
# [ derive ( Parcel , Clone , Debug , PartialEq ) ]
pub struct Health ( f32 ) ;
# [ derive ( Parcel , Clone , Debug , PartialEq ) ]
pub struct SetPlayerPosition {
pub position : ( f32 , f32 ) ,
pub health : Health ,
pub values : Vec < String > ,
}
모든 사용자 정의 유형에는 Parcel
특성이 자동으로 파생될 수 있습니다.
# [ derive ( protocol :: Protocol , Clone , Debug , PartialEq ) ]
pub struct Handshake ;
# [ derive ( protocol :: Protocol , Clone , Debug , PartialEq ) ]
pub struct Hello {
id : i64 ,
data : Vec < u8 > ,
}
# [ derive ( protocol :: Protocol , Clone , Debug , PartialEq ) ]
pub struct Goodbye {
id : i64 ,
reason : String ,
}
# [ derive ( protocol :: Protocol , Clone , Debug , PartialEq ) ]
pub struct Node {
name : String ,
enabled : bool
}
# [ protocol ( discriminant = "integer" ) ]
# [ derive ( protocol :: Protocol , Clone , Debug , PartialEq ) ]
pub enum PacketKind {
# [ protocol ( discriminator ( 0x00 ) ) ]
Handshake ( Handshake ) ,
# [ protocol ( discriminator ( 0xaa ) ) ]
Hello ( Hello ) ,
# [ protocol ( discriminator ( 0xaf ) ) ]
Goodbye ( Goodbye ) ,
}
fn main ( ) {
use std :: net :: TcpStream ;
let stream = TcpStream :: connect ( "127.0.0.1:34254" ) . unwrap ( ) ;
let mut connection = protocol :: wire :: stream :: Connection :: new ( stream , protocol :: wire :: middleware :: pipeline :: default ( ) ) ;
connection . send_packet ( & Packet :: Handshake ( Handshake ) ) . unwrap ( ) ;
connection . send_packet ( & Packet :: Hello ( Hello { id : 0 , data : vec ! [ 55 ] } ) ) . unwrap ( ) ;
connection . send_packet ( & Packet :: Goodbye ( Goodbye { id : 0 , reason : "leaving" . to_string ( ) } ) ) . unwrap ( ) ;
loop {
if let Some ( response ) = connection . receive_packet ( ) . unwrap ( ) {
println ! ( "{:?}" , response ) ;
break ;
}
}
}
열거형 값은 1 기반 변형 인덱스를 통해 전송되거나 각 변형의 문자열 이름을 전송하여 전송될 수 있습니다.
참고: 기본 동작은 변형 이름을 문자열 ( string
)로 사용하는 것입니다.
이 동작은 #[protocol(discriminant = "<type>")]
속성으로 변경될 수 있습니다.
지원되는 판별 유형:
string
(기본값)integer
# [ derive ( protocol :: Protocol , Clone , Debug , PartialEq ) ]
# [ protocol ( discriminant = "string" ) ]
pub enum PlayerState {
Stationary ,
Flying { velocity : ( f32 , f32 , f32 ) } ,
// Discriminators can be explicitly specified.
# [ protocol ( discriminator ( "ArbitraryOverTheWireName" ) ) ]
Jumping { height : f32 } ,
}
직렬화를 위해 변형 이름을 바꿀 수 있습니다.
# [ derive ( protocol :: Protocol , Clone , Debug , PartialEq ) ]
# [ protocol ( discriminant = "string" ) ]
pub enum Foo {
Bar ,
# [ protocol ( name = "Biz" ) ] // the Bing variant will be send/received as 'Biz'.
Bing ,
Baz ,
}