Skip to content

Conference App: synchronize presenters

Add browser-hosted HTTP synchronization to the local Presenter client from Add presenters using cHttpClient. Add the request client and synchronization procedure, then expose it through the first dashboard tile and configure the host to serve the downloaded resources.

Before you begin: Complete Add presenters. Keep its generated runtime, package, host, and SQLite files. The local database remains /dev/idbfs/MyAppData.db until the complete-application phase.

Step 1 — Add Presenter synchronization

Add the HTTP client and JSON packages with the existing package uses in CreateAndSyncDB.pkg.

Use System\FileSystem.pkg
Use System\Http.pkg
Use System\Json.pkg
Use PresenterDataDictionary.pkg

Add this request object inside oCreateAndSyncDB, after InitializeDB. It sends requests to the Conference Data service.

Object oHttpReq is a cHttpClient
    Set psEndpoint to "https://abs01.daelab.net/"
End_Object

Add SynchronizeData after oHttpReq. It uses HttpGet to request the Presenter endpoint, rejects every non-200 response before changing local data, uses HttpResponseToDataType to deserialize the JSON response into Presenter[], and replaces the local records in one transaction.

Procedure SynchronizeData
    Presenter[] aPresenters
    Integer eStatus iItem iItemTo

    Get HttpGet of oHttpReq "/ConferenceData/API/v1/Presenter" to eStatus
    If (eStatus <> 200) Begin
        Send UserError (SFormat("Could not connect to server (HTTP status %1)", eStatus))
        Procedure_Return
    End

    Get HttpResponseToDataType of oHttpReq False "" to aPresenters

    Begin_Transaction
        ZeroFile oPresenterDD

        Move (SizeOfArray(aPresenters) - 1) to iItemTo
        For iItem from 0 to iItemTo
            Clear oPresenterDD
            Send UpdateAllFields of oPresenterDD aPresenters[iItem]
            SaveRecord oPresenterDD
        Loop
    End_Transaction
End_Procedure

The early Procedure_Return means an HTTP error leaves the existing local rows and does not report a successful synchronization. ZeroFile clears the DDO-backed local table only after a successful response. UpdateAllFields copies each Presenter value into oPresenterDD's local buffer; SaveRecord persists that buffer through the Data Dictionary adapter and the built-in cDbSqliteDriver. The save loop remains inside one transaction, so the downloaded set is committed as one database operation.

Step 2 — Add the Synchronize dashboard action

Change the first generated dashboard tile without changing its generated object identity. Set its caption to Synchronize, enable server-side clicks, and call the new procedure instead of navigating to a view.

Object oWelcomeTile is a cWebHtmlBox
    Set piColumnSpan to 6
    Set psCSSClass to "Tile Light"
    Set psHtml to '<div class="WebCon_Sizer" data-ServerOnClick="openview"><div Class="Tile_Title">Synchronize</div><div class="Tile_Subtitle"></div></div>'
    Set pbServerOnClick to True

    Procedure OnClick String sId String sParam
        Send SynchronizeData of oCreateAndSyncDB
    End_Procedure
End_Object

Step 3 — Add the feature-required host configuration

The generated AppHtml/web.config contains an XML declaration and an empty <configuration> element. Add this complete <system.webServer> child inside that existing element. Leave the generated declaration and wrapper unchanged.

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="X-Content-Type-Options" value="nosniff"></add>
            <add name="X-Frame-Options" value="sameorigin"></add>
            <add name="X-XSS-Protection" value="1; mode=block"></add>
            <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains; preload"></add>
            <add name="Cache-control" value="no-cache"></add>
            <add name="Content-Security-Policy" value="default-src 'self'; font-src 'self' fonts.cdnfonts.com; img-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self'; connect-src 'self' abs01.daelab.net;"></add>
            <add name="Permissions-Policy" value="camera=(), geolocation=(), microphone=()"></add>
            <add name="Referrer-Policy" value="same-origin"></add>
            <add name="Cross-Origin-Opener-Policy" value="same-origin"></add>
            <add name="Cross-Origin-Embedder-Policy" value="require-corp"></add>
        </customHeaders>
    </httpProtocol>
    <staticContent>
        <mimeMap fileExtension=".db" mimeType="application/sqlite"></mimeMap>
    </staticContent>
</system.webServer>

The CSP must retain the exact connect-src 'self' abs01.daelab.net; value. On the separately hosted API, emit Access-Control-Allow-Origin for the exact Conference App origin (http://localhost during local hosting, or the exact deployed origin). Configure CORS on the API, not on the WebAppClient host. Do not use wildcard CSP or CORS values.

Checkpoint: Press F5, click Synchronize, then open Presenters and confirm downloaded rows. A browser CORS block means the API origin policy or CSP host is not exact.

Next

Complete the client application.