Archive
JSON Persistence, understanding it
Two days ago I posted what I believe to be an elegant solution to general, JSON based, object persistency. It was naturally never meant to a “one storage mechanism to rule them all” type post; nor solution for that matter. But it did present the solution to a problem I know many people have been struggling with or had issues with quite commonly. It’s one of those issues that you never really see until you get there, until you sit down to code something that happens to include JSon serialization. And it bugs you because things like this should really be a one liner.
To clarify some of the responses I have recieved, both here and on Facebook, I figured it would be appropriate to do a follow-up. I was quite tired when I posted that code, and I also realize that if you havent really bothered with JSON storage before (or indeed, looked at alternatives to Delphi’s somewhat old-fashioned, binary only built-in mechanism) then you might miss my point completely.
For instance, one person posted “what do you do with methods or properties that are not defined, just throw them away”. At first I frankly did not understand what the person was talking about – but then I realized that he had confused my talk about compilers and parsers and the fact that the code came from a library built for that -for the very purpose and point of the article.
Ofcourse I don’t throw away methods or properties, but that has nothing to do with the actual article. The article was really about finding a simple, elegant way of storing an object instance as JSON. Preferably using nothing but what Delphi has to offer.
What is the problem?
Before we look at the problem directly, let’s get an overview of the situation. For instance, how do you store a Delphi object instance as JSon? What are the options we have to work with? What exactly does Delphi provide out of the box?
These are fair, simple questions. Yet if you google it or look it up on Stack Overflow, the answers are overwhelmingly diverse. If you take into account libraries like SuperObject which people seem to mix and match with built-in classes from the runtime library, finding a simple reply can be a challenge. Especially if you don’t know that much about JSon to begin with or are learning Delphi from scratch.
Now to cut a long story short, Delphi has some outstanding solutions with regards to JSon. But naturally there are a few aspects here and there that could be better. And that is not really criticism, an RTL is a complex thing to write and maintain. And the level of support Delphi has for almost everything imaginable is staggering. So I don’t feel this is so much a “lack” as it is an oversight or prioritization issue.
What is lacking is the bridge, or gap if you will, between the world of natively compiled assembly code objects in memory (read: ordinary object pascal objects), and easily representing these as a text-based, Json (JavaScript object notation) format.
To my knowledge there are only two methods you can use to “save” or “take a snapshot” of an object instance that results in Json. The first being:
LSomeObjVar := TJSon.ObjectToJsonObject(instance);
This essentially enumerates all the published properties of that instance and stores it directly in a JSon object (which is itself an instance) and returns that. Which is very handy if you are building a larger JSon schema containing many objects.
The second method, which does more or less the same is this:
LSomeStrVar := TJSon.ObjectToJsonString(instance);
As you no doubt guess that returns the actual JSon text rather than a JSon object. Which is even more handy since that’s ultimately what we want.
To be fair, extracting JSon information through the use of the VCL or FMX is not really a problem. It does what is expected in traditional manner, namely to enumerate published properties that are both readable and writable and emit these in the format in question.
Anyone familiar with Delphi’s Assign(), AssignTo() and the DefineProperty() methods, the latter being a topic of great confusion to beginners; and finally TFiler which is used to deal with data that cannot easily be represented by ordinary properties. If you have any knowledge of these then you should have intimate knowledge of how it all works.
Right, that was the “stringify” options at hand. Now let’s look at the second part of the magic trick – namely to reincarnate an instance from JSon text.
Parsing JSon into an instance
I may be missing something but to my knowledge there are only two methods we can use for this. Naturally you can choose to traverse an object yourself through RTTI, save the information as JSon, then assemble it by hand at the other end — or some variation of the two; but the keyword here were simple, elegant and at-hand. We all know that anything is possible if you sit down and allocate enough time and energy – but this was about what we can do out of the box.
The first method takes a JSon object containing the data, but it demands a class in order to know what instance to create:
TJSon.JsonToObject<TSomeClass>(Source)
This is, in essence, the problem. Knowing beforehand the classtype to use.
It is a problem if you have several classes that inherit from a common ancestor. For example, let’s say you are making an invoice program. And let’s say you have a base-class simply called TInvoice. Inheriting from that is TRetractedInvoice and TPaidInvoice.
- TInvoice
- TRetractedInvoice
- TPaidInvoice
TRetractedInvoice being a class that represents an invoice where where the customer has gotten his money back. Perhaps the product was damaged, did not match his expectations or something similar. Either way, this class is used to represent invoiced where the money has been returned. This is noted in the ledger for the books to even out. Otherwise there will be hell to pay should you get an audit.
The second class that inherits from TInvoice is TPaidInvoice. This decendant represents an invoice which has been paid in full. The transaction is complete and there is nothing to report. Just a normal sale.
Now you could argue that using classes to represent states is overkill. You could in fact just have TInvoice and then use a datatype to represent these states. But that’s not the point. You should be allowed to use classes like this, it should not even be a debate.
But how exactly do you know what class to use before the actual data has been read? No matter how you look at this problem, you cannot escape the fact that seeing into the future is reserved for circus sideshows and scam artists abusing peope’s insecurities.
Thankfully, TJSon presents a second alternative, namely one where you give it a pre-created instance and it will map the properties that match. So if a property in the JSon data match a property in the instance, it will populate it.
TJSon.JsonToObject(someinstance, Source);
But wait, that still does not solve our problem! Simply providing an a pre-made instance gives us more options ofcourse, but the problem of foresight and being able to look into the future is still there.
Unless, we make sure that looking into the past preserves the future that is.
The solution
The obvious solution is to simply store the classname with the JSON text when we stringify the instance. And that is precisely what I have done. This means ofcourse that we have to read the JSon data before we call JSonToObject() but honestly, that is a small price to pay for complete uniformity.
But this brings up a couple of other challenges, namely:
- How do we create a class based purely on a string-name?
- How do we avoid writing the same information for each step in the inheritance chain
When it comes to the first topic, this is where Registerclass() comes into play.
Every class you register through Registerclass() can also be created by name and it’s type looked up. This is an essential part of the binary, built-in persistant system Delphi has always shipped with. So we can put some faith in it.
Interestingly, when looking at these topcis, I suddenly realized something important. It took me a second to see that I was in fact imposing a condition that did not exist, not unless you wanted to clone instances. Because who will be doing the parsing and reading anyhow? There will already be an instance created to this exact piece of data: namely none other than “self”. This is why my solution contains:
procedure TQTXASTPersistent.Parse(ObjectData: string); var LSchema: TJsonObject; LObjData: TJsonObject; LEntry: TJSonObject; LId: string; begin LId := ''; // Parse whole schema LSchema := TJSonObject( TJSonObject.ParseJSONValue(ObjectData, true) ); try if LSchema.Values[QualifiedClassName] <> nil then begin // Find storage entry for our class LEntry := TJsonObject( LSchema.GetValue(QualifiedClassName) ); // attempt to get the identifier if LEntry.Values['$identifier'] <> nil then LId := LEntry.GetValue('$identifier').Value; // validate identifier if LId.Equals(Classname) then begin // Grab the data chunk of our entry LObjData := TJSonObject( LEntry.GetValue('$data') ); // Data PTR valid? if LObjData <> nil then begin // Map values into our instance try ReadObjectJSon(LObjData); except on e: exception do raise EQTXASTJSONError.CreateFmt ('Serialization failed, system threw exception %s with message "%s" error', [e.ClassName, e.Message]); end; end else raise EQTXASTJSONError.CreateFmt ('Serialization failed, unable to find section ["%s\$data"] in JSON document error', [QualifiedClassName]); end else raise EQTXASTJSONError.CreateFmt ('Serialization failed, invalid signature, expected %s not %s error', [classname, LId]); end else raise EQTXASTJSONError.CreateFmt ('Serialization failed, unable to find section ["%s"] in JSON document error', [QualifiedClassName]); finally LSchema.Free; end; end; procedure TQTXASTPersistent.ReadObjectJSon(const Source: TJSONObject); begin TJSon.JsonToObject(self, Source); end;
Simple, elegant and to the point.
It is also flexible to avoid the second topic mention above, namely the trap of recursive or repeatative data. So you can inherit from this class all you want, it will never produce JSon for it’s ancestor. It will always produce the full set of published properties of it’s datatype. Exclusively. So unless you override and mess about with how data is written, it will work quite elegantly for ordinary tasks.
As a safety meassure, I store the object information in its own namespace. I use the qualified name of the class as an entrypoint, and the data for that classtype is stored there. If you should inherit from the baseclass and introduce some special data (for example by overriding the WriteObjectJSon() and ReadObjectJSon() methods, that will automatically end up in it’s own namespace or entrypoint. Pretty cool if I say so myself 🙂
Let’s look at a simple example. Here I have a very humble class with two published properties. I changed the name TQTXASTPersistent to just TQTXPersistent. Just to make it simpler to read:
[TQTXAutoRegister] TTestClass = class(TQTXPersistent) private FFirst: string; FLast: string; published property FirstName: string read FFirst write FFirst; property LastName: string read FLast write FLast; end;
When we create an instance of this, put something in the properties, then serialize. This is how the serialized data looks like:
{
"mainform.TTestClass":
{
"$identifier":"TTestClass",
"$data":
{
"first":"Jon",
"last":"Aasenden"
}
}
,
"$classname$":"TTestClass"
}
If I for some reason need to inherit from that again, and alter the storage routine manually to include more data, The “mainform.TTestClass” section will still be there, but now the properties particular to my new class will end up in its own section (!). They will never collide or overwrite each other. And the root property $classname$ will always contain the actual name of the class the data represents, never an ancestor. This is because inherited data is written first, and the actual instance will write it’s information last.
So here we have a pretty good system if you ask me. A lot easier to work with and deal with than manually having to traverse RTTI information. And even better, no external libraries required. Just what Delphi gives us out of the box.
Cloning, how did you solve it?
But the problem still remains. Namely the abillity to create an instance purely based on the information in the JSon data. Providing the class is known to delphi (or that I write some registerclass equivalent, but why recreate the wheel?).
Well, turned out that with the above mechanism in place, it was quite easy. Instead of a simple “clone” method I made it even more generic, a class function, allowing you to create any instance from a JSon file – providing the class has been registered with Delphi first:
class function TQTXASTPersistent.JSONToObject (const MetaData: string; var obj: TObject): boolean; var LSchema: TJsonObject; LClassName: string; LType: TClass; LNameNode: TJSONValue; LObj: TQTXASTPersistent; begin result := false; obj := nil; // Parse whole schema LSchema := TJSonObject( TJSonObject.ParseJSONValue(MetaData, true) ); try LNameNode := LSchema.Values['$classname$']; if LNameNode <> nil then begin LClassName := LNameNode.Value; LType := GetClass(LClassName); if LType <> nil then begin LObj := TQTXASTPersistent( LType.Create ); LObj.Parse(MetaData); obj := LObj; result := true; end; end; finally LSchema.Free; end; end;
Well, I hope this clears up any confusion on the subject. In my own defence I was very tired when I posted the code, which is always a bad idea.
And as always, if you know of a better way, perhaps some command i have missed or a class I have overlooked, I would love to learn about it.
JSON persistence, when a classtype is only known at runtime
One of the cool things about Delphi is that there are usually many different ways of solving a problem.
When I write code I try to make it as simple as I can. There was a time where I would jump in and try to speed things up with assembler, use exit in for/next loops to avoid setting the result more than absolutely necessary and try to squeeze every last drop of performance out of my PC.
But what about those cases where you don’t know, where you have a large inheritance chain involving many classes – all of which can be serialized and have parent/child relationships impossible to predict?
But as you grow a little bit older and perhaps a tiny bit more mature (ahem, at my rate I’ll hit puberty sometime next year) you start to value different things. Maintainability, safety and readability suddenly become an active part of your vocabulary. So you start looking at what’s already in Delphi rather than coding a faster, cooler version of the wheel.
That JSON thing
I must have seen about 100 different serialization schemes for Delphi. Some RTTI walkers, some binary only streaming, and some even hand-write every property, which to me utterly defeats the purpose of RTTI. I mean, what is the point of RTTI if you cannot automate how classes are saved? And perhaps more importantly: how classes are loaded back.

Serialization plain and simple
Most examples online deal with known classes. Meaning that the code expects you to hardcode the target type you want to de-serialize. Again I find this to completely defeat the purpose of both JSON, RTTI and persistence; the whole point of serialization is being able to reduce an instance to a portable, safe, readable format (string); and then re-create that instance without any loss of information from the portable format at will.
Known at runtime
Having to know exactly what class a piece of JSON text is prior to serialization is backwards, at least to my mind. There will naturally be situations where you do know exactly what class will be involved – at it may be fixed and never change (like child objects of a particular type). But what about those cases where you don’t know, where you have a large inheritance chain involving many classes – all of which can be serialized and have parent/child relationships impossible to predict?
In my case, an AST (abstract symbol tree) which is a model of a program. It’s what a parser and compiler generates before transforming it into machine-code, or in my case bytecodes and JavaScript.
As you can guess, an AST structure can contain all manner of combinations and parent/child relationships. Everything is parsed, validated and placed into the AST structure. Every parameter or return datatype is attached to its logical parent.
In short: you can forget about foresight or hardcoding anything! And if JSON is going to be of any use, it has to be able to de-serialize and recognize a class on the spot.
Autoregister
Earlier I posted an example of an attribute that autoregister a class with Delphi’s persistent framework. To explain what it means to register a class is beyond the scope of this post, but it essentially makes a class “known” to Delphi. Making Delphi able to recognize its type and re-create it by name alone. But this system is mainly used for binary storage, not JSON.
But it’s actually exactly what we need to automate JSON serialization.
Getting into it
Since I can’t really post a whole AST with nearly 100 classes here, I will just post this one class that contains the JSON storage mechanism you need. Just inherit from that class (clean it up and rename it first) and each inheritance step will actually take care of itself. It should be easy enough to extract the essence of this code.
You also want the AutoRegister Attribute I posted earlier! Also keep in mind that in this case we de-serialize to the current instance. You simply need to use Getclass() to get the classtype by name, create an instance of it and then de-serialize the JSON into a fresh new instance.
uses System.Rtti, System.TypInfo, System.Sysutils, System.Classes, System.Generics.Collections, System.Json, REST.Json, REST.JSon.Types, REST.JsonReflect, autoregister; [TQTXAutoRegister] TQTXASTPersistent = class(TInterfacedPersistent) protected procedure WriteObjectJSon(const Target: TJSONObject); virtual; procedure ReadObjectJSon(const Source: TJSONObject); virtual; public procedure Assign(Source: TPersistent); override; function Stringify: string; virtual; procedure Parse(ObjectData: string); virtual; class function JSONToObject(const MetaData: string; var obj: TObject): boolean; end; //########################################################################## // TQTXASTPersistent //########################################################################## procedure TQTXASTPersistent.Assign(Source: TPersistent); begin if assigned(source) then begin if (source is Classtype) or (source.InheritsFrom(ClassType)) then begin Parse( TQTXASTPersistent(Source).Stringify ); end else inherited Assign(Source); end else inherited Assign(Source); end; function TQTXASTPersistent.Stringify: string; var LObj: TJsonObject; begin LObj := TJsonObject.Create; try WriteObjectJSon(LObj); finally result := TJSon.Format(LObj); LObj.Free; end; end; procedure TQTXASTPersistent.Parse(ObjectData: string); var LSchema: TJsonObject; LObjData: TJsonObject; LEntry: TJSonObject; LId: string; begin LId := ''; // Parse whole schema LSchema := TJSonObject( TJSonObject.ParseJSONValue(ObjectData, true) ); try if LSchema.Values[QualifiedClassName] <> nil then begin // Find storage entry for our class LEntry := TJsonObject( LSchema.GetValue(QualifiedClassName) ); // attempt to get the identifier if LEntry.Values['$identifier'] <> nil then LId := LEntry.GetValue('$identifier').Value; // validate identifier if LId.Equals(Classname) then begin // Grab the data chunk of our entry LObjData := TJSonObject( LEntry.GetValue('$data') ); // Data PTR valid? if LObjData <> nil then begin // Map values into our instance try ReadObjectJSon(LObjData); except on e: exception do raise EQTXASTJSONError.CreateFmt ('Serialization failed, system threw exception %s with message "%s" error', [e.ClassName, e.Message]); end; end else raise EQTXASTJSONError.CreateFmt ('Serialization failed, unable to find section ["%s\$data"] in JSON document error', [QualifiedClassName]); end else raise EQTXASTJSONError.CreateFmt ('Serialization failed, invalid signature, expected %s not %s error', [classname, LId]); end else raise EQTXASTJSONError.CreateFmt ('Serialization failed, unable to find section ["%s"] in JSON document error', [QualifiedClassName]); finally LSchema.Free; end; end; procedure TQTXASTPersistent.WriteObjectJSon(const Target: TJSONObject); var LObj: TJsonObject; begin LObj := TJSonObject.Create; LObj.AddPair('$identifier', ClassName); LObj.AddPair('$data', TJSon.ObjectToJsonObject(self) ); Target.AddPair(QualifiedClassName, LObj); Target.AddPair('$classname$', ClassName); end; procedure TQTXASTPersistent.ReadObjectJSon(const Source: TJSONObject); begin TJSon.JsonToObject(self, Source); end; // This function will create any registered class based on name. // The class must be registered first. class function TQTXASTPersistent.JSONToObject (const MetaData: string; var obj: TObject): boolean; var LSchema: TJsonObject; LClassName: string; LType: TClass; LNameNode: TJSONValue; LObj: TQTXASTPersistent; begin result := false; obj := nil; // Parse whole schema LSchema := TJSonObject( TJSonObject.ParseJSONValue(MetaData, true) ); try LNameNode := LSchema.Values['$classname$']; if LNameNode <> nil then begin LClassName := LNameNode.Value; LType := GetClass(LClassName); if LType <> nil then begin LObj := TQTXASTPersistent( LType.Create ); LObj.Parse(MetaData); obj := LObj; result := true; end; end; finally LSchema.Free; end; end;
Autoregister attribute for Delphi
Wouldnt it be nice if Delphi had an attribute that would automatically register your classes? So instead of having to manually call Registerclass() you just decorate the class with an attribute and it’s automatically registered. No messing about with rouge procedure calls in the initialize section, just pretty and neat class declarations as far as the eye can see.
Well, I think that would be a good idea. And after searching for such a class without finding it (which is a bit odd since it’s such an obvious candidate for automation) – I decided to make one.
Now if you are expecting a huge unit with super-duper advanced code, I’m afraid I must disappoint you. This class is about elegance, grace and usefulness. It may be a humble class in the great scheme of things, but as is often the case in life, the simplest things can be of greatest value.
I find it very useful and I hope you find it equally helpful in your projects.
unit AutoRegister; interface uses System.Rtti, System.TypInfo, System.Sysutils, System.Classes; type // Our fancy shmancy attribute TAutoRegister = class(TCustomAttribute) end; implementation // This procedure walks through all classtypes and isolates // those with our TAutoRegister attribute. // It then locates the actual classtype and registeres it // with Delphi's persistance layer procedure ProcessAutoRegisterAttributes; var ctx : TRttiContext; typ : TRttiType; attr : TCustomAttribute; LRealType: TClass; LAccess: PTypeData; begin ctx := TRttiContext.Create(); try for typ in ctx.GetTypes() do begin if typ.TypeKind = tkClass then begin for attr in typ.GetAttributes() do begin if attr is TAutoRegister then begin LAccess := GetTypeData(typ.Handle); if LAccess <> nil then begin LRealType := LAccess^.ClassType; if LRealType <> nil then begin if LRealType.InheritsFrom(TPersistent) or LRealType.InheritsFrom(TInterfacedPersistent) then begin RegisterClass( TPersistentClass(LRealType) ); end; end; break; end; end; end; end; end; finally ctx.Free(); end; end; // We want to register all the classes decorated with our little // attribute when this unit is loaded into memory Initialization begin ProcessAutoRegisterAttributes; end; end.
That’s basically it. Now to use the attribute just save out the unit and include it as you would any other (just add it to the uses-clause where you need it). Then decorate the classes you want registered automatically.
Remember that only classes that inherit from TPersistent (which includes TInterfacedPersistent) can be registered.
uses AutoRegister; type [TAutoRegister] TMyClass = class(TPeristent) end; [TAutoRegister] TMyCoolClass = class(TInterfacedPersistent) end;
And voila, no more Registerclass() calls at the bottom of your units. Just neat, clean object oriented code -and as a bonus: I find it easier to read as well.
Cheers!
Goodbye G+ Delphi Developers group
Looking into the actual data, with JavaScript leading and JavaScript libraries on client and server side (Angular.js, Node.js) on the rise, it was nice to see that while Delphi was not listed as an option, it was the most typed entry in the “others” category -Source: Marco Cantu
- Smart Mobile Studio is written 100% in Delphi
- Smart Mobile Studio was created from scratch to compliment Delphi
- Smart Mobile Studio supports Remobjects SDK out of the box
- Smart Mobile Studio supports Embarcadero Datasnap out of the box
- Smart Mobile Studio helps Delphi developers write the middleware or interfacing that sits between a native Delphi solutions and a customer’s node.js or purely web-based solution. This is 2016 after all.
- Where a Delphi developer would previously have to decline a job offering because the customer’s existing infrastructure is based on node or emits data unsuitable for traditional Delphi components, developers can now relax and write the missing pieces in a Smart pascal, a dialect roughly 90% compatible with the language they know and love to begin with.
- Smart Mobile Studio ships with a wast RTL that greatly simplify talking with Delphi. It also has a VCL inspired component hierarchy where more and more complex behavior is introduced vertically. This gives your codebase a depth which is very hard to achieve under vanilla JavaScript or Typescript.
- Smart Mobile Studio is all about Delphi. It is even used to teach programming in the UK. Teenagers who by consequence and association is statistically more likely to buy Delphi as they mature.
- Decline the project
- Learn JavaScript or Typescript and do battle with its absurd idiosyncrasies, lack of familiar data types, lack of inheritance and lack of everything you are used to
- Use Smart Mobile Studio to write the middleware between your native solution and the customer existing infrastructure
If you pick option number two, it wont take many days before you realize just how alien JavaScript is compared to Delphi or C++ builder. And you will consequently start to understand the value of our RTL which is written to deal with anything from low-level coding (allocmem, reallocmem, fillmemory, move, buffers, direct memory access, streams and even threading). Our RTL is written to make the JavaScript virtual machine palatable to Delphi developers.
Banning dialects?
Once you start banning dialects of a language or an auxiliary utillity designed to empower Delphi and make sure developers can better interface with that aspect of the marketplace – where does it stop? I am curious to where exactly the Google+ Delphi group draws the line here to be honest.
Should Remobject Oxygene likewise be banned since it helps Delphi developers target the dot net framework? That would be odd since Delphi shipped Oxygene for years.
Should script engines be banned? What about SQL? SQL is a language most Delphi developers know and use – but it is by no measure object pascal and never will be. Interestingly, Angular.js seems to be just fine for the Google+ Delphi group. Which is a bit hypocritical since that is JavaScript plain and simple.
What about report engines? Take FastReport for instance: FastReport have for the past decade or more bolted their own scripting engine into the product, a script engine that supports a subset of object pascal but also visual basic (blasphemy!). On iOS you are, if we are going to follow the Apple license agreement down to the letter, not even allowed to use FastReport. Apple is very clear on this. Any applications that embed scripting engines and at the same time download runnable code (which would be the case when downloading report files) is not allowed on appstore. The idea here is that should some code be downloaded that is harmful, well then Apple will give you a world of hurt. And even if you consider it a report-file, it does contain runnable code – and that is a violation.
So is Fastreport Delphi enough? Or is that banned as well?
Where exactly do we draw the line? I can understand banning posts about dot net if it’s all about C#, but if it’s in relation to Delphi or deals with Delphi talking with dot net (or an actual dialect like Oxygene) then I really don’t see why it could be banned or deleted. Even Delphi itself uses dot net. It’s one of the pre-requisites for installing Delphi in the first place. I guess Delphi should also be banned from the Delphi group then?
In our group on Facebook, all are welcome. Embarcadero, Lazarus and Free Pascal, Elevate software (be it their database engines or web builder), Pax compiler, DWScript, Smart Pascal, NewPascal (or whatever it’s called these days) and even Turbo Pascal for that matter. And we sure as shit dont delete posts of Delphi talking to another system.
So goodbye G+ and good luck
Smart Pascal, supported server types

Use node.js to fill your xmas with fun!
Node.js is probably one of the coolest pieces of software I have had the pleasure to work with for years. It’s platform independent and available for just about every operative system you can imagine. I would even go so far as to say it has become universal.
NodeJS allows you not only to write server-side JavaScript, but also your own system level services. This is especially easy on Linux where the philosophy regarding a service is somewhat different from Microsoft Windows. On Linux, a simple bash script can be installed as a service. You can write services in python, perl or whatever tickles your fancy.
Our latest addition: UDP
Today I had a few minutes to test the UDP implementation I finished last week, and I was for some odd reason expecting an exception or “something” to come up. You know.. when something is that easy to write, there’s typically is a catch right? Or maybe im just and old, cynical Delphi developer. Either way, it worked on the first try!
Now I realize that UDP is not what you use for high-end, reliable communication. But that is beside the point. I want the code you get access to in our next update to be polished, easy to use and something you can rely on. And the keyword here is “co-operation”. My personal service stack that I host in my own home is written in 4 different languages. You have Delphi and C# services running under Windows, you have Lazarus daemons on my Linux box (a full PC) and last but not least — you have Smart Pascal servers running on embedded hardware.
Our list of server types now include:
- HTTP
- TCP
- WebSocket
- UDP
I use UDP more or less as a signal trigger between processes to handle wait, ready, update and even restart. So by broadcasting a single “shutdown” signal, all my machines will gracefully stop and then power down.
So, how does an UDP server look like? It borders on ridicules how little effort it takes:
procedure TNodeService1.SetupUDPServer; var Server: TNJUDPServer; begin Server := TNJUDPServer.Create; Server.Port := 1881; Server.Address := '127.0.0.1'; Server.MulticastLoopback := true; Server.Broadcast := true; Server.Exclusive:= false; Server.OnMessage := procedure (Sender: TObject; Data: variant; RequestInfo: TNJUDPRequestInfo) begin writeln("Message recieved!"); end; Server.OnError := procedure (Sender: TObject; ErrorObj: TJsErrorObject) begin writeln("Error:" + ErrorObj.message); end; Server.OnClose := procedure (Sender: TObject; ErrorObj: TJsErrorObject) begin writeln("Server closed"); end; Server.OnAfterServerStarted := procedure (sender: TObject) begin writelnF("Server started, listening on post %d @ %s", [Server.port, Server.Address]); end; Server.Active := true; end;
That’s pretty much it. Naturally you have to fill in the blanks, but the above code is all you have to write to create a UDP server. The cool part is that all server classes inherit from a common ancestor, so once you know how to code one – you have a leg up on using the rest of them.
Running the server as a Linux Daemon
Like all languages, node.js has a few tools that are considered standard. It’s like we Delphi developers take component’s and libraries like GR32 and SynEdit for granted. These packages have become so standard that we forget how hard it can be for beginners to get an overview of what’s available.
Turns our node.js is no different, and the tool everyone is using to run their node.js code as a dedicated background service (meaning that it will start during the boot sequence) is called PM2 or node.js process manager v2.

Running your Smart Pascal server as a system-level daemon is very easy once you know what to look for 🙂
In short, PM2 is like a watch-dog that keeps an eye on your service. If it crashed PM2 will re-started it (unless you tell it otherwise), it also does extensive logging for you – and it will even generate a startup script that you can add to the Linux (or windows) startup sequence.
But the most important aspect of PM2 is that you can easily get some “live” info on your services, like how much memory they consume, the CPU consumption and everything else. It’s also PM2 that makes it a snap to run your node.js servers in cluster mode, meaning that you can spread the workload over multiple machines and cores for better performance.
Getting PM2 up and running is easy enough. Just make sure you have installed NPM first, which is the “node package manager” front-end. To install NPM you just write:
sudo apt-get install npm -y
And with NPM available on your system, you install PM2 through NPM (PM2 is ofcourse written in node.js itself):
npm install pm2 -g
Next, having compiled our Smart Pascal project, we copy the file over to a shared folder on our raspberry PI (I installed Samba to make this easier), cd into the folder and type:
pm2 start backend/backend.js --name backend
Notice the “–name backend” part? PM2 allows you to assign names to your code. This makes it easier to manage them (not having to type the full path every single time).
To check if our service is now installed, type:
pm2 show backend
And voila! We have a live Smart Mobile Studio server running on a Raspberry PI 3! Now whip out Delphi and recycle those legacy services!
You must be logged in to post a comment.