Search code examples
c#hl7kestrelnhapimllp

How to send HL7 ACK message as a TCP response?


I'm receiving HL7 messages via TCP connection. Those messages will always be of type ADT. I'm using Kestrel to listen for thise messages and the NHAPI package to deal with them. I took David Fowler's Kestrel sample code to setup a TCP listener. So based on this sample code

internal class HL7Listener : ConnectionHandler
{
    public override async Task OnConnectedAsync(ConnectionContext connection)
    {
        try
        {
            // handle the incoming message
        }
        catch (Exception exception)
        {
            // handle exceptions
        }
        finally
        {
            ACK acknowledgement = new ACK(); // create an ACK message
            PipeParser pipeParser = new PipeParser();
            string ackMessage = pipeParser.Encode(acknowledgement); // produces => MSH|^~\&|||||||ACK|||2.3
            byte[] ackMessageBytes = Encoding.UTF8.GetBytes(ackMessage);
            
            await connection.Transport.Output.WriteAsync(ackMessageBytes); // send the ACK
        }
    }
}

I'm using the tool 7Edit to send HL7 messages to my application. The echo sample from the repository (link above) works fine. The echo sample code produces a log like this

enter image description here

But when using my code I get this error

enter image description here

So I think I don't convert the ACK message correctly. Any ideas how to fix this?


Solution

  • I doubt you are not implementing MLLP (also called LLP) protocol while sending ACK. I know, 7Edit expects MLLP to be implemented. This way, when you send an ACK to 7Edit (TCP/MLLP client), it looks for Start Block in your incoming data. It never finds it. It just discards your entire message considering garbage and keeps waiting; which causes timeout as you can see.

    May be you should look for some setting in 7Edit to disable MLLP; but this will be temporary solution. Better, you implement MLLP block.

    Description                 HEX     ASCII   Symbol
    Message starting character  0B      11      <VT>
    Message ending characters   1C,0D   28,13   <FS>,<CR>
    

    With MLLP implemented, your message (the stuff you are writing on socket) should look something like below:

    <VT>MSH|^~\\&|......|ACK|......<FS><CR>
    

    Note the <VT>, <CR> and <FS> are place holders in above message.

    You should modify your following line of code:

    byte[] ackMessageBytes = Encoding.UTF8.GetBytes(ackMessage);
    

    as below:

    ackMessage = ((char) 11).ToString() + ackMessage + ((char) 28).ToString() + ((char) 13).ToString();
    byte[] ackMessageBytes = Encoding.UTF8.GetBytes(ackMessage);
    

    For more details, you may refer to this answer.