In client-server mode, your logic often requires resources hosted on the server. To run code on the server, you are used to writing dedicated project methods or ORDA Data model functions.
This can lead to a large number of project methods or ORDA Data model functions that are not always justified.
With 4D 21 R3, some singletons can now have functions executed on the server.
Keep reading to learn how to improve your code organization!
In your desktop applications, certain parts of the code must be executed on the server because they read or update data that needs to be shared by all connected 4D Clients. For example, to share data in memory across all connected clients, you may currently use the Storage on the server.
Your logic may also require server-hosted resources (e.g. querying data).
To run code on the server, you were used to writing:
- a project method with the Execute on server property enabled
- an Execute on server command
- an ORDA Data model functions (which is executed on the server by default)
Now, some singletons can have functions that are always executed on the server.
The server keyword for shared and session singletons
Functions in shared and session singletons now support the server keyword.
When a function is declared with this server keyword, it is always executed on the server, even if the singleton is instantiated on a 4D Client.
Example
In the example below, the Administration shared singleton defines a server function that runs the Process activity() command.
This singleton is instantiated on a 4D Client, and the function is called from there. It returns the activity from the server (processes + sessions).
The Administration shared singleton:
shared singleton Class constructor
// This function is executed on the server
server Function processActivity() : Object
return Process activity()
// This function is executed locally
Function localProcessActivity() : Object
return Process activity()
Code running on the 4D Client:
var $localActivity; $serverActivity : Object
var $administration : cs.Administration
ASSERT(Application type()=4D Remote mode)
// The Administration singleton is instantiated on the 4D Client
$administration:=cs.Administration.me
// Get the processes running on the 4D client
$localActivity:=$administration.localProcessActivity()
ASSERT($localActivity.sessions=Null)
// Get the processes + sessions running on 4D Server
$serverActivity:=$administration.processActivity()
ASSERT($serverActivity.sessions.length>=1)
Going further with the session singleton
In this context, the session singleton provides a major advantage. A session singleton has a unique shared instance for all processes within a session.
As soon as a session singleton can execute logic on the server, it can effectively extend the capabilities of the Session command.
Example
If you store your users in a Users table and implement custom authentication, you can use a session singleton for this purpose.
In the example below, the UserSession session singleton has a checkUser() function executed on the server. The user ID is stored in the session storage shared object.
server Function checkUser($credentials : Object) : Boolean
var $user : cs.UsersEntity
var $result:=False
If ($credentials#Null)
$user:=ds.Users.query("Email === :1"; $credentials.identifier).first()
If (($user#Null) && (Verify password hash($credentials.password; $user.Password)))
Use (Session.storage)
Session.storage.userInfo:=New shared object("userId"; $user.ID)
End use
$result:=True
End if
End if
return $result
To provide the current user to all 4D clients, the session singleton exposes a user computed property retrieved from the server.
session singleton Class constructor()
server Function get user() : cs.UsersEntity
return ds.Users.get(Session.storage.userInfo.userId)
Run the attached HDI to explore concrete examples. The next step is to better organize your code by placing relevant logic in the appropriate class and … don’t wait to start working with 4D sessions!
Comments are not currently available for this post.