1
votes

I searched about this issue before asking but I couldn't find something similar. I developed a client / server solution to send / receive HL7 message. I am using socket to connect the client to the server and from this connection I am able to send just 1 HL7 message using OutputSteam object. How could I send multiple HL7 in the same socket connection? I tried different approaches but they didn't work properly.

Here is the piece of my code from the client side:

//Create socket that is connected to server on specified port
        System.out.println("Connecting to Server....");
        Socket socket  = new Socket(ipServer, serverPort);
        System.out.println("Connected to Server");

        StringBuffer HL7Message1 = new StringBuffer();

        //Message 1
        HL7Message1
        .append(START_BLOCK)
        .append("MSH|^~\\&|NES|NINTENDO|TESTSYSTEM|TESTFACILITY|20010101000000||ADT^A04|Q000000000000000001|P|2.3")
        .append(CARRIAGE_RETURN)
        .append("EVN|A04|20010101000000|||^KOOPA^BOWSER^^^^^^^CURRENT")
        .append(CARRIAGE_RETURN)
        .append("PID|1||123456789|0123456789^AA^^JP|BROS^MARIO^HELLO^WORLD^ONE^||19850101000000|M|||123 FAKE STREET^MARIO \\T\\ LUIGI BROS PLACE^TOADSTOOL KINGDOM^NES^A1B2C3^JP^HOME^^1234|1234|(555)555-0123^HOME^JP:1234567|||S|MSH|12345678|||||||0|||||N")
        .append(CARRIAGE_RETURN)
        .append("NK1|1|PEACH^PRINCESS^^^^|SO|ANOTHER CASTLE^^TOADSTOOL KINGDOM^NES^^JP|(123)555-1234|(123)555-2345|NOK|||||||||||||")
        .append(CARRIAGE_RETURN)
        .append("NK1|2|TOADSTOOL^PRINCESS^^^^|SO|YET ANOTHER CASTLE^^TOADSTOOL KINGDOM^NES^^JP|(123)555-3456|(123)555-4567|EMC|||||||||||||")
        .append(CARRIAGE_RETURN)
        .append("PV1|1|O|ABCD^EFGH^|||^^|123456^DINO^YOSHI^^^^^^MSRM^CURRENT^^^NEIGHBOURHOOD DR NBR^|^DOG^DUCKHUNT^^^^^^^CURRENT||CRD|||||||123456^DINO^YOSHI^^^^^^MSRM^CURRENT^^^NEIGHBOURHOOD DR NBR^|AO|0123456789|1|||||||||||||||||||MSH||A|||20010101000000"
                )
        .append(CARRIAGE_RETURN)
        .append("IN1|1|PAR^PARENT||||LUIGI")
        .append(CARRIAGE_RETURN)
        .append("IN1|2|FRI^FRIEND||||PRINCESS")
        .append(CARRIAGE_RETURN)
        .append(END_BLOCK)
        .append(CARRIAGE_RETURN);

        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();

        //Send the MLLP-wrapped HL7 message to the server
        out.write(HL7Message1.toString().getBytes());

        byte[] byteBuffer =  new byte[200];
        in.read(byteBuffer);
        System.out.println("Received from Server: " + new String(byteBuffer));

From the server side

public String getMessage(InputStream anInputStream) throws IOException  {

            boolean end_of_message = false;
            StringBuffer parsedMessage = new StringBuffer();

            int characterReceived = 0;

            try {
                characterReceived = anInputStream.read();
            } catch (SocketException e) {
                System.out
                .println("Unable to read from socket stream. "
                        + "Connection may have been closed: " + e.getMessage());
                return null;
            }

            if (characterReceived == END_OF_TRANSMISSION) {
                return null;
            }

            if (characterReceived != START_OF_BLOCK) {
                throw new RuntimeException(
                        "Start of block character has not been received");
            }

            while (!end_of_message) {
                characterReceived = anInputStream.read();

                if (characterReceived == END_OF_TRANSMISSION) {
                    throw new RuntimeException(
                            "Message terminated without end of message character");
                }

                if (characterReceived == END_OF_BLOCK) {
                    characterReceived = anInputStream.read();

                    if (characterReceived != CARRIAGE_RETURN) {
                        throw new RuntimeException(
                                "End of message character must be followed by a carriage return character");
                    }
                    end_of_message = true;
                } else {
                    parsedMessage.append((char) characterReceived);
                }
            }

How could I send more HL7 messages in the same socket connection?

1
Your example sends just one message. Can you show how you call your code with more than a single message and what control or error messages you get?sqlab
START_BLOCK, CARRIAGE_RETURN, END_BLOCK. Could you please tell me the values of these variables? Thanks.andres83

1 Answers

2
votes

What you really want to do is separate your sockets from your data. I suggest using a TCP Client Server like this one to manage your sockets. Then you simply, write a message to your Client. I have a service that does this for me. Basically, I package up any string of HL7, which it looks like you already know how to do, and then call the Send method of the TCP Server.

Mine looks like this, but I think the one in the link will look similar:

public int Send(string data)
{
    TcpClient sender = new TcpClient();
    IPEndPoint localEP = new IPEndPoint(IPAddress.Any, Port);
    try
        {
            TcpServerConnection cn;

            if (connections.Count == 0)
            {
                //if there are no connections then we end up here.
                ConnectSocket(sender, localEP);
            }

            cn = connections[0];

            if (cn.Socket.Connected && cn.verifyConnected())
            {
                cn.sendData(data);
                return connections.Count;
            }
            cn.Socket.Close();

            ConnectSocket(sender, localEP);
            if (cn.Socket.Connected && cn.verifyConnected())
            {
                cn.sendData(data);
                return connections.Count;
            }
            cn.Socket.Close();
            return -1;
        }
        catch (Exception e)
        {                   
        }
    }

The important part, as you can see is that the TCP Server figures out whether or not there is an available socket and opens one if necessary. Then it sends the data down the line. I think you'll have a lot of difficulty if you don't separate the transmission/coding to TCP from the HL7 messaging. If you want to wait for an ACK for MLLP release 2, I personally pull the outbound message ID and the returning message ID in the ACK and compare them:

if (lastOutMessageID == lastOutAckID || lastOutMessageID == "")
{
    lastOutMessageID = SendNextHL7Message;
}

And then I listen for the ACK, and raise an event on the data coming in:

void _contractManager_OnAckReceived(string msgID, string ackStatus)
{
    lastOutAckID = msgID;
    lastOutStatus = ackStatus;
    lastAckTime = DateTime.Now;
    outRetries = 0;
    DoNextHL7();
}

But the short version is manage the transmissions and sockets in their own classes and just send and wait data from them.