15 releases (6 breaking)
Uses old Rust 2015
0.7.1 | Mar 21, 2017 |
---|---|
0.7.0 | Mar 19, 2017 |
0.6.0 | Mar 16, 2017 |
0.5.3 | Mar 13, 2017 |
0.1.4 | Feb 23, 2017 |
#202 in WebSocket
44 downloads per month
Used in 5 crates
140KB
3K
SLoC
twist
An implementation of the RFC6455 websocket protocol as a tokio-core Codec and a tokio-proto pipeline ServerProto
This can be used to serve up a tokio-service Service in a tokio-proto TcpServer (See twists for an example).
Note: Even though this is implemented as a pipeline protocol, fragmented websocket messages are supported, so streaming from a websocket client is supported.
Usage
Include the following in your Cargo.toml
dependencies section
twist = "0.1.3"
Extensions
Per Message extensions are now supported by twist
. A per-message extension is applied when a text or binary frame is complete, or a set of fragmented text or binary frames have been fully assembled.
Implementation
twist
exposes three traits relevant for implementing an extension:
-
FromHeader
- Extensions are configured based on the contents of theSec-WebSocket-Extensions
request header. Implement theinit
function to configure your extension based off of this header. You should return anio::Error
if you are unable to support the given header parameters. If the parameters aren't relevant to your extension, you should ensure that yourenabled
function returns false.fn init(&mut self, request: &str) -> Result<(), io::Error> { if request.contains("permessage-deflate") { self.enabled = true; let pmds: Vec<&str> = request.split(',').take_while(|s| s.starts_with("permessage-deflate")).collect(); for pmd in pmds { // Check the config here. // return io::Error if it is invalid. } } Ok(()) }
-
IntoResponse
- Implement theresponse
function to return theSec-WebSocket-Extensions
response header. If you are disabled, returnNone
. -
PerMessage
- This is the meat of the extension. There are three methods to implement.a.
reserve_rsv
- If your extension requires the use of one of the frame's rsv bits, you can attempt to reserve it. The value you receive represents the bits that have already been reserved previously in the extension chain. Check if your bit (or bits) are free, and bitwise or your bits with the given, and return that value. Below is an example fromtwist-deflate
. The deflate extension requires the rsv1 bit, so RSV1 is 4 (0b100).if current_rsv & RSV1 == 0 { Ok(current_rsv | RSV1) } else { Err(other("rsv1 bit already reserved")) }
b.
decode
- Implement this to apply decoding to a message frame (for example decompressing the application data).c.
encode
- Implement this to apply encoding to a message frame before final encoding by twist (for example compressing the application data).
See twist-deflate for a more complete example.
Documentation
Example Usage
See the twists project for an example implementation of an echo server using twist.
Dependencies
~12–18MB
~228K SLoC