Category Archives: Articles

RTC HTTP Server in 199 lines of code

Open a Text Editor of your choice, copy/paste the code below and save it as “MyHttpServer.dpr”.

program MyHttpServer;

{$APPTYPE CONSOLE}

uses
  SysUtils,

  rtcTypes,
  rtcSystem,
  rtcInfo,
  rtcConn,
  rtcDataSrv,
  rtcHttpSrv;

type
// This is our self-contained HTTP Server class ...
  TMyServer=class(TObject)
  protected
    HttpSrv:TRtcHttpServer;
    DataProv:TRtcDataProvider;

  public
    constructor Create(PortNumber:String='80'; IPVer:RtcIPV=rtc_IPVDefault);
    destructor Destroy; override;

    procedure DataProv_CheckRequest(Sender: TRtcConnection);
    procedure DataProv_DataReceived(Sender: TRtcConnection);

    procedure HttpSrv_ListenStart(Sender: TRtcConnection);
    procedure HttpSrv_ListenError(Sender: TRtcConnection; E:Exception);
    procedure HttpSrv_ListenStop(Sender: TRtcConnection);
    procedure HttpSrv_RequestNotAccepted(Sender: TRtcConnection);
    end;

constructor TMyServer.Create(PortNumber:String='80'; IPVer:RtcIPV=rtc_IPVDefault);
  begin
  // Create HttpServer and DataProvider components ...
  HttpSrv:=TRtcHttpServer.Create(nil);
  DataProv:=TRtcDataProvider.Create(nil);

  // Assign Server for our Data Provider ...
  DataProv.Server:=HttpSrv;

  // Assign Data Provider Events (handles Valid Requests) ...
  DataProv.OnCheckRequest:=DataProv_CheckRequest;
  DataProv.OnDataReceived:=DataProv_DataReceived;

  // Assign Server Events (handles the rest) ...
  HttpSrv.OnRequestNotAccepted:=HttpSrv_RequestNotAccepted;
  HttpSrv.OnListenStart:=HttpSrv_ListenStart;
  HttpSrv.OnListenStop:=HttpSrv_ListenStop;
  HttpSrv.OnListenError:=HttpSrv_ListenError;

  // Configure the Server ...
  HttpSrv.ServerPort:=PortNumber;
  HttpSrv.ServerIPV:=IPVer;
  HttpSrv.MultiThreaded:=True;

  // Start the Server listener ...
  HttpSrv.Listen();
  end;

destructor TMyServer.Destroy;
  begin
  // Stop the Server listener ...
  HttpSrv.StopListenNow();

  // Destroy the components ...
  HttpSrv.Free;
  DataProv.Free;
  end;

procedure TMyServer.DataProv_CheckRequest(Sender: TRtcConnection);
  begin
  // Check Request headers and "Accept" all Requests
  // we want to handle with our Data Provider ...
  with TRtcDataServer(Sender) do
    if (Request.Method='GET') and  // we only want "GET" requests
       (Request.ContentLength=0) then // ... with no content body
        if (Request.URI='/html') or
           (Request.URI='/json') or
           (Request.URI='/xml') or
           (Request.URI='/code') then
          Accept; // Accept the Request
  end;

procedure TMyServer.DataProv_DataReceived(Sender: TRtcConnection);
  var
    t:TRtcRecord;
  begin
  with TRtcDataServer(Sender) do
  // We will start processing the request only if
  // we have received the complee request content body ...
    if Request.Complete then
      if Request.URI='/html' then
        begin
        // We can use multiple "Write" calls
        // to prepare our HTML response ...
        Response.ContentType:='text/html';
        Write('<html><body>');
        Write('Your IP: '+PeerAddr+'<br>');
        Write('Your Port: '+PeerPort+'<br>');
        Write('Date & Time: <b>'+DateTimeToStr(Now)+'</b><br>');
        Write('Agent: <i>'+Request['User-Agent']+'</i><br>');
        Write('</body></html>');
        // All "Write" calls will be buffered,
        // RTC will calculate the "Content-Length" for us
        // and send the whole content body out as a single
        // Response - when we are finished with our event.
        end
      else
        begin
        // Using TRtcRecord to prepare our response Object ...
        t:=TRtcRecord.Create;
        try
          t.asText['agent']:=Request['User-Agent'];
          t.asText['ip']:=PeerAddr;
          t.asText['port']:=PeerPort;
          t.asDateTime['now']:=Now;
          if Request.URI='/json' then
            begin
            // Serialize to "JSON" ...
            Response.ContentType:='application/json';
            Write(t.toJSON);
            end
          else if Request.URI='/xml' then
            begin
            // Serialize to "XML-RPC" ...
            Response.ContentType:='text/xml';
            Write(t.toXMLrpc);
            end
          else if Request.URI='/code' then
            begin
            // Serialize to "Code" (RTC format) ...
            Response.ContentType:='text/plain';
            Write(t.toCode);
            end;
        finally
          t.Free;
          end;
        end
  end;

procedure TMyServer.HttpSrv_RequestNotAccepted(Sender: TRtcConnection);
  begin
  // Request wasn't accepted ...
  with TRtcDataServer(Sender) do
    begin
    // Send "404" status code back ...
    Response.Status(404,'Not Found');
    Response.ContentType:='text/plain';
    // Something to show in the Web Browser ...
    Write('Bad command.');
    // And ... Disconnect the Client.
    Disconnect;
    end;
  end;

procedure TMyServer.HttpSrv_ListenError(Sender: TRtcConnection; E: Exception);
  begin
  Writeln('Server Error: '+E.Message);
  end;

procedure TMyServer.HttpSrv_ListenStart(Sender: TRtcConnection);
  begin
  Writeln('Server started.');
  end;

procedure TMyServer.HttpSrv_ListenStop(Sender: TRtcConnection);
  begin
  Writeln('Server stopped.');
  end;

var
  MyServer:TMyServer;

begin
  try
    // Create and start our Server ...
    MyServer:=TMyServer.Create('80');
    try
      // Since this is a console application and our
      // Server is Multi-Threaded, we can do whatever
      // we want here. For simplicity reasons, we will
      // just use "ReadLn" to allow the Server to run
      // while we wait for the user to press <Enter>.

      Writeln('Press <Enter> to Quit ...');
      ReadLn;

      // User has pressed <Enter> - time to kill our Server.
    finally
      MyServer.Free;
      end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Continue reading

Beware of the “As Administrator” option on Windows 8

Yesterday, I was preparing my Windows 8 Tablet PC for development and testing. As always, I went to use the “_clear.cmd” file from the “Lib” folder to delete old files before preparing a new package. But – wait! Windows 8 won’t let me run CMD files just like that! It blocked every time. So … to outsmart this new Windows 8 feature (I think it’s called “Screen-Scan”), I’ve simply selected “As Administrator” to run the “_clear.cmd” file with higher access rights.

Continue reading

Write your first Remote Function (Lesson 5)

In this lesson, we’ll be building a solution with a Server and a Client. This first lesson with a Client side made with RealThinClient Components is simple but shows the concept behind a client – server system that could be the base for a larger application. We’ll be using Remote Functions to accomplish this task.

This Post has three sections.

  1. The Server.
  2. The Client.
  3. Make it work.

Continue reading

Send large files from a Server (Lesson 4)

This demo continues over Demo 3 (Sending small files). Now, we are going to make a webserver that is able to send files no matter their size.

We must be careful with our server’s memory, we may have a really big file in our server and we don’t want to use all of it.

At our first two examples we have been sending all of our content at once on the OnCheckRequest and OnDataReceived events of our RtcDataProvider components.

Continue reading

Send small files from a Server (Lesson 3)

By this moment, we have been sending content generated by our Server. Now we are going to see how to send small files from a folder that resides inside our Server’s running directory. We’ll do it this way because with this approach we can control what files can be accessed from the Server.

We’ll use some functions to secure our Server and check that the content (file size in this case) is small enough to send.

In the next lesson we’ll see how to deal with bigger file sizes.

We’ll need the code of our Lesson 2b post which you can download at Code For RealThinClient SDK Lesson 2b. Continue reading

Server using Query parameters (Lesson 2b)

Now that we have seen how to Create a Web Server and how to Send Dynamically Generated Content, we are going to see how to accept Query Parameters.

We are going to make some small changes to our previous code (Code for Demo Sending Dynamically Generated Content) to accept request’s query parameters.

When we coded our Dynamically Generated Content we give no option to the user to decide what Square values the system will return, so now, we are going to give the user the choice to:

  1. Select the starting number of the Square values.
  2. Select the ending number of the Square values.

Continue reading

Server sending dynamically generated content (Lesson 2)

Now we’re going to create an application to send Dynamically Generated Content. We’ll use as base the RealThinClient SDK – Your First Web Server  project. You can download the source code to work with.

In this lesson, you’ll see how two data providers can work together and how you can use multiple Write calls to send complex content out. Continue reading

Your first Web Server (Lesson 1)

We’re going to build a Web Server with RealThinClient SDK in Delphi.

Basically we are going to:

  • Create a Project
  • Add two RealThinClient SDK components (RtcHTTPServer and RtcDataProvider)
  • Configure three events.
  • Check that our Web Server is working.

We’ll be working the code sections in two formats, one using the with clause and another without it.

Continue reading

Posting code examples to RTC Forums

I’ve been burned by BB tags [b] and [i] more than once when posting code examples to RTC Forums, so I thought this would be worth mentioning here.

When posting to RTC Forums, you will be editing your text in raw format. This gives you full control over the look of your post by allowing you to directly insert special “BB” tags ([i] …[/i] for italic, [b]..[/b] for bold, [u]…[/u] for underlined text, and so on). You can also use the toolbar, which is visible directly above the text entry area (when composing your Forum post) to insert BB tags around your currently selected text.

Continue reading

RTC SDK Setup Process

First we will install the RealThinClient SDK and then the RealThinClient Portal components.

The install process is the same as for other components in the RAD Studio products. First, we unpack the downloaded files (you can download the files for the RTC SDK stater edition HERE, remember to choose the right version according to your RAD Studio version.)

Download Options

Download Options

Continue reading