Chapter 7—Deploying your Web & Mobile Apps

To deploy your Omnis web or mobile application you need to host it on the Omnis App Server which is the main engine at the heart of your Omnis app deployment. You will also need a Web Server to host the HTML page containing your remote form(s) and any other web pages or content. When the end user runs your application, the app connects to the Omnis App Server, via the web server, and the JavaScript remote forms you have designed are loaded in the end user’s desktop browser or the browser on their mobile device. You can deploy your JavaScript Client based application to the web or mobile devices in two ways:

  1. Web and mobile app deployment
    you can deploy your application to the web and provide your end users with a URL to the location of the app, which they can navigate to on their desktop, tablet or mobile device; the initial remote form is embedded into an HTML file which is created for you during development which you will need to edit for deployment

  2. Standalone mobile app deployment
    alternatively you can compile your app into one of the Application Wrappers to provide a single standalone app for deployment to mobile devices; in effect the wrapper points to the HTML page containing the initial remote form for your app. A standalone app can operate “online” with a permanent connection to the internet and the Omnis App Server; it can also work “offline” and then reconnect to the Omnis App Server to synchronize data and content; or a standalone app can operate entirely in “serverless” mode without any connection to the Omnis App Server

In addition to hosting your HTML page, you need to install the Omnis Web Server plug-in into your web server which handles all communication between the Omnis App Server and any connected web and mobile clients.

Omnis Web Architecture

The server side of your web or mobile app comprises the Omnis App Server that runs your Omnis library, a standard Web Server, and your database server(s). All these parts would either run on the same machine, or more typically would be on the same LAN or subnet, communicating via TCP/IP. The web server and the Omnis App Server can be hosted on a Windows, macOS, or Linux computer server.

The web server would store your entire website, including any HTML pages containing your JavaScript remote forms and any other web pages as required, such as landing pages.

The Omnis library contains the GUI and data class definitions, business rules, and application logic, while the database server would be an industry-standard database server, such as Oracle, MySQL, PostgreSQL, Sybase, DB2, or any JDBC or ODBC compliant database such as MS SQL Server.

The Omnis App Server is the main engine that runs your web and mobile applications. It is a multi-threaded server that runs your Omnis application, executing all the business logic, accessing your server database(s), and handling all the client interactions to-and-from your web and mobile clients. Web and mobile client access to the Omnis App Server is restricted to a specified number of users and is determined by the server license, which you must purchase separately from your locale sales office.

Standalone Mobile Apps

As an alternative to deploying your applications to web browsers on web and mobile devices, you can deploy a mobile app using one of the Application Wrappers available for Android and iOS. See the Creating Standalone Apps section for more information.

Editing Your HTML Pages

Omnis creates an HTML page when you test your JavaScript remote form (when you press Ctrl-T) that contains details of the JavaScript Client object, your remote form class, the location of your web server (or your computer when testing), and so on. You can use this HTML file for deploying your web application, but you will need to edit it, or copy the relevant lines of code containing the JavaScript Client object to your own HTML pages.

The test HTML file has the same name as your remote form plus the .htm extension, and is located in the html folder under the main Omnis folder. For example, under Windows 7/8 the HTML template is located in your AppData\Local folder, such as:

C:\Users\<user-name>\AppData\Local\Omnis Software\OS<version>\html

You can edit the test HTML in a standard web page design tool or a text editor, such as Notepad under Windows.

The JavaScript Client Object

In the template HTML file, there is a <div> that contains the JavaScript Client called ‘omnisobject1’. It contains various parameters that provide details about your application that are sent to the Omnis App Server when the client connects. The parameter names are in lowercase and prefixed with ‘data-‘, to comply with HTML5.

The code for omnisobject1 from the ‘jsctempl.htm’ file is as follows (for existing users, the equivalent old parameter names are included in parenthesis):

<div id="omnisobject1" style="position:absolute;top:0px;left:0px" data-webserverurl="" (was WebServerURL)
data-omnisserverandport="" (was OmnisServerAndPort)
data-omnislibrary="" (was OmnisLibrary)
data-omnisclass="" (was OmnisClass)
data-param1="" data-param2="" (was param1, param2,..)
data-commstimeout="0"> (new parameter)

For example, the HTML page containing the Omnis quiz has the following <div> tag containing the JavaScript Client object and its parameters:

<div id="omnisobject1" style="position:absolute;top:0px;left:0px" data-webserverurl="http://194.131.70.208/cgi-bin/js/omnisapi.dll" data-omnisserverandport="5775" data-omnislibrary="STUDIOQUIZ" data-omnisclass="jsQuiz" data-param1="" data-param2=""></div>

You can add another Omnis object to the same HTML page, but it must have a unique id, such as “omnisobject2”, and you can set its own server, library, and form parameters.

JavaScript Client Object Parameters

data-webserverurl

The data-webserverurl property identifies the HTTP URL of either the local IP address of your computer during development or the address of the Web Server and location of the web server plug-in.

When testing with the development version of Omnis, the data-webserverurl is set to “_PS_” which will be replaced with the address of the computer from which the HTML page is being served, that is, your development computer. For example, if the test HTML page is at http://127.0.0.1:5000/jschtml/test.htm, then _PS_ will be replaced with http://127.0.0.1:5000. For testing, data-omnisserverandport will be empty.

For deployment, when using a Web Server, the data-webserverurl parameter should be set to the location of the Omnis web server plug-in, such as http://www.myhost.com/scripts/omnisapi.dll, .which handles all the communication between the server and the client.

data-omnisserverandport

For development and testing data-omnisserverandport can be empty. For deployment, data-omnisserverandport tells the Omnis web server plug-in how to connect to the Omnis App Server. If the Omnis App Server is on the same machine as the web server, then data-omnisserverandport can be the port number of the Omnis App Server, e.g. it could be "5000" if the Omnis App Server is at port 5000 on the same machine as the web server. If the Omnis App Server is on a different server from the web server, then the data-omnisserverandport parameter must be “IP-Address:Port-number” of the Omnis App Server, e.g. it could be "111.222.000.111:5000" if the Omnis App Server is at port 5000 on a machine with IP address 111.222.000.111.

data-omnislibrary and data-omnisclass

The data-omnislibrary parameter identifies the library containing your remote form, and data-omnisclass is the remote form class displayed by the omnisform object.

data-commstimeout

The data-commstimeout parameter allows you to give the end user the option to timeout a request or carry on waiting. The default value of zero means that no timeout is applied, and the client will continue to wait for a response. To apply a timeout, you need to enter an integer representing the timeout in seconds. When the client sends a message to the server it must respond within this timeout period, otherwise the user will be prompted to either continue waiting for a response, or abort the request.

Managing Wifi Connections

The client should handle a wifi connection going away while processing a request at the server, so when the connection comes back, the client should respond properly. Otherwise, you have the option to provide a timeout, as above.

Additional and Custom Parameters

You can specify up to nine additional parameters (named data-param1, data-param2, ..) which can be passed into the row variable parameter pParams of the $construct() method of the remote task assigned to the remote form.

In addition to the pre-defined parameters, you can include your own custom parameters if you wish to pass extra values to the task or form $construct method. Custom parameter names should be prefixed with “data-“ and should be lowercase. The parameter will be added to the construct row variable which you can interrogate in your task or form $construct method.

Positioning the Omnis object

The position or alignment of the “omnisobject1” itself within your HTML page is where the Omnis JavaScript Client remote form will be displayed in a web browser. For mobile clients you have less control since the remote form will usually fill the entire mobile screen. By default, the JavaScript Client is displayed in the top left corner of the client browser (set using style="position:absolute;top:0px;left:0px"), but for web clients you can reposition the JavaScript Client object to appear anywhere in your HTML page using alternative style or positioning parameters.

Centering the omnisobject

By replacing the default style parameter in the div tag on the JavaScript Client object with style=”width:900px; margin:auto” will center the remote form in the browser, assuming your remote form is 900 pixels wide. Note that you cannot use the align property on the omnisobject to reposition it, therefore align="center" will not center the omnisobject.

The above technique for centering the omnisobject will be fine for web-based applications but it may not work for all mobile devices, therefore you can use the following method to center the omnisobject for all devices. You have to place two extra divs around the div containing the omnisobject and change the style parameter inside the omnisobject div, as follows:

<div id="grandparent" style="float:left; width:100%; overflow:hidden; position:relative;">
  <div id="parent" style="clear:left; float:left; position:relative; left:50%;">
    <div id="omnisobject1" style="display:block; float:left; position:relative; right:50%;" data-webserverurl="_PS_" data-omnisserverandport="" data-omnislibrary="JSLIBRARYNAME" data-omnisclass="JSREMOTEFORMNAME" data-param1="" data-param2="">
    </div>
  </div>
</div>

CSS styles and JavaScript folders

The Omnis html folder contains a number of other folders, including CSS, formscripts, icons, images, and scripts, which contain the CSS style sheets, JavaScript files, icons, and other images, which are required to run the Omnis JavaScript Client: these folders and their contents must be copied to the equivalent location in your web server relative to the HTML page containing your remote form(s).

In addition, you need to copy any icon sets used by your forms from /iconsets in your Omnis development tree to the /icons folder at the same location as the .htm file for your app; the icon set for your library will be a subfolder of /icons/iconsets.

Fav icon

The icon used for the test HTML page (displayed in the top-left of the browser tab) is the image file called 'favicon.ico' located in the html/images folder. The image file in the development version of Omnis is the Omnis logo, but for deployment you can replace this image with your own icon file.

Customizing the JavaScript Working Message

You can change the appearance and positioning of the working message displayed in the JavaScript Client when some processing is occurring. The working message is an animated GIF which is in a DIV laid over the main JavaScript Client area. You can restyle the working message overlay DIV by adding your own class in the ‘user.css’. The default style for the working message is in the omnis.css style sheet:

#omnis_overlay  {
    background:url('images/xajax-loader.gif') 20px 20px no-repeat;
}

But you can override this in user.css, for example:

#omnis_overlay {
    background-pos
}

Which will center the working image, and/or you could also add your own animated GIF.

Setting up the Omnis App Server

In order to deploy your Omnis web or mobile application, you need to download and install the Omnis App Server which will run your Omnis application (library) file. The Omnis App Server is available for Windows, macOS, or Linux computer servers. There is a Tech note also on the Omnis website called:

  1. TNJS0003: “Setting Up The Omnis App Server”

And when running on Windows, you can set the Omnis App Server up to run as a service which is described in this Tech note:

  1. TNWI0002: "Running the Omnis Application Server as a Windows Service"

You should read these tech notes for the latest information about setting up the Omnis App Server, including information about the latest version of IIS and Apache appropriate to deploying Omnis web and mobile apps.

Server Configuration

There is a JSON based configuration file in the Studio folder called ‘config.json’ which is used to configure the Omnis App Server, including setting up properties for the server itself and logging, as well as the settings for Web Services support. The config file also includes a section to enable the Java Class cache to be cleared, and other configurable items in Omnis.

The configuration of the Omnis App Server can be set up during installation or by selecting the Server Configuration option in the File menu in the Omnis App Server. Alternatively, you can configure or change the settings of the Omnis App Server by editing config.json using any compatible text editor, but the file must conform to JSON syntax.

Template Configuration File

The config.json file created in the Studio folder contains only a subset of settings needed initially for the Omnis App Server, but there are many more settings you can add to the file to enable or configure further options. There is a template ‘config.json’ file containing all possible sections and settings located in the ‘templates’ folder in the ‘Studio’ folder: you can copy sections out of this file and add them to your copy of the config.json file in the Studio folder.

Server Configuration File

The first part of the config.json file has the following layout:

{

  "server": {

    "port": 5988,

    "stacks": 20,

    "timeslice": 1,

    "webServiceURL": "",

    "webServiceConnection": "",

    "webServiceLogging": "full",

    "webServiceLogMaxRecords": 100,

    "webServiceStrictWSDL": true,

    "RESTfulURL": "",

    "RESTfulConnection": "",

    "start": false,

    "retryBind": false,

    "showBindRetryMessage": true,

    "bindAttempts": 10,

    "timeOffsetMinutes": ""

  }

}

where

  1. port, stacks, timeslice
    configure the Omnis App Server executable

  2. webService
    these parameters configure WSDL/SOAP based web services

  3. RESTful
    these parameters configure REST based web services

  4. start
    if true means Omnis automatically executes Start server at startup

  5. retryBind
    Set retryBind to false if you do not want Omnis to retry binding to the server port after its first attempt; retryBind defaults to true if it is omitted

  6. showBindRetryMessage
    If retryBind is true, showBindRetryMessage controls whether or not a working message is displayed while retrying the bind to the server port

  7. bindAttempts
    If retryBind is true, bindAttempts overrides the default number of attempts to bind to the port at 1 second intervals

  8. timeOffsetMinutes
    allows you to add an offset to the date-time setting on the Omnis App Server. Omnis adds the value of this setting to the current system date-time when generating the value for #D and #T. If the entry is not present, it defaults to zero, meaning no offset is applied

Server Logging

The Omnis App Server has a logging mechanism to support RESTful web services, if applicable. There is an external component that performs logging, located in the logcomp folder of the Studio tree, with just one component, logToFile. NOTE: you can use logToFile in the Development version of Omnis Studio to log server activity including REST calls which can be useful while testing & debugging your app.

You can configure server logging by adding a member to the config.json configuration file, with the following layout:

 

{

  "server": {

    "//": "See Server Configuration section above",

  },

  "log": {

    "logcomp":"logToFile",

    "datatolog": [

      "restrequestheaders",

      "restrequestcontent",

      "restresponseheaders",

      "restresponsecontent",

      "tracelog",

      "seqnlog",

      "soapfault",

      "soaprequesturi",

      "soaprequest",

      "soapresponse",

      "cors",

      "headlessmessage",

      "headlesserror",

      "systemevent"

    ],

    "overrideWebServicesLog":true,

    "logToFile": {

      "folder":"logs",

      "rollingcount":10

    }

  }

}

 

where

  1. logcomp
    is the name of the logging component to use, that is, "logToFile" which referencese the logtofile.dll component in the logcomp folder of the Studio tree.

  2. datatolog
    is an array that identifies the data to be written to the log - one or more ofthe values listed in the array above
    - tracelog means that data written to the trace log is also written to the new log
    - seqnlog means sequence log entries that record method execution are written to the new log instead of the old sequence log file

  3. overrideWebServicesLog
    allows you to just send SOAP web service log entries to the new log; true means just send log entries to the new log, false means send them to both the old web services log and the new log.

  4. logToFile
    is a member with the same name as the value of logcomp. This contains configuration specific to the logging component.
    - folder is the name of the folder where logs will be placed; this can be a single folder name relative to the Omnis data folder, or it can be a full path name, which must not end in a path separator character
    - rollingcount is the number of log files that will be maintained, can be up to 1024. The log component uses a new log file every hour (and a new one at startup). The log component deletes the oldest file or files so that the number of log files does not exceed this count
    - daily allows you to enable daily log file (true) or the defauly hourly log files (false).

logToFile: Folder location

The "folder" item in the “logToFile” section can be a folder name (relative to Omnis folder), or a full path name, which must not end in a path separator character, and the end folder name will be created if it does not already exist. In previous versions, you could only specify a folder relative to the Omnis folder, but now a full path can be used which can be outside the main Omnis folder. For example:

"folder": "/Users/bd/Sites/logs"

would send the log to the specified folder, while

"folder": "logs"

would still be read as relative to the main Omnis folder (note no starting or ending path separator).

You must use / as the path separator on macOS and Linux, whereas, you can use / or \ on Windows.

logToFile: Rolling count

The maximum for the “rollingcount” item in the “logToFile” can be an integer up to 1024. The logtofile component uses a new log file every hour, so the new max value would allow logs to be stored for up to six weeks, at which point the oldest logs would be deleted.

If there is an error initialising logging, the logtofile component also writes it to standard output when running on Linux.

logToFile: daily

If set to true, Omnis creates a new log file for each day. Omnis re-uses the log file for a day if it is already present at startup. The rollingcount applies as for hourly logs. The item defaults to false, which means hourly logging is used.

Log File Format

Each log record has the following layout:

  {"thread":0,"when":"20141017 14:04:14","type":"tracelog","length":127}ExternalLibrary File 'C:\dev\UnicodeRun\xcomp\damdb2.dll' failed to load. OS Error: The specified module could not be found.

where

  1. thread
    identifies the thread logging the entry,

  2. when
    is the date and time of the entry,

  3. type
    is the type of the entry (one of the datatolog values), and

  4. length
    is the length in bytes of the data following the initial JSON header.

This is followed by a final CRLF. Log files can typically be read in a text editor, but be aware that they can contain binary data if the content of RESTful requests or responses is binary.

Server Licensing

You can download the Omnis App Server installer from the Omnis website at: www.omnis.net. Having installed the Omnis App Server you will need to serialize it according to the number and type of clients you expect to serve. There are a number of different server deployment licenses for running web and mobile apps in the JavaScript Client. Please refer to www.omnis.net, or contact your local sales office for details about these Omnis App Server deployment licenses. In addition, you will need to purchase a different development license and deployment server license to create and deploy standalone mobile apps running in serverless client mode.

Licensing Mechanism

In order to enforce licensing for JavaScript Client based apps, the UUID of each client is logged with the Omnis App Server. Prior to Studio 8.1.6, the UUID was stored in a cookie in the client computer which required any clients to have cookies to be enabled for this licensing mechanism to work. However, the method for storing the client UUID has changed in version 8.1.6: the UUIDs are now stored in the ‘localStorage’ on each client which is now used to manage client licenses on the Omnis App Server. Therefore, clients no longer have to have cookies enabled for App Server Licensing to be enforced.

Setting the Omnis App Server Port Number

You can set the Omnis App Server port using the command Calculate $prefs.$serverport as 5912.

Server Multi-threading

The Omnis App Server allows multiple client requests to be processed concurrently, allowing smoother allocation of available processor time and avoiding any lengthy delays on the client: a client request might be a request from a client to execute an event, or a request from the client to call a server-side method. To handle these multiple client requests, the Omnis App Server can be made to run in multi-threaded mode. By default, the Omnis App Server runs in single-threaded mode, handling client requests in a strictly first-come, first-serve basis; in this case, client requests are queued, with each request being handled only when the previous request has completed. You can however handle multiple client requests concurrently using the Omnis Multi-threaded Server, which you can enable by executing the Start server command on the Omnis App Server: see below.

The Multi-threaded Server maintains a pool of method stacks that can process web and mobile client requests simultaneously. The pooling mechanism allows a balance to be struck between performance and server resources - the number of method stacks in the pool is configurable via the $serverstacks Omnis preference, and also available in the Omnis App Server Configuration dialog.

Multiple Method Stacks

The standard single-threaded Omnis App Server has only a single method stack to process methods. Broadly speaking, once a method call has been pushed onto the method stack no other method call can begin to execute until the first call has completed. For the majority of web and mobile client applications this is fine for processing events, particularly if some processing is performed on the client and your web server receives relatively few hits or requests for data. By contrast, the Omnis Multi-threaded Server contains a pool of method stacks which are available to process multiple client requests, and this is appropriate for more data intensive web applications where lengthy calls to a server database are required, or for web applications that receive higher volumes of traffic. When a request to execute a method is received from a web or mobile client, that method call is pushed onto any unused stack or, if there are no unused stacks, the message is queued until one becomes available. Each method stack runs in its own thread, which means that if a method stack is stalled (for example, it is waiting for the database server) the other stacks will continue to execute.

Potentially, the Multi-threaded Server may have to cope with a very large number of simultaneous clients, each with their own remote form and remote task instances. Typically though, a small proportion of clients will require the use of the server at any one time. In fact, multi-threading does not increase the server processor time available, it just allows the available processor time to be allocated in a smoother way. The method stack pool mechanism allows a balance to be struck between performance and server resources - the number of method stacks in the pool is configurable with the $root.$prefs.$serverstacks property, which is set to 5 by default.

As method stacks are allocated dynamically, it is very likely that a remote client will not get the same method stack every time it executes a method on the server. Each method stack contains its own state which, apart from during an individual method call, does not belong to any particular client. This state includes the Current Record Buffers (CRBs) for all files and variables (apart from class variables) and such modes as the current list. A client cannot rely on any properties or values of this state being preserved across different method calls. The only things belonging to the client are its instance and task variables. So a client must do such things as setting the main file and current list each time one of its methods is executed, and should not rely on such things as the values of memory-only fields being maintained across method calls. As a special case, the class variables for the remote task and remote form classes are shared amongst all clients so can be used to hold shared data (see below for the warnings about the care needed when using shared variables).

Using the Multi-threaded Server

When the Multi-threaded Server starts up, it opens the libraries, data files and SQL session pools required by the clients (see below for the description of a SQL session pool). You need to issue the Start server command to cause the method stacks and associated threads to be created. The Start server command can specify an optional stack initialization method; when specified, this method is pushed onto every client method stack and allowed to execute (so if $serverstacks is 5 it will execute five times), so it can be used to initialize the state of the method stacks. The Start server command generates a fatal error if, due to lack of resources or some other reason, it is unable to complete successfully.

When you want to stop the server, you should issue the Stop server command, but quitting the Studio program achieves the same result.

When the server is active, Omnis continues to be responsive to events on the server and could, for example, display a window with 'Start server' and 'Stop server' buttons. It is not recommended that the server program performs any substantial tasks while it is deployed and in use listening for client requests.

Any runtime errors generated by client methods are reported in the trace log (using a similar mechanism as errors during library conversion), but you can override this default behavior by making sure each client method stack has an error handler. You can use the stack initialization method call for the Start server command to define an error handler for each method stack.

Note that you cannot debug methods running in a remote form or task instance, after you have called the Start server command in a development version of Omnis.

Database Access

If you are accessing a server database in your web application, and using the Multi-threaded Server, you must use the Object DAMs (introduced in Omnis Studio 3.0) which are capable of multi-threading. Using the Object DAMs, you can connect directly to Oracle, MySQL, PostgreSQL, DB2, and Sybase, as well as most ODBC- and JDBC-compliant databases such as MS SQL Server.

The Object DAMs are implemented as external components and use object variables based on the Object DAMs, and interact with a DAM using the methods of the object. Using this approach, you create object variables of a particular DAM class. There is a group of common methods that apply to all DAM objects and a set of DAM specific methods based on the type of object. Various chapters in the Omnis Programming manual provide more information about accessing your data using the DAMs.

Omnis App Server Commands

There are some Omnis commands that you can use to control the Multi-threaded Server.

Start server

The Start server command is used to create the client method stacks and associated threads. It takes an optional stack initialization method as a parameter. The command clears the flag if it is used in a copy of Omnis which is not capable of supporting multi-threading or your serial number does not allow clients to connect. A fatal error is generated if for some other reason it is not possible to create the stacks and threads.

Stop server

The Stop server command stops the server from responding to client requests. Once the server has been started you should stop it before quitting Omnis, before using Omnis for anything apart from serving client requests (e.g. running a standard LAN-based Omnis application), or before opening or closing any Omnis data files or libraries.

The Stop server command disposes of all remote task and form instances. The resources used by the client stacks and threads are not released, but they will be reused by the next Start server command.

Begin and End critical block

These commands are used to denote a section of code which needs to execute in single threaded mode without allowing other client methods to execute. For example:

Set current list cList
Begin critical block
  Build list from file
End critical block

Here cList is a class variable which is shared amongst the clients and the critical block is used to prevent other clients from accessing the list whilst it is being built. Generally class variables should only be used when the shared functionality is essential and only with care:

Calculate cString as 'abc' ;; OK
Calculate cString as $cinst.$xyz()
; only OK inside a critical block

Simple atomic operations such as the first line of the above example are safe, but when a method call is involved it may be interrupted by other threads and cause problems. Class variables should not be used as bind variables or as the return list for SQL operations.

Yield to other threads

The Yield to other threads command is a hint that the executing thread is waiting for other threads and is prepared to yield its processor time. It can be used when waiting for semaphores (since with the Multi-threaded Server another client stack could be holding the semaphore), as follows:

Do not wait for semaphores
Repeat
  Prepare for edit
  If flag true
    Break to end of loop
  End If
  Yield to other threads
Until break

Commands which are not available to a client

The following commands are not available for methods running on the Multi-threaded Server. They usually generate a 'Command not available when executing a client method' fatal error but some (such as the Debugger… group) simply do nothing:

The Libraries… commands
The Classes… commands
Pre V30 SQL commands…
The Data management… commands
The Message boxes… commands
The Debugger… commands
Quit Omnis
Enter data
Prompted find
And all the Omnis data file and lookup commands

Any other command which would cause a dialog to be displayed on the server is not available for methods running on the Multi-threaded Server. In addition, there is a lot of notation, such as the notation for opening and closing libraries and data files, that will not work in a method running on the Multi-threaded Server.

SQL Session Pools

Suppose the Multi-threaded Server has N method stacks, and therefore N threads capable of processing methods on behalf of clients. This means that at any one time, there can be at most N SQL sessions in use. However, the Multi-threaded server may have many more than N current users. If you are using SQL, you need a potentially large number of sessions to the database server. There is nothing wrong with this in itself, and there are occasions when you might want to use database access permissions, to control the tables and columns accessible to different users. If this is the case, you require a separate session for each user. However, if all users have the same access permissions, you really only need N SQL sessions. This can significantly reduce the resource usage of the server. SQL Session Pools provide a way to do this.

A SQL Session Pool is a set of multi-threaded DAM sessions, which can be shared by clients. Typically, you would create a session pool with one session for each method stack. Details of how to use SQL Session Pools can be found in the Omnis Programming manual.

Server Load Sharing

Load sharing allows a pool of Omnis App Server processes, running on one or more machines, to serve clients. Once a client connects to an Omnis App Server process, all subsequent requests for that client need to be handled by the same Omnis App Server process, since the process contains the instance data for the client. Therefore, load sharing provides a mechanism that assigns a new client connection to an Omnis App Server process.

The data-omnisserverandport parameter in an HTML page normally has the syntax:

[(IP address|domain name):](service name|port number)

To use load sharing, you prefix this property with a name for the pool of Omnis App Server processes and a comma, for example “Omnis,6000”, or “Omnis,194.131.70.197:6000”. In this case, the address information in the property no longer addresses an Omnis App Server. Instead, it addresses a new module, a load sharing process.

When a new connection arrives at the Omnis web server plug-in, the plug-in inspects the syntax of the data-omnisserverandport parameter. If it is prefixed by a pool name, the plug-in connects to the load sharing process, and sends it a message that asks for the address of a server process in the pool. The load sharing process typically returns the address and port number of the least busy process in the pool. The plug-in then connects to this process, and sends the web or mobile client connection to it. When the plug-in responds to the client, it includes the address of the Omnis App Server process in the response.

When the client sends subsequent messages to the web server for this web or mobile client connection, it sends the address passed in the connect response instead of the data-omnisserverandport parameter. Thus the only additional overhead imposed by load sharing occurs during connection setup.

So how does Omnis know (1.) which Omnis App Server processes exist, and (2.) which Omnis App Server process is the least busy? The load sharing process (LSP) has a .ini file, which contains the pool names for the pools for which it is responsible, and for each pool, the addresses of the Omnis App Server processes in the pool. Periodically, the load sharing process polls each Omnis App Server process, and asks it for the percentage of web or mobile client connections currently in use (using the serial number as the maximum), and information about how much time the server has spent processing requests. The load sharing process combines this information to determine which process is the least busy.

You can configure the time interval between polls of each Omnis App Server process via the .ini file. Once every 10 or 20 seconds is usually frequent enough.

Enabling Load Sharing

To enable the load sharing process you need place the LSP program on your web server, or a machine connected to your web server. It is a single executable called Omnislsp.exe (Windows) or omnislsp (Linux and macOS). A configuration file (omnislsp.ini) must be made to accompany the Omnislsp program, and this takes the following format:

[Setup]
Port=6001
QuietMode=0
BucketSize=100
LogLineThreshold=16
Pool1=Omnis
[Omnis]
PollTimer=10
Server1=123.145.71.123:7001
Server2=123.145.71.124:7002

The commands for the lsp are:

  omnislsp –start

  omnislsp -stop

(with the omnislsp.ini in the same directory as the program)

The Port entry in the .ini file identifies the TCP/IP port number on which the LSP listens for requests from the Omnis web server plug-in.

The QuietMode entry in the .ini file indicates if the LSP generates OK messages, or messages to the console, to report its status. When set to zero, it will generate messages. When set to one, it will not.

The LogLineThreshold entry in the .ini file indicates when the text log generated by the LSP will be reduced in size. If the LSP writes a line to the log, and the file contains LogLineThreshold lines, it will reduce the file size to LogLineThreshold/2 lines, maintaining the most recently written lines, before writing the line to the log. The log is in the same directory as the omnislsp program.

The BucketSize entry specifies how the LSP breaks up the server processes into groups, based on how busy they are. It is a value in milliseconds. The LSP divides the processes into 10 buckets, based on the average time to process a request obtained from the information it gathers by polling the server processes periodically. The buckets are numbered 1-10, where 1 contains the least busy servers, and 10 the most busy servers. A server is in the smallest numbered bucket, for which its average time to process a request is less than or equal to (bucket number)*BucketSize. If a server is so busy that this calculation does not allocate it to a bucket, it belongs to bucket 10. You may need to experiment with possible settings for BucketSize, in order to determine the optimum setting for your application.

Each pool has its own section in the .ini file. The PollTimer entry indicates the frequency in seconds at which the LSP polls the server processes in the pool for information. The ServerN entries identify the TCP/IP address and port of each server process in the pool.

You also need to edit the 'data-omnisserverandport' parameter in your HTML file containing the JavaScript Client plug-in, for example:

  data-omnisserverandport="Omnis,6001" or
  data-omnisserverandport="Omnis,123.456.789.010:6001"

where Omnis is the name of a pool of Omnis App Server processes and 6001 is the port number of the LSP.

On the LSP servers

The Omnis App Servers may be stopped and restarted without the need to stop the LSP.

Load Sharing Mechanism

The load sharing process periodically polls the processes in a pool of Omnis App Server processes. Each server returns the current number of connections to the server, the maximum number of concurrent connections allowed to the server (specified by the serial number), the number of requests since the last poll, and the total elapsed time in milliseconds taken to process the requests. The load sharing process organizes the servers into buckets, based on the results of the information returned from polling the servers.

When a connection request arrives at the load sharing process, it allocates a server to the request as follows. It traverses the buckets, starting with that for the least busy servers, looking for a server that has some free connections. Within a bucket, it looks for the server with the smallest percentage of connections in use, using the results of the last poll. If there is more than one server with the same smallest percentage of connections in use, the process allocates the connection to the server to which it least recently allocated a connection. At this point, the load sharing process also updates the connection statistics from the last poll, to reflect the new connection. The traversal stops when a free process has been found. If all servers are fully utilized, the LSP allocates the connection to a server at random; in this case, it is likely that the server will reject the request, and return a suitable error to the client.

Installing as a Service (Windows only)

The omnislsp process can be installed as a service which starts-up automatically when Windows loads. For this purpose, two additional parameters are supported:

omnislsp –install    Creates and starts the “Omnis Load Sharing Process” service.
omnislsp –uninstall  Stops and removes the service.

The startup-type for the new service is set to “Automatic” and the service uses the omnislsp executable and .ini file at their current locations. When omnislsp runs as a service, dialog boxes are disabled and messages are written to the application event log instead.

Socket Binding

For the development version, Omnis will retry the bind 5 times, once a second, and then report an error via the trace log; this behavior is the same as previous versions. The Omnis App Server will retry indefinitely once a second.

When running as a Service, after a few bind attempts, Omnis outputs a message to the system event log (if the event log is being used for Studio), “Failed to bind web client socket - will retry indefinitely”. If the bind is eventually successful, Omnis outputs a second message, “Successful bind of web client socket”.

Note that you can stop the service while the indefinite retries are occurring, but you cannot use the tray to bring Omnis to the front (or do anything else with the Studio service) as the web client bind occurs quite early in the initialization of Studio.

The Omnis App Server displays a working message while the retries are occurring; this allows the end-user to cancel the retry loop.

Managing Server Timeouts

You can manage what is displayed in the end user’s browser when the Omnis Server responds with a Server error or Disconnected message. You can create a client-executed remote form method named $ondisconnected which will be called when there is an error on the server or the client is disconnected.

The method has a single parameter which provides the error text. This is only populated if it was triggered by a server error, rather than a disconnect due to Remote Task timeout etc. If you wish to prevent the default behavior, you must return kTrue from this method.

The form which initiated the server request will be queried for the method first. If it is not found, or it does not return kTrue, any parent forms (if it is a subform) will be tried.

Setting Up Your Web Server

In addition to the Omnis App Server, you need to install and configure a standard web server, such as Microsoft IIS, Apache, or Tomcat. You should download a suitable web server from the appropriate vendor. You need to install the appropriate Omnis Web Server plug-in in the correct location on your web server, for example, in the /cgi-bin, /scripts, or /webapps folder. A different plug-in is available for each of the most common web servers.

Installing the Web Server Plug-in

Apache Server Plug-in

The Apache module for Linux is called mod_omnis.so and is located in the clientserver\server folder in the main Omnis tree. The Apache module works with Red Hat and other Linux distributions. This module is faster than the nph-omniscgi server extension.

Two versions of the Apache web server plug-in are provided in the clientserver\server folder, under the main Omnis folder, to support Version 2 and Version 2.2 Apache web servers.

To install the Apache module

  1. Copy mod_omnis.so to the Apache modules directory, e.g. on RedHat 9.x this is /etc/httpd/modules

  2. Add the following lines at the end of access.conf:

    <Location /omnis_apache>
      SetHandler omnis-apache
    </Location>
  1. Add the following lines to httpd.conf, at the end of each block of similar directives:

    LoadModule omnis_module modules/mod_omnis.so
    AddModule mod_omnis.cpp

You need to restart httpd (restarting the system is the simplest way to do this). After installing the Apache module, you can address it using /omnis_apache in the data-webserverurl parameter in the JavaScript Client object.

Installing the Java Servlet

NOTE: From Studio 10.x onwards the JavaServlet is no longer provided in the Omnis tree due to a change in licensing for Java: see the Readme for more details about Java Legacy Integration.
Omnis Studio includes a Java Servlet web server plug-in that allows you to run your Omnis web applications with any web server that supports version 2.3 of the Servlet API. Web servers that comply with Java Servlet API 2.3 include the Apache TomCat and Jetty web servers, but there are several others. For more information about Java Servlets, see: http://www.oracle.com/technetwork/java

The Java Servlet allows Omnis remote forms to connect to an Omnis App Server via a Java web server. In this respect, the Servlet is the Java equivalent of the ISAPI, CGI or the regular Apache plug-in available in Omnis Studio.

The Java Servlet is called RdtaServlet and can be found in the Omnis Studio installed tree in the clientserver\server\omnisservlet folder. Inside the Servlet folder, the servlet files are in the following folder structure:

Servlet
|
 - WEB-INF
   |
    - rdtaserv.dll (Platform dependant)
      |
       - web.xml
         |
          - classes
            |
             - com
               |
                - rdta
                  |
                   - RdtaServ.class

To install the servlet on your web server, such as the Apache Tomcat server, you should place the whole servlet folder in the Webapps folder within the Tomcat installation. If you wish, you can rename the servlet folder.

You will need to restart the webserver in order for the servlet to be loaded.

Web server parameters for the Java Servlet

The data-webserverurl parameter in your HTML containing your remote form must have the correct format to access a web server with the Java Servlet.

  1. data-webserverurl
    this must be the URL to the tomcat webserver appended with the name and path of the servlet, such as "http://www.mydomain.com/servlet/%servletname%"

Note if you have renamed the servlet folder you should use the new name in the data-webserverurl parameter instead of ‘servlet’;

The default value for %servletname% is 'rdtaservlet'. You can modify this or add others by modifying the web.xml file. The following xml can be added to the <web-app> element in the document to add a new servlet alias name. For example

  <servlet-mapping>
    <servlet-name>RdtaServ</servlet-name>
    <url-pattern>/%servletname%</url-pattern>
  </servlet-mapping>

ISP Web Hosting

If your web site is hosted by a third-party, such as an ISP, they will need to place the Omnis web server plug-in in their cgi-bin folder, and furthermore they need to provide you with a direct connection to the Internet. Your ISP may want to test the web server plug-in, usually the case for any files you place in their cgi-bin folder.

If your Omnis web application uses a web site hosted by an ISP you will need to adjust your port settings in the Omnis App Server and HTML files. In this case you can use DomainName:Port or IPAddress:Port in your port setting.

Secure Sockets

You can use secure sockets (HTTPS) if you have installed an SSL certificate on your web server. The JavaScript Client will use a secure connection to connect the client to the web server if you prefix the URL or IP_address in the data-webserverurl parameter with “https://”, for example:

https://remainderOfFullURL

In addition, remote tasks have the $issecure property that lets you turn secure mode on and off dynamically, by assigning to the property at runtime in your application.

Secure socket connections do not support the "address:port" format for the data-webserverurl parameter of a JavaScript Client object.

Web Server Plug-in Custom Configuration

You can configure the Web Server plug-in via a separate configuration file, allowing greater security and control over user access to your Omnis web or mobile application. It is not necessary to configure the web server plug-in in most circumstances, but this functionality provides added flexibility and security. The parameters specified in your configuration file can provide default connections for clients, simplifying the post command required to connect to the Omnis App Server. The configuration file should be placed in the same directory as your Web Server plug-in.

  1. Access and Security
    Using the web server plug-in configuration file you can restrict access to an Omnis App Server

  2. Configure Server parameters
    The configuration file allows you to override parameters for the Omnis App Server, or in effect, provide default parameters if the oserver parameter is blank in your cgi parameters in your html; in this case the value would be taken from the configuration file.

  3. Post content to Remote tasks
    the configuration file allows you to pass HTTP Post content to the Omnis remote task.

Server plug-in activation

The new functionality in the Omnis Web Server plug-in is built into the plug-ins supplied with the Omnis App Server installation, but you have to rename plug-in itself to activate the new functionality.

mod_omnis.so

If you are using mod_omnis.so under Linux or Windows, you need to change the value of the location in your http.conf or equivalent apache configuration script to /omnis_apacheini, for example:

<location /omnis_apacheini>

SetHandler omnis-apache

</location>

nph-omniscgi

Rename the nph-omniscgi.exe to nph-omniscgiini.exe for Windows, or rename nph-omniscgi to nph-omniscgiini for Linux.

omnisapi.dll

For Windows IIS based servers, rename omnisapi.dll to omnisapiini.dll.

rdtaserv.dll

If you are using the Web Services enabled Web Server plug-in, rename rdtaserver.dll to rdtaserverini.dll.

Creating a Configur ation file

The configuration file should be named omnissrv.ini and be placed in the same directory as your Web Server plug-in, for both Windows and Linux.

The format of the configuration file mirrors that of a Windows .ini file and is defined as follows:

  1. Section names are contained in square brackets e.g. [SectionName].

  2. A section ends when another section begins or at End Of File (EOF).

  3. Comments are lines beginning with a semicolon (‘;’).

  4. All text following a comment is ignored until the line is terminated.

  5. Keys are of the form keyname=value where keyname is a unique identifier within the section and value is the value of the specified key.

  6. Section names, key names and key values must not contain white space.

  7. Section names and key names are case sensitive.

The new functionality in the Web Server plug-in is controlled using specific named sections in the configuration file. The omnissrv.ini file can contain the AllowConnectionsTo section which controls access to the Omnis App Server. The .ini file can also include either a DefaultConnection or OverrideConnection section (but not both), which either provide default parameters for the Omnis App Server or override parameters posted to the Omnis App Server from the http web server.

Controlling Server Access

You can control access to your Omnis App Server by including the [AllowConnectionsTo] section in the configuration file. This section contains a list of key names of the form address<n> where n is a sequentially numbered character starting at 1. When this section is present, connections to Omnis App Servers are limited to those defined in the specified key values. In the event that the oserver parameter is defined as a port number, only the port number is required.

For example, in the following AllowConnectionsTo section connections are limited to Omnis App Servers running on the local machine on port 5920 and the remote machine 192.168.0.2 on port 5920.

[AllowConnectionsTo]

address1=5920

address2=192.168.0.2:5920

Note that the local IP address in the configuration file cannot be resolved. Imagine the server plug-in and the Omnis App Server are on the same machine, with an IP address of 192.168.0.3. If the incoming request was of the form data- OmnisServer=5920, the configuration file has to match this form. So if you want to allow only connections to port 5920, you would have to add this line to the [AllowConnectionsTo] section: address1=5920. If you use the expanded form of the address, i.e. address=192.168.0.3:5920, the server plug-in would deny the request. In the event of a denial of service the plug-in returns a HTTP 403 error with the following message ‘Access to the resource has been denied’.

Default Connections

You can provide default connection parameters in the [DefaultConnection] section of the configuration file. This section provides a means of adding missing values into an HTTP post, or in effect, providing a complete set of default parameters if none are provided in the HTTP post. When they are present in the HTTP request, the values in DefaultConnection are ignored and the values are taken from the original request. The DefaultConnection section can contain the following keys:

  1. OmnisServer

  2. OmnisClass

  3. OmnisLibrary

  4. PostDataParamName

  5. Any number of additional parameter pairs in the form Parameter Name=value

The OmnisServer, OmnisClass and OmnisLibrary mirror the operation of the identically named remote form parameters. The value of the PostDataParamName key specifies a variable name for all the content of the HTTP post. All other keys are assumed to be parameters. They are passed to the Omnis remote task and appear as columns in the row variable. The column name is the key name and the value matches the value of the key. One thing to note, if the parameter is present in the original request and the configuration file also contains a definition for the parameter, the value is always taken from the request even if the parameter has no associated value. For example:

[DefaultConnection]

OmnisServer=192.168.0.1:5920

OmnisClass=remoteTask

OmnisLibrary=TEST

param1=value1

param2=value2

PostDataParamName=PostData

In the context of the above DefaultConnection section, consider the following URL which attempts to connect to Omnis:

/omnis_apacheini?OmnisClass=remoteTask&param1=1234

The OmnisClass and param1 values are taken from the URL while the other values are taken from the DefaultConnection section. In this case, no OmnisServer and OmnisLibrary parameters are provided in the query string, so those values are taken from the configuration file. Therefore the plug-in will amend the query string to:

/omnis_apacheini?OmnisClass=remoteTask&OmnisServer=192.168.0.1:5920&
OmnisLibrary=TEST&param1=1234&param2=value2&PostData=

Note PostData is empty as the content-type is application/x-www-form-urlencoded, so in this case the data is not passed to Omnis.

Overriding Connections

You can override the server parameters passed to the Omnis App Server by an HTTP post by including a [OverrideConnection] section in your configuration file. In this case, all the values in the request are ignored, and the Omnis App Server uses values from the configuration file. The OverrideConnection section may contain the following keys with associated values:

  1. OmnisServer

  2. OmnisClass

  3. OmnisLibrary

  4. PostDataParamName

  5. Any number of additional Parameter Name=value

These keys function exactly as described in the DefaultConnection section. An example OverrideConnection section is as follows:

[OverrideConnection]

OmnisServer=192.168.0.1:5920

OmnisClass=rtTest

OmnisLibrary=TEST

param1=value1

param2=value2

PostDataParamName=PostData

In the context of the above OverrideConnection section, consider the following URL which attempts to connect to Omnis:

/omnis_apacheini?OmnisClass=remoteTask&param1=1234

In this case, the values in OmnisClass and param1 submitted in the post are ignored, and all the values for the post are taken from the DefaultConnection section in the configuration file. Therefore the query string is amended to:

/omnis_apacheini?OmnisClass=rtTest&OmnisServer=192.168.0.1:5920&
OmnisLibrary=TEST&param1=value1&param2=value2&PostData=

Note PostData is empty as the content-type is application/x-www-form-urlencoded, so in this case the data is not passed to Omnis.

Creating Standalone Mobile Apps

In addition to using the JavaScript Client in the web browser on any computer or mobile device, you can embed your JavaScript Client based remote forms into a Standalone app or “wrapper”, which you can deploy to end users as a self-contained app which they can install onto a mobile device. To create a standalone app, we provide a JavaScript Wrapper Application for each supported mobile platform, which currently includes Android, iOS, and Windows. The wrapper applications create a thin layer around a simple Web Viewer which can load the initial JavaScript remote form for your mobile application.

The wrapper applications allow you to deploy mobile apps that end users can run either in Offline or “serverless mode”, without any connection to the Omnis App Server, or in Online mode which would allow end users to connect to the Omnis App Server to synchronize their data and update the application content.

image1

  1. Offline or Serverless mode
    end users can run your app in standalone or “offline” mode without ever connecting to the Omnis App Server or a database server. The Application Files (remote form definitions, scripts, etc) are bundled with the wrapper app to create a single, clickable application file; this allows complete “offline” operation, or a one-off connection can be made to the Omnis App Server to install the applications files and from there on a connection to the Omnis App Server would not be needed

  2. Optional connection
    end users have the option to switch to “online” to synchronize the database and app content via the Omnis App Server; this mode would suit end users who have an intermittent connection, but often need to synchronize their data with a central location

Wrapper Application Source Files

The projects and source code for the wrapper applications are available to download from the Omnis website: www.omnis.net/download/jswrapper.jsp

The ZIP files contain template configuration files, together with the project and source files so you can build your standalone app or customize the wrappers if required.

There is a separate manual called ‘Building The [iOS / Android / Windows] Wrapper’ available on the Omnis website about using and customizing the wrapper applications for mobile app deployment: this manual contains all the latest information for each of the supported mobile platforms and will be updated regularly to keep abreast of any changes in the build process.

Configuring the Wrapper Application

The wrapper applications can be configured to run a single JavaScript remote form as the entry point to the app, which can be configured in a configuration file called config.xml.

Configuration file

The config.xml file contains the URL for the page containing your JavaScript remote form and depending on the platform, may contain a number of other parameters specific to your platform. The config.xml is standardized for all platforms, and is based on the following structure:

<?xml version="1.0" encoding="utf-8" ?>
<settings>
  <AppTitle>0</AppTitle>
  <AppStandardMenu>1</AppStandardMenu>
  <AppTimeout>300000</AppTimeout>
  <SettingsFloatControls>0</SettingsFloatControls>
  <SettingsScaleForm>1</SettingsScaleForm>
  <SettingsAllowHScroll>0</SettingsAllowHScroll>
  <SettingsAllowVScroll>0</SettingsAllowVScroll>
  <SettingsMaintainAspectRatio>0</SettingsMaintainAspectRatio>
  <SettingsOnlineMode>1</SettingsOnlineMode>
  <ServerOmnisWebUrl>http://172.19.250.25:5911</ServerOmnisWebUrl>
  <ServerOnlineFormName>/jschtml/rfOnline</ServerOnlineFormName>
  <ServerOmnisServer></ServerOmnisServer>
  <ServerOmnisPlugin></ServerOmnisPlugin>
  <ServerOfflineFormName>rfOffline</ServerOfflineFormName>
  <ServerAppScafName>mylib</ServerAppScafName>
  <TestModeEnabled>0</TestModeEnabled>
  <TestModeServerAndPort>172.19.250.25:5911</TestModeServerAndPort>
</settings>

The config.xml contains the following properties (note that some may not be included on a particular platform):

  1. AppTitle
    whether or not the app displays a title bar at the top. Note that hiding the title on Android 3 will hide the ActionBar which will remove access the testing menu

  2. AppStandardMenu
    whether or not the standard menu is displayed at the top.

  3. AppTimeout
    the time in milliseconds after which the app will close after being sent to the background.

For all platforms:

  1. MenuIncludeSettings
    whether the “Settings” menu option is available in the app.

  2. MenuIncludeOffline
    whether the runtime menu option is available to switch to offline mode.

  3. MenuIncludeAbout
    whether the “About” menu option is available in the app.

The following settings control the scaling of the app (remote form) on the device:

  1. SettingsFloatControls
    when SettingsScaleForm is "0" (false), the client uses the $edgefloat property of each JavaScript Client control on the form. When applying the screen size, the client uses $edgefloat to float the edges of controls (note that the component values are not supported, just the edge-related values). If the form is wider or taller than the screen, floating only occurs if the relevant SettingsAllowHScroll or SettingsAllowVScroll parameter is false. The amount by which the controls float is the difference between the actual screen width or height and the designed width or height of the form for the closest matching layout breakpoint. The value of $edgefloat is stored for each layout brealpoint

  2. SettingsScaleForm
    If you set this to "1" (true), the client scales the form to fit the available screen space. The scaling factor is the screen width or height divided by the value of the closest matching layout breakpoint. For these purposes, the actual screen size excludes the operating system areas such as the status bar

  3. SettingsAllowHScroll and SettingsAllowVScroll
    set these to "1" if you want to allow horizontal or vertical scrolling of the form respectively, or "0" if not

  4. SettingsMaintainAspectRatio
    If you set this to "1", scaling maintains the aspect ratio of the form. When turned on, and depending on SettingsAllowHScroll and SettingsAllowVScroll, it may reduce the scaling factor in one direction, to make the form fit, and center the form vertically or horizontally as required

  5. SettingsOnlineMode
    whether the app starts in Online mode.

The following settings relate to the Omnis App Server:

  1. ServerOmnisWebUrl
    URL to the Omnis App Server or Web Server. If using the Omnis App Server it should be http://<ipaddress>:<omnis port>. If using a web server it should be a URL to the root of your Web server. http://myserver.com

  2. ServerOnlineFormName
    route to the form’s .htm file from ServerOmnisWebUrl. So if you’re using the built in Omnis server, it will be of the form /jschtml/myform.htm. If you are using a web server, it will be the remainder of the URL to get to the form, e.g. /omnisapps/myform. (Do not add the .htm extension!)

Only ServerOmnisWebUrl & ServerOnlineFormName are needed for Online forms. The other Server… properties are for Offline mode.

  1. ServerOmnisServer
    The Omnis App Server <IP Address>:<Port>.

  2. ServerOmnisPlugin
    If you are using a web server plug-in to talk to Omnis, the route to this from ServerOmnisWebUrl. E.g. /cgi-bin/omnisapi.dll

  3. ServerOfflineFormName
    Name of the offline form. (Do not add .htm extension!)

  4. ServerAppScafName
    Name of the App Scaf. This will be the same as your library name.

The remaining parameters refer to test mode.

  1. TestModeEnabled
    whether the app will start in test mode (Ctrl-M on form from Studio to test on device)

  2. TestModeServerAndPort
    the <ipaddress>:<port> of the Omnis Studio Dev version you wish to use test mode with.

You can also change these parameters by pressing the menu button on the mobile device, and using the menu options to change them. The app remembers the last setting made via the menu, so the config.xml lets you set the initial values in the wrapper application.

Access Permission Requests

When you deploy your app and the end user downloads it, the app must request permissions to access various areas of the device, for example, the app must request access to the device Contacts, Camera, or Location (GPS) if this functionality is required in your app.

It is considered bad practice and potentially confusing for the end user to include unnecessary permissions for your app, especially if you are distributing your app through one of the online app stores. When downloading/installing your app, the user can see which permissions your app has requested access to, so any unnecessary permission requests may give the user the impression that your app is malicious and they may not download and use your app.

Testing Remote Forms in a Wrapper App

During development, you can open a JavaScript remote form in a wrapper application using the Test Form Mobile (Ctrl-M) option, assuming a wrapper application is setup and enabled (otherwise you can still test your mobile forms in a desktop browser on your development computer before you setup the wrapper app). This option appears beneath the ‘Test Form’ option in the remote form context menu. The Test Form Mobile option is only displayed in the relevant menus when both:

  1. A wrapper application is enabled for test form (see the menu of the Android app, and the system settings for the iOS app)

  2. A wrapper application is connected to the Omnis App Server, using the test form parameters.

The $designshowmobiletitle property determines whether or not the title of a wrapper application is visible when you use the Test Form Mobile (Ctrl-M) option. For deployment, config.xml allows you to configure whether or not the title is displayed in the wrapper application.

The JavaScript Serverless Client

PLEASE NOTE: you will require a new alternative Development license to enable the $serverlessclient property in a remote form: the property will remain grayed out without this alternative license.
(Also note that previous versions of the Serverless Client provided local database support using UltraLite and a MobiLink server from Sybase but this setup is no longer supported.)

You can switch a remote form to operate in “Serverless Client” mode in which case your mobile app can operate entirely without a connection to the Omnis App Server. In order for a remote form to be available in Serverless or offline mode, you must set its $serverlessclient property to kTrue.

Any mobile app containing remote forms in serverless client mode has the ability to switch between “offline” and “online” modes at the user’s request. Separate forms can be used for the same app in offline/online modes to provide different functionality.

The Serverless Client also includes Local Database support, utilising a SQLite database, and even provides the ability for your offline form to synchronize an end user’s local database with an online database. This means that a user could switch to offline mode while in areas of no or patchy network coverage to continue working, and then switch back to online mode when back in the office.

How does it work?

The Serverless Client has provision for a local client-side database. This can be used as a local database for the standalone mode for your app, or it can be used to synchronize with an online “Consolidated Database” (CDB). In the latter case, the local database is used for storing tables held in the server-side database and for caching SQL transactions performed whilst the Omnis App Server is not available.

image2

JavaScript Serverless Client allows forms to work in ‘offline’ mode

The client-side database can be SQLite and the synchronization of the local database with a “consolidated database” administered by the SQLite Synchronization Server provided by Omnis Software.

You can download the ‘SQLite Synchronization Server’ manual from the Omnis website: www.omnis.net/download

Serverless Client Methods

All methods running in a Remote form in serverless client mode must be set to ‘Execute on Client’ (right click the method name in the method editor and select ‘Execute on Client’). From Studio 10.0.1 onwards the default execution type for new methods added to a serverless client remote form is client-executed.

Initialization and Termination Methods

The $construct() and $destruct() methods in a remote form cannot be executed as client methods, therefore you can create methods with the names $init() and $term() which perform a similar function that can be executed on the client. The $init() and $term() methods can be used in standalone apps running inside the JavaScript Client wrapper application in which all methods must be executed on the client.

The $init() method is called after the form and the client script files have been loaded. This allows you to do any final initialization of the remote form. The $term() method is called when a remote form instance destructs.

You can use $cinst.$layouttype in client methods, including $init(), to get the current layout breakpoint of the remote form on the client (you can use $cinst.$screensize for the old $screensize based forms).

Remote Task Instances

The Application Wrappers send a unique device ID when connecting to the Omnis App Server. Omnis checks whether there is already a remote task instance with the same device ID and form name in the current library, and if it finds one, it will close it before opening a new task instance. This means that wrappers will not free the remote task connection when they timeout (as you cannot trap this event), but when the app is re-opened, it will close the old task before opening a new one.

Serverless Client Application File (SCAF)

The Serverless Client Application File (SCAF) is a SQLite database that contains all of the resources necessary for a mobile application to run locally in the wrapper in standalone mode. These resources include JavaScript scripts, CSS files, image files and Omnis remote forms. There are two SCAF files needed for each wrapper application:

  1. Omnis SCAF (omnis.db)
    files needed to run the JavaScript Client

  2. Application SCAF (<library_name>.db)
    contains all your application files

Omnis Studio will generate these SCAF files automatically in the ‘/html/sc’ folder under the main Omnis folder. These files need to be placed on the Omnis App Server in the same location for end users (mobile clients) to access if necessary (see below).

Whenever you save a remote form which has $serverlessclient set to kTrue, it will update the application files in your Omnis folder. A message is displayed while Omnis exports all the necessary files.

Updating the SCAF

When you make changes to CSS files or scripts you must update the SCAF to ensure your app is built using an up-to-date SCAF. You can update the SCAF in the Studio Browser by clicking on the ‘Omnis Studio’ node and selecting the ‘Update Omnis SCAF’ option. For example, the SCAF needs to be updated after the ‘user.css’ has been changed to ensure the omnis.scaf contains the updated style sheet. Quitting and restarting Omnis Studio also updates the SCAF.

Deployment of SCAF Files

When the wrapper application is executed for the first time in offline mode it will check if any SCAF files are bundled with the application (see the wrapper building section for info on how to do this). If these files exist, they are copied into the application space on the device and used in the wrapper. Note that bundling SCAF files with the application will increase the size of the application bundle.

If SCAF files are not distributed with the application the application will attempt to connect to the Omnis App Server on startup and download the latest versions of the SCAF files.

For the application to know which application SCAF to use the option: <APPSCAF>name</APPSCAF> (where name is the name of the Omnis library)
is used in the config.xml file within the wrapper application.

Updating SCAF Files

Once the app has been installed onto a device, it will add an entry to the ‘Settings’ app of the device, with the same name as your app.

image3  image4

The wrapper configuration sub menu “Update Omnis Software Package” contains options for updating the SCAF files. The available options are:

  1. Never
    the SCAF will never be updated

  2. Always On Startup
    will attempt to connect to the Omnis App Server and update the SCAF files every time the application is run

  3. Next Startup Only
    will attempt this update only on the next execution of the wrapper application

It is also possible for the end-user to update the SCAF from inside the app by swiping down the screen to open the runtime menu and selecting the appropriate menu item.

Database Support

The JavaScript wrapper application contains embedded support for SQLite and provides client-executed methods with access to a local private SQL database. The database can currently only be used by Serverless Client applications in offline mode, inside the wrapper application on Android and iOS.

All interactions between the JavaScript Client and the wrapper will be asynchronous, so the database API also takes this into account.

Schema and Query Classes

The JavaScript Client-executed method code generator restricts the $definefromsqlclass() method for use with either a query or a schema class name as the first argument although it is still possible to pass a subset of column names required using parameter two onwards. This will allow for example:

Do list.$definefromsqlclass('SchemaName')

and the code generator will expand this into JavaScript to define the list or row with the columns from the schema.

Data Types

When creating rows to be used for bind variables, it is important that the data types of the columns in the row match those in the database.

Client methods only provide a ‘var’ data type when creating variables, which will generally be interpreted as Character type. As such, it is safest to manually add columns to your row, using the function:

Do lRow.$cols.$add(<name>,<data type>,<data subtype>,[<length>])

e.g.:

Do lRow.$cols.$add('Age',kInteger,kShortint)

The SQL Object

A Serverless Client application gains access to the embedded database using a SQL Object, which in this case is a property of the current remote form called $sqlobject:

$cinst.$sqlobject

For example:

Calculate oVar as $cinst.$sqlobject

All requests to the SQL object are asynchronous (except $getlasterrortext and $getlasterrorcode), and call a client-executed completion method ($sqldone) in the current remote form instance upon completion. Each request returns an identifier when called and the same identifier is passed as a parameter to the completion method, allowing the request to be identified. Thus, multiple requests may be in progress “simultaneously”, although they will only execute serially in the wrapper.

Note that you do not need to provide a $sqldone() method although if you do not, errors may be ignored. On success, the returned unique identifier is positive. A negative value indicates an error code.

In the following sections, oSQL is a Var containing the SQL object returned by $cinst.$sqlobject.

$getlasterrortext()

Do oSQL.$getlasterrortext() Returns lErrText

Returns the error text of the last operation. “OK” implies success.

$getlasterrorcode()

Do oSQL.$getlasterrorcode() Returns lErrCode

Returns the error code of the last operation. 0 implies success.

$selectfetch()

Do oSQL.$selectfetch(cSQLlBindVarsiFetchCapReturns id

Executes a statement with a result set (typically select or select distinct) and fetches the initial set of rows.

  1. cSQL
    is the statement. This may be hand-coded, or the result of $select/$selectdistinct for a schema or query class. cSQL can contain bind variable place-holders in the form @[column_name], where column_name is the name of a column in lBindVars.

  2. lBindVars
    is a row variable referenced by one or more bind variable markers in the SQL text.

  3. iFetchCap
    is the number of rows to initially fetch (this can be kFetchAll to fetch all rows in the result set).

For all object methods, note that lBindVars may contain columns not referenced by the SQL text. Only those columns referred to by name in the bind place holders will be read.
On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned by $selectfetch)

  2. A list containing zero or more rows from the initial result set.

At this point it is your responsibility to copy or populate the appropriate form controls to display the data.

Example1:

Do iList.$definefromsqlclass('myQuery')
Do oSQL.$selectfetch($clib.$queries.myQuery.$selectiList, 100) Returns id

Example2:

Do oSQL.$selectfetch('select * from Table1 where age=@[age]'lBindVars,100) Returns id

$fetch()

Do oSQL.$fetch(selectfetchid, iFetchCapReturns id

Fetches more rows from the result set generated by the last $selectfetch() executed.

  1. selectfetchid is the id returned by $selectfetch() and passed to $fetch(); a new ID is returned.

  2. iFetchCap is the number of rows to fetch.

In this case, the id returned by the call to $fetch() is a new ID. On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned by $selectfetch)

  2. A list containing zero or more further rows from the result set.

$insert()

Do oSQL.$insert(cSQLlistReturns id

Inserts one or more rows into a database table.

  1. cSQL is the insert statement. This may be hand-coded, or the result of $insert for a schema class. cSQL can contain bind variable place-holders in the form @[$column_name], where column_name is the name of a column in listorrow.

  2. listorrow is the list or row containing the data to insert.

On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned from $insert()).

Example:

Do oSql.$insert("INSERT INTO Product (name, quantity) VALUES (@[colName],@[colQuant])",lBindVarsReturns IDinsert

$delete()

Do oSQL.$delete(cSQLrowReturns id

Deletes zero or more rows from a database table.

  1. cSQL is the delete statement. This may be hand-coded, or the result of $delete() for a schema class. cSQL can contain bind variable place-holders in the form @[column_name], where column_name is the name of a column in row.

  2. row contains the values referenced by the bind variable place-holders.

On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned from $delete()).

$update()

Do oSQL.$update(cSQL, newRow, oldRow) Returns id

Updates zero or more rows of a database table.

  1. cSQL is the update statement. This may be hand-coded, or the result of $update for a schema class. cSQL can contain bind variable place-holders in the form @[$column_name], where column_name is the name of a column in newRow or oldRow. If the bind variable is used in the SET clause, it will come from the newRow variable, if it is used in the WHERE clause, it will come from the oldRow variable.

  2. newRow is the row containing the values referenced by the bind variable place-holders of the new values, i.e. those specified in the SET clause.

  3. oldRow is the row containing the values referenced by the bind variable place-holders of the old values, i.e. those specified in the WHERE clause.

On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned from $update()).

$execute()

Do oSQL.$execute(cSQLReturns id

Executes a SQL statement that does not return a result set, intended for use with DDL administrative commands such as CREATE, DROP and ALTER.

  1. cSQL is the SQL statement to be executed. Note that bind variable place holders are not supported.

On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned from $execute()).

The following methods may be used to obtain database meta-data:

$selecttables()

Do oSQL.$selecttables() Returns id

Retrieves table names defined in the local database.

On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned from $selecttables()).

  2. Single-column list containing the TableName of each table in the local database.

$selectcolumns()

Do oSQL.$selectcolumns(tableNameReturns id

Retrieves column names and type information for the specified table.

On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned from $selectcolumns ()).

  2. A list describing the table column definitions, defined with the following columns:
    ColumnName - name of the table column.
    SqlType - name corresponding to the column’s SQL data type.
    ColumnSize - the size of a variable-length data type, e.g. for CHAR and BINARY.
    Precision - the numeric precision for a NUMERIC column. Zero for others.
    Scale - the numeric scale for a NUMERIC column. Zero for others.
    Default - the default value that was assigned to the column when the table was created.

$selectindexes()

Do oSQL.$selectindexes(tableNameReturns id

Retrieves column index information for the specified table.

On completion, $sqldone() is called with the following parameters:

  1. The request id (as returned from $selectindexes ()).

  2. A list describing the table column definitions, defined with the following columns:
    IndexName - name of the index.
    ColumnNames - comma-separated list of column names used by the index.
    PrimaryKey - kTrue if the index was created with the PRIMARY KEY clause.
    Unique - kTrue if the index was created with the UNIQUE clause.

$sqldone method

The $sqldone method is the client-executed completion method for SQL objects. When you add the $sqldone method to a remote form Omnis adds pre-defined or boilerplate code, as well as the required parameter variables, and sets the method to execute on the client automatically. This saves you having to add the same code every time you want to create the $sqldone method – you can then add to or amend the code as you wish. The code added to $sqldone is:

;; parameter vars pRequestId (Var type), pList (List) created
;; local vars lErrorCode and lErrorText created
;; Check for an error:
Do $cinst.$sqlobject.$getlasterrorcode() Returns lErrorCode
If lErrorCode<>0 ;; sql error occurred, show message
  Do $cinst.$sqlobject.$getlasterrortext() Returns lErrorText
  Do $cinst.$showmessage(lErrorText,'SQL Error')
  Quit method
End If
Switch pRequestId
  ;; Add cases for the IDs returned by your requests here.
End Switch

The code first checks if there was an error, then creates a Switch statement to handle the results based on the request in pRequestId. If you do not want to use this code, just select the lines of code and delete them.

SQLite Database Support

The SQLite offline storage and synchronization process uses a SQLite database on the remote client device. More specifically, SQLite synchronization relies on SQLite databases on the server and on each client device to store user tables as well as synchronization status info. The SQLite Synchronization Server uses these tables to pass data to/from each synchronization client and to forward synchronization requests on to the Consolidated Database (CDB). The SQLite Synchronization process is described in the ‘SQLite Synchronization Server’ manual which you can download from the Omnis website: www.omnis.net/download

To use the SQLite database object, the mobile device application is linked with the dbSQLite library. The SQLite initialization parameters are as follows:

$syncinit()

Do oSQL.$syncinit(syncParams) Returns id

The SQLite module currently recognizes the following parameters:

Username – The synchronization user name (defined at the synchronization server).
Password – The synchronization user password (defined at the synchronization server).
HostString – RESTful connection URL to Omnis Sync Server.
Timeout – The timeout in seconds for synchronization operations.

On completion, $sqldone() is called with the following parameters:

Example:

Do con.$define(Username, Password, HostString, Timeout)
;;define using local variables
Do con.$assigncols(
'user1','xxxxxx','http://192.168.0.10:7001', 5)
Do oSQL.$syncinit(conReturns id

HostString

The HostString parameter is a RESTful connection URL to Omnis Sync Server. For a direct connection to the built-in Omnis server, the HostString should be of the form:

http://<ip-address>:<$serverport>

If you are connecting through a web server, you need to add the omnisrest… server plugin to your web server (in the same way as the other server plugins), and connect through that. The HostString should then be of the form:

http://<web server address>/<Omnis rest plugin>/ws/<XXX>

Where <XXX> is either:

<Omnis $serverport> (if Omnis is on the same machine as the web server)

<Omnis server ip-address>_<Omnis $serverport>

<Server Pool>,<Omnis server ip-address>_<Omnis $serverport>

E.g: http://mysite.com/cgi-bin/omnisrestisapi.dll/ws/192.168.1.14_7001
or http://mysite.com/cgi-bin/omnisrestisapi.dll/ws/POOL,7001...

$sync()

This method invokes a request for uplink synchronization followed by downlink synchronization. Only tables previously configured for uplink (or normal) synchronization will upload IUD requests to the SyncServer. Likewise only tables configured for downlink or (normal) synchronization will receive IUD requests.

Please refer to the ‘SQLite Synchronization Server’ manual for information on the design, implementation and usage of the synchronization server. You can download this manual from the Omnis website: www.omnis.net/documentation

No Database Support

If the remote client application does not require database support, the application can instead be linked with the dbNoSQL library. This library provides stub definitions for the database API calls required by the wrapper application. Note that in this mode however, any calls to the SQL object will fail.

JavaScript Client Wrapper Application

The wrapper encapsulates a WebView which hosts the JavaScript Client application. The wrapper initializes using the supplied config.xml file which also informs the wrapper of the HTML page to load for the application.

The wrapper can be configured to connect to the Omnis IDE as a client for testing purposes. This is achieved via the Test Mobile Form menu option in the Studio IDE. The wrapper also provides device-independent access to features such as GPS, the camera and audio interface using the Device Control (see the JavaScript Components chapter for details about accessing device features).

image5

To support Serverless operation, the WebView runs local scripts that contain client executed methods.

Before you compile the app, you will need to customize the config.xml file.

When the client operates in online mode it uses the URL parameter from the config file to load the remote form and the wrapper behaves like a standard JavaScript application. If the client is to run offline however, the other config parameters are used to allow the wrapper to (optionally) update its local copy of the application, or to run the forms locally.

iOS Wrapper Project

The iOS wrapper project has two targets, both with differing local database support, and one with support for Push Notifications. These are:

  1. OmnisJSWrapper – includes embedded SQLite database which is used for local database support, plus Synchronization with a back-end server using the SyncServer.

  2. OmnisJSWrapper – as above but with Push Notifications.

iOS Wrapper Licensing

The iOS application wrapper uses the UICKeyChainStore wrapper, created by kishikawakatsumi and governed by the MIT license: more info is available here:
https://github.com/kishikawakatsumi/UICKeyChainStore

If you distribute your Omnis app using the iOS wrapper you will need to comply with the terms of this license and include the MIT requirements in your own software license.

Push Notifications

Push Notifications are supported in the Android, iOS, and Windows 10 JavaScript Wrappers (version 2.0+) which means you can send messages to any clients that have your mobile app installed (even if it is not running). In this respect, the ability to send push notifications provides a powerful and interactive feature that proactively encourages end users to open and use your mobile app.

A notification or message pushed to a client could include an important news item, a message to users about a new entry into the database, or anything else you want your end users to know about. You can include a payload of data to send with the notification, which will be passed to your Remote Form, allowing you to provide a response or outcome to the user clicking on the notification. The following is a notification on an Android phone.

image6

Support for notifications is provided via the Cloud Messaging or Push Notification Service on the respective platform, which must be enabled in your mobile app project when it is built using the latest JavaScript Wrapper SDK. To setup notifications in your app on Android and iOS, you will need to use Firebase from Google: on Windows 10 you need to setup the Push Notification Services in the Store Dashboard.

In order to manage notifications, it is possible to create groups of devices, and send notifications to particular groups, or individual devices. All functionality can be achieved in your Omnis code (using the notation), or using an admin tool, called Push Notifications, under the Tools menu on the Omnis menubar. Note the tool is an Omnis library located in the Startup folder which must be present for Push Notifications to work in your mobile apps, including your Omnis code, and for the Omnis App Server configuration to be setup.

For further information about setting up Push Notifications in your mobile apps, see the Push Notifications document on the wrapper download page, available here:

http://www.omnis.net/download/jswrapper.jsp

Headless Omnis Server

There is a “headless” version of the Omnis App Server on Linux that allows you to run your JavaScript Client-based web and mobile applications in a headless environment. The headless server is available for Linux only.

A so-called headless Omnis Server installed under Linux does not have a window-based interface, but can be controlled remotely from the command line in a Terminal window on the Linux machine, or you can configure the headless server using an Admin tool which is accessible using an HTML page located in the HTML folder in the main Studio folder (the admin tool library is located in the Startup folder of the Headless Omnis Server tree).

Considerations

Console Commands

There is a server config item in config.json ‘headlessAcceptConsoleCommands’, a Boolean. When set to true (the default), the headless server provides a basic command line interface when used in a terminal window.

From Studio 8.1.6, the default setting for ‘headlessAcceptConsoleCommands’ has been changed to false. Previously this was set to True which meant that all Console Commands were recorded which meant that 100% of CPU was used when the Headless server was run as a service: you will need to enable this option in config.json to accept all Console Commands.

Functions

The function isheadless() returns true when running in the headless server.

sys(231) returns zero in headless server.

sys(233) returns empty in headless server; it returns the title of the main Omnis application window in the full server.

Java

You can start the JVM at startup by setting the ‘startjvm’ in the java section of config.json to true: it cannot be started by any other mechanism on the headless server.

Class Notation

If your Omnis code creates new classes using notation, there is a mechanism to initialise new objects using template files, located in the ‘componenttemplates’ folder in the ‘Studio’ folder. The folders are: componenttemplates/window, componenttemplates/remoteform, componenttemplates/report containing the template files to create window, remote form, and report instances, respectively. Each template file name is complibrary_compcontrol.json, with spaces converted to _ (underscore): it is a copy of an object.json file where only the properties and multivalueproperties members are used. complibrary and compcontrol are the component library and control name.

Restrictions

There are various restrictions or differences from full Omnis Server, as follows:

  1. Printing images to PDF in the headless server is restricted to PNG images (or true-color shared pictures) only.

  2. There is no port support.

  3. You should use the ‘start’ entry in the ‘server’ section of config.json to start the multi-threaded server

  4. The Test if running in background command always sets flag to true in the headless server.

  5. Several commands and notation methods generate an error if executed in the headless server e.g. open window, $open for a window, etc.

  6. Picture conversion functions are not supported: pictconvto, pictconvfrom, pictconvtypes, pictformat, pictsize (a runtime error is generated).

  7. Standard messages generated by the server (OK messages and errors) are sent to the server log file, or could be routed to the Terminal if appropriate

Installing the Headless Server (Linux)

Download the installer from: www.omnis.net/download/

This install assumes you are running as Root or using sudo.

Update your version of Linux using the commands below that correspond to your distribution of linux:

Centos/Redhat: sudo yum update
Suse: sudo zypper update
Ubuntu/Debian: sudo apt-get update

Once updated, you will need to install the dependencies that Omnis requires to run, which are as follows:

  1. Centos/Redhat: cups, pango

  2. Suse/Debian: Runs out of box

  3. Ubuntu: cups, libpango1.0

Once these are installed you can start the installer:

./Omnis-Headless-App-Server-8.1-x64.run

Follow through the installer as you would a normal install of Omnis Studio making sure your serial number is correct or the install will fail.

For Centos 7 and Redhat the service will not automatically start after a reboot, therefore you will need to manually add Omnis (or whatever you called your service) to the service autostart list using the following lines:

sudo /sbin/chkconfig --add homnis
sudo /sbin/chkconfig --list homnis (This line is to show that you have added homnis correctly)
sudo /sbin/chkconfig homnis on

You can now configure the Headless server using the Admin tool, as below.

To summarize the steps for each platform:

CENTOS7 & REDHAT

Required commands for Omnis to run on Centos:

sudo yum update
sudo yum install cups pango
sudo /sbin/chkconfig --add homnis
sudo /sbin/chkconfig --list homnis
sudo /sbin/chkconfig homnis on

SUSE

The Headless Server should work out of the box on SUSE, but we would recommend an update just in case:

sudo zypper update

Ubuntu 16.04, 17.04 & DEBIAN 9

sudo apt-get update
sudo apt-get install unzip libpango1.0 cups

Headless Server Admin Tool

There is an Admin tool (OSAdmin) that you can use to configure the Headless Omnis Server: the Admin tool is implemented as a remote form and can be loaded in a web browser by opening the web page called ‘osadmin.htm’, which is located in the ‘html’ folder of the Omnis Server tree (not the SDK). However, before you can open this page to configure your headless server, you will need to set edit the osadmin.htm file to specify the location of your headless server. You need to edit the “data-webserverurl” parameter (enter either URL, IP address or Service name, and Port number, e.g. http://192.1.1.68:5000), then move the file to a location that allows you to open the file in a web browser and has network access to the headless server (the Headless Omnis Server installer should prompt you to set these options, but you may also like to change them manually).

image7

The Headless Server Admin tool has a number of tabs that let you view or configure the server Activity, Logs, Settings, and Users. When you first open the admin tool in your browser, you are requested to login: use the default username: omnis, password: 0mn1s (first character is zero). After logging in, you can change the password for the default user, or create other users.

The configuration and settings for your Headless Server are stored in a SQLite database. The location of this database is specified in the "headlessDatabaseLocation" item in the “server” section of the Omnis Configuration file (config.json).

Activity

The Activity tab lets you see all Open Libraries on the server. You can use the Refresh button to refresh the list.

The Open button lets you open a library on the server; note the construct method will be run if present. You can click on a library in the list and close it using the Close Library button; note that closing a library will suspend all clients connected to that library.

The Active Tasks tab shows all current, active task instances or client connections on the server; you can select a task or connection and view its details. You can kill or close a task instance or connection using the Kill Task button; note that killing a task or connection will suspend the operation of the application for the connected client.

Logs

The Logs tab lets you view the logs for the Server:

  1. Server
    provides a log of the headless server activity (the location of the logs can be set under the main Settings tab)

  2. Monitor
    provides a log of all the active client connecttions (task instances)

  3. Service
    provides a log of all the errors or messages generated by the server including any messages in the trace log or information about any web service requests.

Under the Service tab, the Configure button lets you set up what messages are recorded in the log, including the attribute "folder" of "logToFile" which is the name of the path relative to the Omnis Server tree where the service logs are generated. These settings are added to the config.json for the server, under the “log” member:

  "log": {

    "logcomp": "logToFile",

      "datatolog": [

      "restrequestheaders",

      "restrequestcontent",

      "restresponseheaders",

      "restresponsecontent",

      "tracelog",

      "seqnlog",

      "soapfault",

      "soaprequesturi",

      "soaprequest",

      "soapresponse",

      "cors",

      "headlessdebug",

      "headlesserror",

      "headlessmessage",

      "systemevent"

      ],

      "overrideWebServicesLog": true,

      "logToFile": {

        "stdout": false,

        "folder": "logs",

        "rollingcount": 10

        },

      "windowssystemdragdrop": true

      }

Settings

Under the Settings tab you can specify the location of the Server and Monitor logs, plus the timer period and size of the logs. You can also set up the Server Port, number of Server Stacks, and the Timeslice for the Headless server (and specified in the config.json file), and you can restart the service from here.

The default service name of the Headless server is “homnis” which is specified in the “server” member of the config.json file:

{
"server": {

"service": "homnis"
 

Users

The Users tab lets you update users or create new ones. The default omnis user can be changed here. When checked, the Re-start Option will allow a user to restart the server.