damos 0 Posted Sunday at 05:35 PM Hi i am Testing ICS as HL7 Server on AvailDataAvailable i have wrote procedure TcpSrvForm.ClientDataAvailable( Sender : TObject; Error : Word); Var Client: TWSocketClient; Buffer: AnsiString; ReceivedData: string; AckMsg: string; Len: Integer; begin if Error <> 0 then begin Display('Socket Error: ', Error); Exit; end; Client := Sender as TWSocketClient; Len := Client.ReadCount; if Len <= 0 then Exit; SetLength(Buffer, Len); Client.Receive(@Buffer[1], Len); // Convert buffer to string and trim unnecessary spaces ReceivedData := Trim(String(Buffer)); // Ensure message ends with <CR> if (not ReceivedData.IsEmpty) and (Strutils.RightStr(ReceivedData,1)=#13) then begin Display('Received HL7 Message: '+ReceivedData); // Create HL7 Acknowledgment (ACK) AckMsg := 'MSH|^~\&|RECEIVER|SENDER|ACK||' + FormatDateTime('YYYYMMDDHHNNSS', Now) + '||ACK|' + IntToStr(Random(1000000)) + '|P|2.3' + #13 + 'MSA|AA|' + 'MSG12345' + #13; // Send ACK back to client Client.SendStr(#11+AckMsg+#28+#13); Display('Sent ACK: '+AckMsg); end else begin Display('Incomplete HL7 message received (waiting for <CR>)'); end; end; Each HL7 block has the following format #11+HL7Block+#28+#13 or VT +HL7Message +FS+CR Each HL7Block consist Messages ending with CR Example VT MSH|^~\&|OR-CO|MIRTH|LISSYSTEM||20191126132820||ADT^A04^ADT_A04|2653973|P|2.4+CR EVN|A01||||OR-CO|20191126132400+CR PID|||22522527||CCCCCCCCCC^VVVVVVVV^KKKKKKKK||19581003000000|M|||ΠΕΤΡΟΥ ΡΑΛΛΗ 3^^ΑΘΗΝΑ^^15121||2106127519||||||27014802733+CR NK1|1|^ΜΑΡΙΑ|MTH+CR PV1||E|392^102106001^0^392||||1068^SSSSSS^DDDDDD||||||||||||1-2611222|||||||||||||||||||||||||20191126132400+CR DG1|||D64.9^LLLLLLLLLLLL+CR IN1|||551OOOOOOOOOOOOOOO|||||||||||||||||||||||||||||||||||||||||||||11456652+CR VT+CR This is Working only When Client is disconnected never reach data from client Each message Block from Client has to be Acknowledgement by HL7 ACK message I have tested with LineEnd=#13 and LineEnd=#28#13 Share this post Link to post
Angus Robertson 592 Posted Sunday at 06:54 PM Never heard of HL7, but it looks like a simple ASCII protocol, one line at a time. I'd suggest you use the TIcsIpStrmLog component in TCP Server mode which has an onRecvEvent that returns a simple line at a time, you can define the line end in various ways. The main sample is OverbyteIcsIpStmLogTst,dpr that sends and receives lines of data, including to itself. ICS V9,4 adds a new component OverbyteIcsAppMonSrv.pas that handles a text protocol very similar to your example with | as field separators, communicating between different ICS applications, with a new sample IcsAppMon.dpr use the server component to collect information from multiple clients and return information those clients. Angus Share this post Link to post
KenR 29 Posted Monday at 06:57 AM I use a TWSocket to listen for HL7 transmissions. It works perfectly. Ken Share this post Link to post
FPiette 387 Posted Monday at 07:35 AM I have used TWSocket for hospital application (HL7 V2.3) and never had any issue. You should turn line mode on and use CR as line end. The as it is ASCII, use ReceiveStr to get the lines one at a time into a string. Share this post Link to post
damos 0 Posted Monday at 08:49 AM I follow the example and Use procedure TForm6.WSocketServer1DataAvailable(Sender: TObject; ErrCode: Word); Var ReceivedData: string; AckMsg: string; begin if ErrCode <> 0 then Exit; with Sender as TWSocket do begin ReceivedData := ReceiveStr; ReceivedData := LeftStr(ReceivedData,Length(ReceivedData)-Length(LineEnd)); // remove EndOfLine DisplayMemo.Lines.Add('Line: '+ IntToStr(Length(ReceivedData)) +' '+ReceivedData); end; AckMsg := 'MSH|^~\&|RECEIVER|SENDER|ACK||' + FormatDateTime('YYYYMMDDHHNNSS', Now) + '||ACK|' + IntToStr(Random(1000000)) + '|P|2.3' + #13 + 'MSA|AA|' + 'MSG12345' + #13; end; Never get the message from Client can you give a simple example that line ends with FS+CR (#28#13) With Indy works Fine Share this post Link to post
Angus Robertson 592 Posted Monday at 08:57 AM Of course TWSocket can be used for HL7, but using TIcsIpStrmLog requires a lot less code. OverbyteIcsAppMonSrv.pas even parses the | delimited fields. Angus Share this post Link to post
FPiette 387 Posted Monday at 10:12 AM 1 hour ago, damos said: Never get the message from Client can you give a simple example that line ends with FS+CR (#28#13) In HL7, end of segment is single CR (#13). Set TWSocket LineEnd to single #13. Share this post Link to post
damos 0 Posted Monday at 06:41 PM I have to disagree with you General format on common versions of HL7 2.3....2.7 are standard VT+HL7Block+FS+CR , each HL7Block consist of HL7 records according the version each line end with CR \x0B MSH|^~\&|... PID|... PV1|... \x1C\x0D i have to read all the block that is ending with FS+CR (MIRTH OPERATION) and answer with ACk or NAK the HL7 message that is the flow Control I have also try with LineEnd=#13 i have attach simple project and simple Flow from HL7 client Socket.rar Share this post Link to post
Angus Robertson 592 Posted Monday at 07:38 PM You would be better to avoid using LineMode if the lines are 'unusual', always read all received data, buffer it, and check for end of line/row/packet yourself, which can be multiple methods. That is what the TIcsIpStrmLog component does, but you may need to copy the code to add more flexibility. Angus 1 Share this post Link to post