Here is a self contained sample:
compile and execute. After 30 seconds check your app's dir. You'll find a trace.log file and an actual connection where you can click on send and no error is reported. Futhermore, Tsocket reports being connected to your local computer's ip instead of the assigned ip.
Unless I'm missing something here, this self contained sample proves how tsocket is not working properly???
Code: Select all
#include "Fivewin.ch"
FUNCTION MAIN()
LOCAL oWnd
local oMsg
DEFINE WINDOW oWnd
@ 1, 2 BUTTON "Send";
SIZE 100, 50;
ACTION ( oMsg:CreateHL7Message(), ;
oMsg:Tcp_HL7_Transmit(), ;
omsg:IsAcknowledged() )
ACTIVATE WINDOW oWnd ;
ON INIT ( oMsg := tExporter():new(), omsg:SetupIPSocket() ) ;
VALID( omsg:end(), .t. )
RETURN NIL
*-------------------------------------------------------------------------------------------------------------------------------
CLASS TEXPORTER
DATA oSocket
DATA isConnected AS LOGIC INIT .f.
DATA nPort AS NUMERIC INIT 15000
DATA cIp, cId, cHL7
DATA aAcks AS ARRAY INIT {}
METHOD New() CONSTRUCTOR
METHOD SetupIpSocket()
METHOD Tcp_Hl7_Transmit()
METHOD isAcknowledged()
METHOD CreateHL7Message()
METHOD UniqueId() // HL7 segments
METHOD obx()
METHOD obr()
METHOD orc()
METHOD Pid()
METHOD Env()
METHOD Msh()
METHOD nte()
METHOD End()
END CLASS
*-------------------------------------------------------------------------------------------------------------------------------
METHOD new() CLASS TEXPORTER
::nPort := 15000
::cIP := "98.19.1.4"
RETURN SELF
*-------------------------------------------------------------------------------------------------------------------------------
METHOD SetupIpSocket() CLASS TEXPORTER
::oSocket := TSocket():New( ::nport )
::osocket:lDebug := .t.
::oSocket:cLogfile := cFilePath( GetModuleFileName( GetInstance() ) ) + "trace.log"
::oSocket:bRead = { | oSocket | aadd( ::aAcks, oSocket:GetData() ) }
::oSocket:bConnect = { || ::isConnected := .t., logfile( "trace.log", { "Connected to ip:", ::osocket:cIpAddr } ) }
::oSocket:Connect( ::cIp )
RETURN NIL
RETURN NIL
*-------------------------------------------------------------------------------------------------------------------------------
METHOD CreateHL7Message() CLASS TEXPORTER
::uniqueId()
::cHL7 := chr( 11 ) + ::msh() + chr(13) + ;
::env() + chr( 13 ) + ;
::pid() + chr( 13 ) + ;
::orc() + chr( 13 ) + ;
::obr() + chr( 13 ) + ;
::obx() + chr( 13 ) + ;
/*::nte() + chr( 13 ) +*/ chr( 28 ) + chr( 13 )
RETURN NIL
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Tcp_HL7_Transmit() CLASS TEXPORTER
if !::isConnected
MsgStop( "Connection to " + ::oSocket:cIpAddr + " at " + cValToChar( ::osocket:nPort ) + " failed." )
Return Nil
Endif
::oSocket:SendData( ::cHL7 )
RETURN NIL
*-------------------------------------------------------------------------------------------------------------------------------
METHOD isAcknowledged() CLASS TEXPORTER
local aParsed
local nPos
if !empty( ::aAcks )
aParsed := HB_ATOKENS( aTail( ::aAcks ), chr( 13 ), .T., .F.)
nPos := aScan( aParsed, { |e| left( e, 3 ) == "MSA" } )
if nPos > 0
aParsed := HB_ATOKENS( aParsed[ nPos ], "|", .T., .F. )
if alltrim( aParsed[ 3 ] ) == alltrim( ::cId ) .and. "NORMAL" $ upper( aParsed[ 4 ] )
RETURN .T.
Endif
endif
Endif
RETURN .F.
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Msh() CLASS TEXPORTER
local cStr := "MSH|"
cStr += "^~\&|" //2- encoding chars
cStr += "MP8-PathLabs|" //3- snd app
cStr += "|" //4- snd facility
cStr += "|" //5- recv app
cStr += "|" //6- recv facility
cstr += DTOS( date() ) + StrTran( time(), ":", "" )+ "|" //7
cStr += "|" //8
cstr += "ORU^R01|" //9
cstr += ::cId + "|" //10
cStr += "||||"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Env( cTrigger ) CLASS TEXPORTER
local cStr := "EVN|"
cStr += "R01|"
cStr += DTOS( date() ) + StrTran( time(), ":", "" ) + "|"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Pid() CLASS TEXPORTER
local cStr := "PID|"
cStr += "||"
cStr += "REC:00000001|"
cStr += "||||||||||||||"
cStr += "ACC:00000001^^^^^|"
cStr += "|"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD orc() CLASS TEXPORTER
local cStr := "ORC|"
cStr += "RE|"
cStr += "ORDER:0000000^|"
cStr += "|||||||"
cStr += "USERID|"
cStr += "|||||||||"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD obr() CLASS TEXPORTER
local cStr := "OBR|"
cStr += "ORDER:0000001^|"
cStr += "|||||"
cStr += DTOS( Date() ) + StrTran( Time(), ":", "" ) + "|"
cStr += "||"
cStr += "TRNSCRIPT|"
cStr += "||||||||||||||"
cStr += "F|"
cStr += "||||||"
cStr += "PTHLGST^PthlgstNameString|"
cStr += "|||||||||||"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD obx() CLASS TEXPORTER
local cStr := ""
local nSeq
//local aRsts :={ ::oTrans:oTrGrss:GetText(), ::oTrans:oTrDg:GetText() }
local aRsts := { "Text line one. Sample text. The fox jumped over the white fence", ;
"Text line two. Sample text. More foxes jumped over the white fence" }
For nSeq := 1 to 2
cStr += "OBX|"
cStr += cValToChar( nSeq )+ "|"
cStr += "ST|"
cStr += "||"
cStr += aRsts[ nSeq ] +"|"
cStr += "||||||||||||" + chr(13)
Next nSeq
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD Nte() CLASS TEXPORTER
local cStr := "NTE|"
RETURN cStr
*-------------------------------------------------------------------------------------------------------------------------------
METHOD UniqueId() CLASS TEXPORTER
local cPrvId := ::cId
While ::cId == cPrvId
::cid := Right( cValToChar( Year(date() ) ), 2 ) + ;
StrZero( Month( date() ),2 ) + ;
StrZero( Day( date() ),2 ) + ;
cValToChar( Seconds() )
End
return nil
*-------------------------------------------------------------------------------------------------------------------------------
METHOD End() CLASS TEXPORTER
iif( upper( valtype( ::osocket ) ) == "O", ::osocket:End(), )
RETURN NIL