×
Menu
Index

TCP communicatie

 

Introductie

Om met de server te communiceren via TCP/IP dient een XML document  of commando gestuurd te worden naar het IP adres van de SoftRules® Server met een specifieke poort. Deze Port is opgegeven in de Configuration Manager. Aan die Port is een Configuration van SoftRules® gekoppeld of de Configuration wordt in het Request meegegeven (bij een TCP - DISPATCH Port).
 
Let op!
Om te koppelen met de SoftRules server wordt normaliter onze REST-API gebruikt. Onderstaande TCP communicatie is ook dan te zien via de Configuration Manager.
 
De volgende functies zijn beschikbaar via de server via deze FunctieID's:
 
100. Ophalen publiceren userinterface data items
201. Server Statistics
203. Server Status
204. Ophalen Sessie XML
 
 
Bij het beschrijven van deze functionaliteit worden programmeervoorbeelden in C# gegeven. Vanzelfsprekend is de werking van SoftRules® niet beperkt tot applicaties die ontwikkeld zijn voor het .Net framework.
 

Voorbeeld

Hieronder volgt een voorbeeld in C# van het versturen van een XML document naar SoftRules® via TCP/IP.
 
private string sendXml(string xml)
{
    const int READBUFSIZE = 8196;
    const int SENDBUFSIZE = 8196;
           
    TcpClient m_Client = null;
    Stopwatch m_TimeBetweenPackages = new Stopwatch();
 
    string m_IP = '127.0.0.1';
    string m_TCPPort = '56000';
    string m_ResultString = "";
 
    try
    {
        m_Client = new TcpClient(m_IP, m_TCPPort);
        m_Client.ReceiveBufferSize = READBUFSIZE;
        m_Client.SendBufferSize = SENDBUFSIZE;
 
        if (m_Client.Connected)
        {
            //write
 
            string signature = "SoftRules";
            byte[] signatureBytes = Encoding.UTF8.GetBytes(signature);
            byte[] requestBytes = Encoding.UTF8.GetBytes(xml);
            byte[] LengthBytes = BitConverter.GetBytes(requestBytes.Length);
 
            byte[] totalRequestBytes = new byte[signatureBytes.Length + LengthBytes.Length + requestBytes.Length];
 
            System.Buffer.BlockCopy(signatureBytes, 0, totalRequestBytes, 0, signatureBytes.Length);
            System.Buffer.BlockCopy(LengthBytes, 0, totalRequestBytes, signatureBytes.Length, LengthBytes.Length);
            System.Buffer.BlockCopy(requestBytes, 0, totalRequestBytes, signatureBytes.Length + LengthBytes.Length, requestBytes.Length);
 
            MemoryStream mStream = new MemoryStream(totalRequestBytes);
 
            byte[] sendBuffer = new byte[SENDBUFSIZE];
            int read = 0;
            while ((read = mStream.Read(sendBuffer, 0, sendBuffer.Length)) > 0)
            {
                m_Client.GetStream().Write(sendBuffer, 0, read);
            }
 
            //read
 
            byte[] rcvBuffer = new byte[READBUFSIZE];
            byte[] totalBuffer = new byte[0];
            int recvMsgSize = m_Client.GetStream().Read(rcvBuffer, 0, m_Client.ReceiveBufferSize);
 
            byte[] lengthBytes = new Byte[4];
 
            System.Buffer.BlockCopy(rcvBuffer, 0, signatureBytes, 0, 9);
            System.Buffer.BlockCopy(rcvBuffer, 9, lengthBytes, 0, 4);
            if (Encoding.UTF8.GetString(signatureBytes) == "SoftRules")
            {
                int lengthRequest = BitConverter.ToInt32(lengthBytes, 0);
                totalBuffer = new Byte[lengthRequest];
                int totalBytesReceived = recvMsgSize - 13;
                System.Buffer.BlockCopy(rcvBuffer, 13, totalBuffer, 0, recvMsgSize - 13);
 
                m_TimeBetweenPackages.Start(); //start stopwatch for max 5 sec.
                bool bStopReceiving = false;
 
                while ((totalBytesReceived < lengthRequest) && (!bStopReceiving))
                {
                    if (m_Client.Available > 0)
                    {
                        recvMsgSize = m_Client.GetStream().Read(rcvBuffer, 0, m_Client.ReceiveBufferSize);
 
                        System.Buffer.BlockCopy(rcvBuffer, 0, totalBuffer, totalBytesReceived, recvMsgSize);
                        totalBytesReceived += recvMsgSize;
                    }
 
                    if (m_TimeBetweenPackages.ElapsedMilliseconds > 5000)
                    {
                        bStopReceiving = true;
                    }
                }
 
                m_ResultString = Encoding.UTF8.GetString(totalBuffer);
            }                                       
        }
    }
    catch (SocketException se)
    {
        throw se;
    }
    catch (Exception e)
    {
        throw e;
    }
    finally
    {
        if (m_Client != null)
        {
            if (m_Client.Client != null)
            {
                m_Client.Client.Close();
            }
            m_Client.Close();
        }
    }
 
    return m_ResultString;
}
 

Response

De server geeft een Xml terug dat voldoet aan de volgende XSD:
 
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="softrulestcpframe">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="softrules" minOccurs="1" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="softrules">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="header" minOccurs="1" maxOccurs="1"/>
                <xs:element ref="result" minOccurs="0" maxOccurs="1"/>
                <xs:element ref="xmldocument" minOccurs="0" maxOccurs="1"/>
                <xs:element ref="status" minOccurs="0" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="result">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="errorcode"/>
                <xs:element ref="errordescription"/>
                <xs:element ref="errordetail"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="errorcode" type="xs:integer"/>
    <xs:element name="errordescription">
        <xs:complexType/>
    </xs:element>
    <xs:element name="errordetail">
        <xs:complexType/>
    </xs:element>
    <xs:element name="header">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="functionid" minOccurs="1" maxOccurs="1"/>
                <xs:element ref="configid" minOccurs="0" maxOccurs="1"/>
                <xs:element ref="inadapter" minOccurs="0" maxOccurs="1"/>
                <xs:element ref="outadapter" minOccurs="0" maxOccurs="1"/>
                <xs:element ref="parameters" minOccurs="0" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="functionid" type="xs:integer"/>
    <xs:element name="configid" type="xs:integer"/>    <!-- Vereist bij een TCP Dispatch poort -->
    <xs:element name="inadapter" type="xs:string"/>    <!-- Vereist bij een TCP Dispatch poort -->
    <xs:element name="outadapter" type="xs:string"/>   <!-- Vereist bij een TCP Dispatch poort -->
    <xs:element name="parameters">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="parameter">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="name"/>
                <xs:element ref="value"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="value" type="xs:string"/>
    <xs:element name="xmldocument" type="xs:string"/> <!-- Dit is een CDATA section -->
    <xs:element name="status" type="xs:string"/>
</xs:schema>
 

Messages

Message kunnen zelf worden aangemaakt en doorgegeven worden aan de server (Raise Exception). Het systeem zal zelf ook Messages genereren en deze doorgegeven. Eén van de belangrijkste zijn de validatiemeldingen. Standaard zal SoftRules® messagecode 1 toekennen, indien er geen messagecode meegegeven is uit de configuratie.
 
Messagecode 2 geeft aan dat het een validatie melding betreft op de In Xml.
Messagecode 3 geeft aan dat het een validatie melding betreft op de Out Xml.
 
<softrulestcpframe>
     <softrules>
          <result>
               <configuration>O109 - Compleet bij Elkaar Pakket - Berekenen (1000)</configuration>
               <function>ProcessXml (14)</function>
               <messages>
                    <message>
                         <messagecode>2</messagecode>
                         <messagedescription>(1,422)  Het element PP_INGDAT is ongeldig. De waarde 23-12-2022 is ongeldig volgens het bijbehorende gegevenstype Decimal - De Pattern-beperking is mislukt.</messagedescription>
                         <Severity>Error</Severity>
                    </message>
                    <message>
                         <messagecode>2</messagecode>
                         <messagedescription>(1,216)  Het element PK_INGDAT is ongeldig. De waarde 23-12-2022 is ongeldig volgens het bijbehorende gegevenstype Decimal - De Pattern-beperking is mislukt.</messagedescription>
                         <Severity>Error</Severity>
                    </message>
                    <message>
                         <messagecode>3</messagecode>
                         <messagedescription>(1,7782)  Het element PP_TKRT is ongeldig. De waarde € 0,00 is ongeldig volgens het bijbehorende gegevenstype Decimal - De tekenreeks € 0,00 is geen geldige Decimal waarde.</messagedescription>
                         <Severity>Error</Severity>
                    </message>
               </messages>
          </result>
          <xmldocument/>
     </softrules>
</softrulestcpframe>
 
Bovenstaand voorbeeld heeft dus twee meldingen betreffende de input Xml en één betreffende de Out Xml.