Home > Delphi, JavaScript, Object Pascal, OP4JS, Smart Mobile Studio > Getting data into your Smart Mobile apps

Getting data into your Smart Mobile apps

The new reality is all about small, powerful mobile devices. The 80’s was all about home computing, the 90’s about creativity and the 2k’s about connectivity. Well we have mastered all of those aspects of computing, and now it’s the age of mobility! Not just for devices you put in your pocket, but for the data that comes with it.

Getting data

No matter if you are writing your next iPhone or Android application with Delphi + FMX or Smart Mobile Studio + Phonegap, your data has to come from somewhere. Unless it’s a very small, very limited notepad application where your customer is expected to populate it from top to bottom; but that would be a very strange app in our day and age.

Getting data from your company servers or perhaps the latest public service is not always easy. But with the advent of WebSockets this has pretty much changed – if you have paid attention to the web technology that is.

So what are WebSockets? In short it’s just like normal networking sockets, but with a few limitations. You are allowed to connect, send ordinary text and also binary data. The latter is in the form of blobs or untyped array buffers. Dont worry, we have taken care for all that for you, so sit back and relax and enjoy the code.

Also websockets are automatically created for long sessions, so the underlying architecture will try to keep the connection alive. This is very important since we dont want to re-connect over and over again just to send small packets. So it’s more economic to keep a single connection alive that both server and client read and write to.

Creating a server

First you need to download the WebSocket server (based on Indy which is installed with Delphi). This can be done from this website. If you havent written a server before, don’t worry – it’s actually quite fun! Especially with WebSocket since essentially what you do is read commands, fetch data, send a response – and then wait for another command again. But you should get a book on the subject if you are a complete newbie, or get acquainted with the concept by trying Indy from Delphi first.

Server design is also fun because you get to define the protocol your mobile devices should use! You can go for a simple text-based protocol, you can opt for superobject (JSON objects) based packets, XML or just invent something completely new. You may also want to stick to standards so that people can buy access to your services? Quite a few people make a living creating just web-services. It’s a rather lucrative market to be honest.

Note: I urge you to create your first server as a normal GUI program, and only later when everything is working 100% isolate it as a Windows Service or Linux Daemon. There are bound to be errors (network coding is no different from other types of coding) and it’s easier to debug and display those errors with a GUI.

Creating the client

Your apps liven up with data from a server

Your apps liven up with data from a server

This is the fun part! Once you have some rudimentary server up and running, be it an echo service or a serious power-house of a database service, Smart Mobile Studio will help you deal with it.

Working with web-sockets is really not that different from using the ordinary Indy components. You call commands and handle events, like OnMessage which signals that a text has been received from the server. Remember that you can send and deal with binary data through Base64 encoding. JSON is perfect for stringifying complex datatypes – so everything is really for the picking here.

Below is a websocket class ready to be played with. Please note that this uses the new RTL classes, which means you have to be a part of the beta team to compile it. Although it will compile if you remove all the write() method except the string based one.

Either way, it demonstrates how easy it is to transport data between your company server – and your Smart Mobile Studio application. Websockets are super awesome, easy to use, they work on all platforms (and all popular browsers), on mobile devices just as desktop — so it’s the easiest route to get your data from A to B.


  TWebSocketHandle  = THandle;

  TWebSocketState = (stError,stIdle, stConnecting, stConnected, stClosing, stClosed);

  TWebSocketOpenEvent     = procedure (sender:TWebSocket);
  TWebSocketCloseEvent    = procedure (Sender:TWebSocket);
  TWebSocketErrorEvent    = procedure (Sender:TWebSocket);
  TWebSocketMessageEvent  = Procedure (Sender:TWebSocket;Value:String);

  EWebSocket = Class(EW3Exception);
  TWebSocket = Class(TObject)
  private
    FHandle:    TWebSocketHandle;
    FOnOpen:    TWebSocketOpenEvent;
    FOnClose:   TWebSocketCloseEvent;
    FOnMessage: TWebSocketMessageEvent;
    FOnError:   TWebSocketErrorEvent;
  public
    Property    OnOpen:TWebSocketOpenEvent read FOnOpen write FOnOpen;
    Property    OnClosed:TWebSocketCloseEvent read FOnClose write FOnClose;
    Property    OnMessage:TWebSocketMessageEvent
                read FOnmessage write FOnmessage;
    Property    OnError:TWebSocketErrorEvent
                read FOnError write FOnError;

    function    SocketState:TWebSocketState;
    Function    Connected:Boolean;
    function    URL:String;
    function    Protocol:String;

    Procedure   Connect(URL:String;Protocols:Array of String);
    Procedure   Write(value:String);overload;
    procedure   Write(Value:TMemoryHandle);Overload;
    Procedure   Write(Value:TStream);overload;
    Procedure   Write(Const Data:TBinaryData);overload;

    procedure   Disconnect;
    Destructor  Destroy;Override;
  end;

uses  W3C.DOM,
      W3C.TypedArray,
      W3C.WebSocket;

//############################################################################
// TWebSocket
//############################################################################

Destructor TWebSocket.Destroy;
Begin
  if (FHandle) then
  Disconnect;
  inherited;
end;

function TWebSocket.Protocol:String;
begin
  if (FHandle) then
  result:=JWebSocket(FHandle).protocol;
end;

function  TWebSocket.URL:String;
begin
  if (FHandle) then
  result:=JWebSocket(FHandle).url;
end;

function TWebSocket.SocketState:TWebSocketState;
	const
		CONNECTING: Integer = 0;
		OPEN: Integer = 1;
		CLOSING: Integer = 2;
		CLOSED: Integer = 3;
begin
  if (FHandle) then
  begin
    case JWebSocket(FHandle).readyState of
    CONNECTING: result:=stConnecting;
    OPEN:       result:=stConnected;
    CLOSING:    result:=stClosing;
    CLOSED:     result:=stClosed;
    else        result:=stError;
    end;
  end else
  result:=stIdle;
end;

Function TWebSocket.Connected:Boolean;
begin
  result:=not (SocketState in [stIdle,stClosed,stError]);
end;

Procedure TWebSocket.Connect(URL:String;Protocols:Array of String);
begin
  (* disconnect socket if already connected *)
  if connected then
  disconnect;

  (* Allocate new socket *)
  try
    asm
    (@self.FHandle) = new WebSocket(@url,@protocols);
    end;

    JWebSocket(FHandle).onclose:=Procedure ()
      begin
        if assigned(FOnClose) then
        FOnClose(self);
      end;

    JWebSocket(FHandle).onopen:=Procedure ()
      Begin
        if assigned(FOnopen) then
        FOnOpen(self);
      end;

    JWebSocket(FHandle).onmessage := procedure ()
    var
      event:  Variant;
    begin
      asm
        @event = event;
      end;
      if assigned(FOnMessage) then
      FOnMessage(self,String(event.data));
    end;

    JWebSocket(FHandle).onerror := procedure ()
    begin
      if assigned(FOnError) then
      FOnError(self);
    end;

  except
    on e: exception do
    Raise EWebSocket.CreateFmt
    ('Connect failed, system thew exception %s [%s]',[e.classname,e.message]);
  end;

end;

procedure TWebSocket.Disconnect;
begin
  if Connected then
  begin
    try
      try
        JWebSocket(FHandle).close();
      except
        on e: exception do;
      end;
    finally
      FHandle:=NULL;
    end;
  end;
end;

Procedure TWebSocket.Write(value:String);
begin
  JWebSocket(FHandle).send(value);
end;

procedure TWebSocket.Write(Value:TMemoryHandle);
begin
  JWebSocket(Fhandle).send(JArrayBufferView(Value));
end;

Procedure TWebSocket.Write(Value:TStream);
var
  mRaw: TMemoryHandle;
begin
  if Value<>NIL then
  begin
    if Value.Size>0 then
    Begin
      Value.Position:=0;
      var mBytes:=Value.Read(Value.Size);
      mRaw:=TDataType.BytesToTypedArray(mBytes);
      Write(mRaw);
    end;
  end;
end;

Procedure TWebSocket.Write(Const Data:TBinaryData);
begin
  if Data<>NIL then
  Begin
    if Data.Size>0 then
    Write(Data.ToTypedArray);
  end;
end;

Advertisements
  1. abouchez
    March 30, 2015 at 6:28 am

    Creating a client/server system is IMHO much more than just a transmission protocol.
    Instead of re-inventing the wheel, use a real client/server framework, like our little mORMot.
    We introduced those last weeks bi directional service writing with interfaces to define the messages, using websockets for the push notifications, and still allowing REST stateless requests on the very same link.
    BTW our server-side https://github.com/synopse/mORMot/blob/master/SynBidirSock.pas unit if much more than a proof of concept: it has classes to support protocols (and includes JSON or binary compressed+encrypted content), is able to emulate REST over WebSockets, uses little resources, runs under Linux, almost all code shared between client and server, with included regression tests (including multi-threaded concurrent clients).
    We we include some client code generator code for SmarMobileStudio for those WebSockets services, once it has been stabilized, oin addition to our pure REST access http://synopse.info/files/html/Synopse%20mORMot%20Framework%20SAD%201.18.html#TITL_90

    • Jon Lennart Aasenden
      March 30, 2015 at 11:42 am

      Read the doc: “The so-called Smart Pascal language” ? So called? It’s a tech name given not just by me, but also eric grange which maintains the back-end compile. So the dialect is called Smart Pascal. DWS and SMS may go separate ways (and have in many internal respects) so it’s not the same as DWS

      • abouchez
        March 30, 2015 at 11:53 am

        “so-called” was without any pejorative aspect. It means “commonly named”, i.e. it indicates the name that is commonly or usually used for something. http://www.merriam-webster.com/dictionary/so-called
        I use SmartPascal almost every day, and enjoy its features!

        • Jon Lennart Aasenden
          March 30, 2015 at 11:57 am

          oki 🙂

    • Jon Lennart Aasenden
      March 30, 2015 at 11:53 am

      mORMot sounds great! DO you have a server i can test

      • abouchez
        March 30, 2015 at 11:54 am

        Samples “27 – CrossPlatform Clients” and “29 – SmartMobileStudio Client” can be used to test them.
        There is no WebSockets direct sample published yet (it is a just committed feature, which would probably evolve).

        • Jon Lennart Aasenden
          March 30, 2015 at 12:12 pm

          That sounds very interesting. I am planning to make a win32/64 service which includes a high-end DB provider through websockets, and also a high-end service dispatcher.

          Hm. Perhaps you could do me a favour? Could you investigate the possebility of a Delphi nodeJS dispatcher? Meaning a win32/64 service which can dispatch and execute multiple nodeJS servers simultaniously? I am asking since this is your field of expertice more than it is mine. I have coded hundreds of servers, and written my own socket library – but i rarely do any research on this.
          We could perhaps do some co-operation, a Smart Bundle of server software provided by you as a separate second product could be very interesting indeed.

  2. March 30, 2015 at 12:37 pm

    Hi there. I’ve created my first game with mORMot and SmartMS.
    Take a look at http://youtu.be/Jn6ODHkg6js

    • Jon Lennart Aasenden
      March 30, 2015 at 3:35 pm

      You see, the problem here is that you always include nudity. Hence I cant really promote that neither on Facebook or otherwise.
      Try using some other type of images please.

  1. No trackbacks yet.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: