Skip to content
A simple way to serve and connect the Fleetrace SPA client applications.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

FR Node Server

Also known as

  • fr-node-server-d (my local name)
  • fr-direct-proxy (description in package.json)

The FR node server can be a proxy to the real result server application at the backend.

But this app is not a proxy. It will store posted data in fields of the dummy variable, a global instance of the Dummy typescript class in memory.

There is no tcp connection from proxy to backend. Dummy implements iconn and oconn mocks, so that from the client perspective, the thin server application looks similar to the fat server application.


  • It does not use the request lib to pass the call on.
  • It implements the api itself through the dummy instance.
  • It uses dashed-urls.


  • It uses mock connections in dummy class.
  • It does not have real tcp input or output connections.
  • It does not define request lines.
  • It does not have the WantRequest variable.

Web Sockets

It can use web-sockets.

wsServer.on('connection', ws => {
  ws.on('message', message => {  
    let messageObject = JSON.parse(message.toString());
    if ( == -2)             
    if ( == -1)             
  • Do not get confused, the real proxy server (indirect or outer message loop) has separate instances of the real connection class.
  • But here we only have one dummy instance.
  • Variables for iconn, oconn and dummy reference the same instance of the Dummy class.

Inside of Dummy we have:

    //client is of type WebSocket
    registerApp(client: any): void {

    writeToSocket(t: string) {
        if (this.isDirectProxy)

    broadcastToConnectedApps(msg: string) {
        this.connectedApps.forEach((ws: WebSocket) => {
            if (ws.readyState === 1) {
                let requestParams = {
                    race: 1,
                    it: 0,
                    netto: msg
                if (this.verbose)
                    this.log('broadcasting netto...');
            } else {

So, if this app is a direct proxy (it is) then input messages (timing messages) will be broadcast to all connected apps (Angular clients).

Using the indirect way, it would send timing messages via tcp to the input socket of the backend. The backend would itself broadcast messages via the tcp output socket. You would receive these and then broadcast the netto content to all connected Angular apps. In other words, the timing message would travel via the outer loop. You would also receive what traditional timing clients may be sending to the desktop result server, and what is being manually entered into the UI of the desktop application.

This application can connect spa clients directly, without a backend application.

Note that the hardcoded race and it params in the json above will not be used here.

Angular Clients

  • FR03A1 or similar.
  • FR03A1 can be configured via url query param, see links in client/index.html.
  • The Angular client will be input or output, or both.

You should check that the Angular client:

  • Evaluates the query param. (Calls initParams() in ngOnInit().)
  • Uses the dashed style for api calls.
  • Is connected.
  • Does open the web-socket channel (watch button).
  • Does Accept and not Drop the web-socket traffic.
  • Has already downloaded current event data from the server.

The good question is of course, whether this should be in configuration, hardcoded or manual.

By default, the server starts out in Connected state. But a client can control the connection status and set it to false.

When a client queries the server capabilities and detects web-socket support, it could automatically initialize the channel, instead of doing that later manually, via the watch button.

When the client downloads current event data it will retrieve the params as part of it. When the client is a thin client, you may need to init the params via special api call.


Since this is a thin server, someone will need to upload the initial event data into the dummy instance. This is probably a task for admin, but we do not do authentication/authorization, not yet.

We do not have a database either.

You can’t perform that action at this time.