FB_LocalClient

FB_LocalClient 1:

Bei gesetztem bEnable-Eingang wird immer wieder versucht, nach Ablauf der CLIENT_RECONNECT_TIME, die Verbindung zum Remote-Server herzustellen. Der Remote-Server wird über die sRemoteHost-IP Adresse und die nRemotePort-IP Portadresse identifiziert. Der Datenaustausch zum Server wurde in einem separaten Funktionsbaustein FB_ClientDataExcha gekapselt. Der Datenaustausch erfolgt zyklisch, immer nach Ablauf von PLCPRJ_SEND_CYCLE_TIME. Dabei wird die sToServer-Stringvariable zum Server gesendet, der vom Server zurückgesandte String steht am Ausgang sFormServer zur Verfügung. Eine andere Implementierung, in der der Remote-Server bei Bedarf angesprochen wird, ist aber ebenfalls möglich. Bei einem Fehler wird die vorhandene Verbindung geschlossen und eine neue aufgebaut.

Schnittstelle

FUNCTION_BLOCK FB_LocalClient
VAR_INPUT
    sRemoteHost     : STRING(15) := '127.0.0.1';(* IP adress of remote server *)
    nRemotePort     : UDINT := 0;
    sToServer       : T_MaxString:= 'TEST';
    bEnable         : BOOL;
END_VAR
VAR_OUTPUT
    bConnected      : BOOL;
    hSocket         : T_HSOCKET;
    bBusy           : BOOL;
    bError          : BOOL;
    nErrId          : UDINT;
    sFromServer     : T_MaxString;
END_VAR
VAR
    fbConnect       : FB_SocketConnect := ( sSrvNetId := '' );
    fbClose         : FB_SocketClose := ( sSrvNetId := '', tTimeout := DEFAULT_ADS_TIMEOUT );
    fbClientDataExcha : FB_ClientDataExcha;

    fbConnectTON     : TON := ( PT := PLCPRJ_RECONNECT_TIME );
    fbDataExchaTON   : TON := ( PT := PLCPRJ_SEND_CYCLE_TIME );
    eStep            : E_ClientSteps;
END_VAR

Realisierung

CASE eStep OF
    CLIENT_STATE_IDLE:
        IF bEnable XOR bConnected THEN
            bBusy := TRUE;
            bError := FALSE;
            nErrid := 0;
            sFromServer := '';
            IF bEnable THEN
                fbConnectTON( IN := FALSE );
                eStep := CLIENT_STATE_CONNECT_START;
            ELSE
                eStep := CLIENT_STATE_CLOSE_START;
            END_IF
        ELSIF bConnected THEN
            fbDataExchaTON( IN := FALSE );
            eStep := CLIENT_STATE_DATAEXCHA_START;
        ELSE
            bBusy := FALSE;
        END_IF

    CLIENT_STATE_CONNECT_START:
        fbConnectTON( IN := TRUE, PT := PLCPRJ_RECONNECT_TIME );
        IF fbConnectTON.Q THEN
            fbConnectTON( IN := FALSE );
            fbConnect( bExecute := FALSE );
                fbConnect(sRemoteHost := sRemoteHost,
                nRemotePort := nRemotePort,
                bExecute        := TRUE );
            eStep := CLIENT_STATE_CONNECT_WAIT;
        END_IF

    CLIENT_STATE_CONNECT_WAIT:
        fbConnect( bExecute := FALSE );
        IF NOT fbConnect.bBusy THEN
            IF NOT fbConnect.bError THEN
                bConnected := TRUE;
                hSocket         := fbConnect.hSocket;
                eStep     := CLIENT_STATE_IDLE;
                LogMessage( 'LOCAL client CONNECTED!', hSocket );
            ELSE
                LogError( 'FB_SocketConnect', fbConnect.nErrId );
                nErrId := fbConnect.nErrId;
                eStep := CLIENT_STATE_ERROR;
            END_IF
           END_IF

    CLIENT_STATE_DATAEXCHA_START:
        fbDataExchaTON( IN := TRUE, PT := PLCPRJ_SEND_CYCLE_TIME );
        IF fbDataExchaTON.Q THEN
            fbDataExchaTON( IN := FALSE );
            fbClientDataExcha( bExecute := FALSE );
            fbClientDataExcha( hSocket := hSocket,
                    sToServer := sToServer,
                    bExecute    := TRUE );
            eStep := CLIENT_STATE_DATAEXCHA_WAIT;
        END_IF

    CLIENT_STATE_DATAEXCHA_WAIT:
        fbClientDataExcha( bExecute := FALSE );
        IF NOT fbClientDataExcha.bBusy THEN
            IF NOT fbClientDataExcha.bError THEN
                sFromServer := fbClientDataExcha.sFromServer;
                eStep     := CLIENT_STATE_IDLE;
            ELSE
                (* possible errors are logged inside of fbClientDataExcha function block *)
                nErrId := fbClientDataExcha.nErrId;
                     eStep :=CLIENT_STATE_ERROR;
            END_IF
        END_IF

    CLIENT_STATE_CLOSE_START:
        fbClose( bExecute := FALSE );
        fbClose(    hSocket:= hSocket,
            bExecute:= TRUE );
        eStep := CLIENT_STATE_CLOSE_WAIT;

    CLIENT_STATE_CLOSE_WAIT:
        fbClose( bExecute := FALSE );
        IF NOT fbClose.bBusy THEN
            LogMessage( 'LOCAL client CLOSED!', hSocket );
            bConnected := FALSE;
            MEMSET( ADR(hSocket), 0, SIZEOF(hSocket));
            IF fbClose.bError THEN
                LogError( 'FB_SocketClose (local client)', fbClose.nErrId );
                nErrId := fbClose.nErrId;
                eStep := CLIENT_STATE_ERROR;
            ELSE
                bBusy := FALSE;
                bError := FALSE;
                     nErrId := 0;
                eStep := CLIENT_STATE_IDLE;
            END_IF
        END_IF

    CLIENT_STATE_ERROR: (* Error step *)
        bError := TRUE;
        IF bConnected THEN
            eStep := CLIENT_STATE_CLOSE_START;
        ELSE
            bBusy := FALSE;
            eStep := CLIENT_STATE_IDLE;
        END_IF
END_CASE