#tokio-codec #hl7 #message #protocols #layer #lower #mllp

hl7-mllp-codec

A Tokio codec for HL7 Minimal Lower Layer Message Transport protocol (MLLP)

9 releases

0.4.0 Jul 22, 2022
0.3.0 Aug 5, 2021
0.2.0 Aug 2, 2021
0.0.6 Nov 29, 2019

#1729 in Asynchronous

Download history 28/week @ 2024-07-25 6/week @ 2024-08-01 6/week @ 2024-09-19 7/week @ 2024-09-26 9/week @ 2024-10-03 36/week @ 2024-10-10 50/week @ 2024-10-17 16/week @ 2024-11-07

67 downloads per month

MIT license

22KB
294 lines

A HL7 MLLP Codec for Tokio

This is a tokio play project, implementing support for HL7 Minimal Lower Layer Message Transport protocol (MLLP) within a tokio codec.

Latest version Documentation

Run an example listener at 127.0.0.1:8080 by cargo r --release --example listener, or run an example publisher using cargo r --release --example publisher

Docs are available as usual from cargo doc --lib --open


lib.rs:

A tokio codec implementation for the HL7 MLLP network protocol.

HL7's MLLP is a simple, single-byte-text based protocol for framing HL7 messages over a TCP (or similar) transport. The full specification is available at the HL7 site (Note that they place the standards behind a free membership/login form).

This crate provides a Codec implementation that encodes/decodes MLLP frames from a Tokio stream, allowing simple programmatic access to the messages (both primary and ack/nack).

Tokio (and the rust async ecosystem) is currently in a state of flux, however there are two simple (not production ready!) examples in the source, of both a publisher and a listener. NB. These examples just write output to the console, and this can seriously limit throughput. If you want to run some simple perf tests with the samples, ensure you minimise the amount of data written out.

Example

This is a highly simplified example, lifted from the Examples included in source control.

Publisher

use bytes::*;
use tokio_util::codec::Framed;
use tokio::net::TcpStream;
use futures::{SinkExt, StreamExt};

use hl7_mllp_codec::MllpCodec;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Open a TCP stream to the socket address.
let stream = TcpStream::connect("127.0.0.1:8080").await?;

// Construct a MLLP transport using our codec
let mut transport = Framed::new(stream, MllpCodec::new());

// Send some bytes wrapped in MLLP (Note: not a valid HL7 message)
transport.send(BytesMut::from("Hello World")).await?; //because this is through the codec it gets wrapped in MLLP header/footer for us

if let Some(response) = transport.next().await {
match response{
Ok(msg) => println!("  Received response: {:?}", msg),
Err(e) => println!("  ERROR: {:?}", e)
}
}

Ok(())
}

Crate Features

By default this crate is designed to strictly comply with the MLLP Specification, however there are scenarios where systems in production do not comply with the standard. In those cases there is a crate feature noncompliance available which enables some non-compliant behaviours:

  • Removes the assumption that there's only message at a time on the wire in the event that a publisher fails to wait for an ACK/NAK, and publishes multiple messages asyncronously

Dependencies

~2.5–9MB
~57K SLoC