Echo Server and Echo Client

This demonstration is based on the featured demo of the mileage server and client (in the Business folder) and also on this Node.js JavaScript example. You might like to adapt it to store a game score if it is higher than the existing highest score.

We set up Node.js on the Raspberry Pi by following these instructions. We copied EchoServer.js to /var/www on the Pi, used LXTerminal to change directory with the instruction cd /var/www and started the server with node EchoServer.js.

Two of the statements in the client are noteworthy:
  • Use of req.Get('trial.txt?unused=' + intTostr(randomInt(5000))); instead of req.Get('trial.txt'); is a trick to prevent caching and thereby ensure that you download the latest file contents.
  • In the statement Req.Open('POST', edtDestination.Text);, 'POST' is needed in some browsers (e.g. Chrome) to send the message, whereas 'GET' worked in the Smart internal browser.

See below our testing, the Smart Pascal code of the server and client and the XML code of the client's form.

Testing

The tests use an Apache web server installed on a Raspberry Pi for the download of EchoClient.html and trial.txt. The server is in the /var/www folder on the Pi and trial.txt is stored by the server in the same directory. The text file is downloaded using the method shown on the previous page.

With the Smart internal browser, Internet Explorer (9 and 11) and Edge the data typed into EchoClient was echoed successfully both directly and via the stored file. On our system the browsers Chrome, Firefox and Opera uploaded the data and downloaded it from file but did not accept the echo directly. Chromium 22 and Safari 5 failed to upload the data.

Screenshot of Echo Testing in the Microsoft Edge Browser

Screenshot of Echo Testing in the Microsoft Edge Browser

Smart Pascal code of Echo Server

We changed the code of a new Node.js project named EchoServer to the following. You can compare it with the equivalent JavaScript version.

unit Unit1;

interface

type
  TServer = class
  public
    procedure Run;
  end;

implementation

uses
  NodeJS.Core, NodeJS.http, NodeJS.fs;

{ TServer}

procedure TServer.Run;
begin
  http.createServer(
    procedure(request: JServerRequest; response: JServerResponse)
    begin
      request.on('data', lambda (msg: Variant)
        response.write(msg, 'utf8');
        fs.writeFile('trial.txt', msg, nil);
        Console.log('Echoed and saved: ' + msg);
      end);
      request.on('end', lambda
        response.end;
        Console.log('End of response');
      end);
    end)
    .listen(8080, '');

  Console.log('Server running at http://192.168.0.6:8080');
end;

end.
    

Smart Pascal Code of Client

unit Form1;

interface

uses 
  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Label,
  SmartCL.Controls.Button, SmartCL.Controls.EditBox, SmartCL.Inet,
  SmartCL.Controls.Panel, SmartCL.Time;
type
  TForm1 = class(TW3Form)
    Timer : TW3Timer;
    procedure W3Button1Click(Sender2: TObject);
    procedure GetFile(Sndr: TObject);
  private
    {$I 'Form1:intf'}
    Req: TW3HttpRequest;
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
  end;

implementation

{ TForm1 }

procedure TForm1.W3Button1Click(Sender2: TObject);
begin
  Req := TW3HttpRequest.Create;
  Req.OnDataReady := lambda (Sender)
    lblReceived.Caption := 'Received: ' + Sender.responseText;
  end;
  Req.Open('POST', edtDestination.Text);
  Req.Send(edtMessage.Text);
  Timer.Enabled := true;
end;

procedure TForm1.GetFile(Sndr: TObject);
begin
  Req := TW3HttpRequest.Create;
  Req.OnDataReady := lambda (Sender)
    lblFileContents.Caption := 'File contents received : ' + Sender.responseText;
  end;
  Req.Get('trial.txt?unused=' + intTostr(randomInt(5000)));
  Timer.Enabled := false;
end;

procedure TForm1.InitializeForm;
begin
  inherited;
  lblTitle.Font.Size := 16;
  lblTitle.Font.Weight := 'bold';
  lblDestination.Font.Weight := 'bold';
  lblMessage.Font.Weight := 'bold';
  lblFileContents.Caption := '';
  randomize;
  Timer := TW3Timer.Create;
  Timer.Delay := 100;
  Timer.OnTime := GetFile;
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
end;

initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.    

XML Code of Form

<SMART>
  <Form version="2" subversion="1">
    <Created>2015-09-25T09:20:58.070</Created>
    <Modified>2015-09-27T19:40:58.347</Modified>
    <object type="TW3Form">
      <Caption>W3Form</Caption>
      <Name>Form1</Name>
      <object type="TW3Panel">
        <Width>272</Width>
        <Height>288</Height>
        <Name>W3Panel1</Name>
        <object type="TW3Label">
          <Caption>Message</Caption>
          <Width>72</Width>
          <Top>44</Top>
          <Left>8</Left>
          <Height>32</Height>
          <Name>lblMessage</Name>
        </object>
        <object type="TW3Label">
          <Caption>Destination</Caption>
          <Width>128</Width>
          <Top>44</Top>
          <Left>112</Left>
          <Height>32</Height>
          <Name>lblDestination</Name>
        </object>
        <object type="TW3EditBox">
          <Value></Value>
          <Text>Hello</Text>
          <Range></Range>
          <Width>96</Width>
          <Top>76</Top>
          <Left>8</Left>
          <Height>32</Height>
          <Name>edtMessage</Name>
        </object>
        <object type="TW3EditBox">
          <Value></Value>
          <Text>http://192.168.0.6:8080</Text>
          <Range></Range>
          <Width>152</Width>
          <Top>76</Top>
          <Left>112</Left>
          <Height>32</Height>
          <Name>edtDestination</Name>
        </object>
        <object type="TW3Button">
          <Caption>Send</Caption>
          <Width>128</Width>
          <Top>124</Top>
          <Left>56</Left>
          <Height>32</Height>
          <Name>W3Button1</Name>
          <OnClick>W3Button1Click</OnClick>
        </object>
        <object type="TW3Label">
          <Caption>Received:</Caption>
          <Width>232</Width>
          <Top>176</Top>
          <Left>8</Left>
          <Height>32</Height>
          <Name>lblReceived</Name>
        </object>
        <object type="TW3Label">
          <Width>256</Width>
          <Top>216</Top>
          <Left>8</Left>
          <Height>32</Height>
          <Name>lblFileContents</Name>
        </object>
        <object type="TW3Label">
          <Caption>Echo Client</Caption>
          <AlignText>1</AlignText>
          <Width>272</Width>
          <Top>8</Top>
          <Height>32</Height>
          <Name>lblTitle</Name>
        </object>
      </object>
    </object>
  </Form>
</SMART>

Programming - a skill for life!

Loading text files from the website