Tips   >   Internet   >   Internet (All Contents)

Internet

This section covers topics releated to using the internet from Omnis Studio. (Email, FTP, HTTP, TCP, etc.)

HTTP Download File

You can use the HTTPPage command to download a file from a web server. The trick is to remove the header from the file before saving it to the local computer.

The following sample code downloads a zip file and prompts the user for a file name and location to save the file.

; Ping the server to make sure we are connected to the internet.
Calculate Server as 'studiotips.net'
TCPPing (Server) Returns Milliseconds
If Milliseconds<0
   OK message (Icon) {Unable to ping the server at '[Server]'}
   Calculate FlagOK as kFalse
Else
   
   ; Figure out the URL to the file to be downloaded.
   ; The file could be any file type: zip, pdf, jpg, txt, etc.
   Calculate DownloadsDirURL as 'http://www.studiotips.net/downloads/free/'
   Calculate FileName as 'test.zip'
   Calculate URL as con(DownloadsDirURL,FileName)
   
   ; Load the file into a character variable.
   HTTPPage (URL) Returns Buffer
   If len(Buffer)=0
      OK message (Icon) {The server returned an empty page for the URL:////[URL]}
      Calculate FlagOK as kFalse
   Else
      
      ; Remove the HTTP header and copy the character variable contents to a binary variable.
      ; The header is separate from the content by an empty line.
      Calculate Find as con(kCr,kLf,kCr,kLf)
      Calculate Binary as mid(Buffer,pos(Find,Buffer)+len(Find))
      
      ; Prompt the user for a file name and location to save the file.
      Calculate Path as FileName
      ; (path[,prompt,filter,initial-directory,appflags])
      Do FileOps.$putfilename(Path,'Save Downlioaded File As') Returns bContinue
      If not(bContinue)
         Calculate FlagOK as kTrue
      Else
         
         ; Create the file using the FileOps external.
         Do oFileOpsExt.$createfile(Path) Returns FlagOK
         If FlagOK
            Do oFileOpsExt.$writefile(Binary) Returns FlagOK
         End If
         Do oFileOpsExt.$closefile()
         If not(FlagOK)
            OK message (Icon) {FileOps error when attempting to create and write to the file at:////[Path]}
         Else
            OK message (Icon) {The downloaded file has been saved at:////[Path]}
         End If
      End If
   End If
End If
Quit method FlagOK

HTTPPage

The Omnis command HTTPPage returns the contents of a web page.

; Ping the server to make sure we are connected to the internet.
Calculate Server as 'studiotips.net'
TCPPing (Server) Returns Milliseconds
If Milliseconds<0
   OK message (Icon) {Unable to ping the server at '[Server]'}
Else
   
   ; Get the home page contents.
   Calculate URL as 'http://www.studiotips.net'
   HTTPPage (URL) Returns Text
   
   OK message (Icon) {StudioTips home page content is:////[Text]}
   Breakpoint {Right-click on the Text variable to see the full contents.}
   
End If
Quit method Text

Click the Run Demo button in the StudioTips Browser to test the sample code.

Open Web Browser to URL

This tip provides cross platform code for opening the default web browser and pointing it to a specified URL. The Go to URL button in the StudioTips Browser window uses this code.

You can copy the sample code included with this tip to your library.

; Open the default browser to a specified URL.
Switch sys(6)
      
   Case 'M','X' ;; Mac, Mac OS X
      
      Calculate ScriptText as con('open location "',iMyURL,'"')
      Calculate ScriptText as con('$runapplescript(',chr(39),ScriptText,chr(39),')')
      Do [ScriptText]
      
   Case 'W','N' ;; Windows, Windows NT or 2000
      
      Register DLL ('Shell32.dll','ShellExecuteA','JJCCCCJ') Returns ErrorCode
      Call DLL ('Shell32.dll','ShellExecuteA',0,'#NULL#',iMyURL,'','#NULL#',1)
      
   Default
      
      OK message [sys(85)] (Icon) {Sorry I don't know how to open your Internet browser}
      
End Switch

FTP

Omnis has a whole group of FTP commands which you can use.

FTPChmod
FTPConnect
FTPCwd
FTPDelete
FTPDisconnect
FTPGet
FTPGetBinary
FTPGetLastStatus
FTPList
FTPMkdir
FTPPut
FTPPutBinary
FTPPwd
FTPReceiveCommandReplyLine
FTPRename
FTPSendCommand
FTPSetConfig
FTPSite
FTPType

You can look up information on each of these command in the F1 Help.

The StudioTips tipBase library contains an object class called, oFTP. I use the oFTP object for uploading the StudioTips documentation to the studiotips.net website and for the AutoUpdater utility.

The oFTP object class acts as an adapter to the Omnis FTP commands, making it easy for you to setup and use FTP in your application. You don't have to study all the Omnis FTP commands. You simply use the public methods of oFTP and it executes the FTP command for you. StudioTips members are welcome to copy the oFTP object class to their own applications.

After you instantiate the oFTP object using an object datatype variable of the scope of your choice you send it an $initialize message. The $initialize message includes parameters that specify the server, user name, password, etc. Once the object has been initialized it knows the server, user name and password, so you don't need to supply that information as you call the various public methods of oFTP.

If an error occurs, the error information is copied to an iErrText ivar of the oFTP object class, and kFalse is returned to the sender. The FTP error code is looked up and the user readabble FTP error text is appended to the iErrText. An $:ErrorText method returns the current value of iErrText to the sender. The oFTP object will also check if your application uses an oErrorHandler object instantiated by the startup task variable errhndlr, and if you do, oFTP will send a $logError or $logFTPError to your error handler.

The following is some sample code of how you might use the oFTP error handler object.

Calculate ServerAddr as 'studiotips.net'
Calculate UserName as 'temp@studiotips.net'
Calculate Password as 'pass'
Calculate PortNum as ''
Calculate InitialDir as ''
Calculate PingTimeOutSeconds as 0 ;; Don't use TCPPing
; (pServerAddr,pUserName,pPassword,pPortNum_opt,pInitialDir_opt,pPingTimeoutSeconds_opt)
Do oFTP.$initialize(ServerAddr,UserName,Password,PortNum,InitialDir,PingTimeOutSeconds) Returns FlagOK
If FlagOK
   
   Do oFTP.$connect() Returns FlagOK
   If FlagOK
      
      Do oFTP.$:PathWorkingDir() Returns FolderPath
      
      Do oFTP.$:FilesList_longformat() Returns FilesList
      If FilesList.$colcount=0
         Calculate FlagOK as kFalse
      Else
         OK message oFTP Object Class (Icon) {There are [FilesList.$linecount] files and/or directories found in the [FolderPath] directory on the [ServerAddr] server for the FTP user [UserName]}
      End If
   End If
End If
If not(FlagOK)
   Do oFTP.$:ErrorText() Returns ErrText
   OK message FTP Error (Icon) {[ErrText]}
End If
Quit method FlagOK

StudioTips members are welcome to copy the oFTP object class from the tipsBase library to their own applications or download it from studiotips.net/downloads/

Click the Run Demo button in the StudioTips Browser to run the sample code.

TCP

Omnis has a whole group of TCP commands which you can use.

TCPAccept
TCPAddr2Name
TCPBind
TCPBlock
TCPClose
TCPConnect
TCPGetMyAddr
TCPGetMyPort
TCPGetRemoteAddr
TCPListen
TCPName2Addr
TCPPing
TCPReceive
TCPSend
TCPSocket

You can look up information on each of these command in the F1 Help.

This section contains tips, demos, and sample code on some of the Omnis TCP commands, things you can do, and things you want to watch out for.

TCPName2Addr

Use the TCPName2Addr Omnis command to convert a domain name to an IP address.

TCPName2Addr (hostname) Returns address

; Note: IPAddr will be an error code number if the hostname could not be looked up.

; Test with the vencor.ca domain.
Calculate HostName as 'vencor.ca'

TCPName2Addr (HostName) Returns IPAddr
If isnumber(IPAddr)
   OK message TCPName2Addr (Icon) {Unable to get a valid IP address for the host name '[HostName]'}
Else
   OK message TCPName2Addr (Icon) {The IP address for the host name '[HostName]' is '[IPAddr]'}
End If

Note: This command fails if the address of a Domain Name Server has not been defined in your computer. Not all host IP Addresses may be known to the Domain Name Server. If the Domain Name Server is busy or unavailable, the command times out and returns an error. Defining often-used servers to a local hostŐs file or using a caching Domain Name Server increases performance of this command.

I tested to see what this method does if you feed it an IP address rather than a domain name. If the IP address is a valid format, the method simply returns the IP address. If the IP address is not a valid format, e.g. one of the numbers is greater than 255, the method returns and error.

; Test with the IP address of the vencor.ca domain from the previous code snip.
Calculate HostName as IPAddr

TCPName2Addr (HostName) Returns IPAddr
If isnumber(IPAddr)
   OK message TCPName2Addr (Icon) {Unable to get a valid IP address for the host name '[HostName]'}
Else
   OK message TCPName2Addr (Icon) {The IP address for the host name '[HostName]' is '[IPAddr]'}
End If


; Test with an valid IP address that likely doesn't exist.
Calculate HostName as '192.255.254.253'

TCPName2Addr (HostName) Returns IPAddr
If isnumber(IPAddr)
   OK message TCPName2Addr (Icon) {Unable to get a valid IP address for the host name '[HostName]'}
Else
   OK message TCPName2Addr (Icon) {The IP address for the host name '[HostName]' is '[IPAddr]'}
End If


; Test with an invalid IP address.
Calculate HostName as '192.168.1.258'

TCPName2Addr (HostName) Returns IPAddr
If isnumber(IPAddr)
   OK message TCPName2Addr (Icon) {Unable to get a valid IP address for the host name '[HostName]'}
Else
   OK message TCPName2Addr (Icon) {The IP address for the host name '[HostName]' is '[IPAddr]'}
End If

Click the Run Demo button in the StudioTips Browser window to run the sample code.

You can use the TCPAddr2Name Omnis command to convert an IP address to a domain name. I have not always been successful in converting a valid IP address to the domain name.

TCPPing

Use the TCPPing Omnis command to ping a server.

TCPPing (hostname[,size,timeout]) Returns milliseconds

; Test with the vencor.ca domain.
Calculate HostName as 'vencor.ca'

; (Hostname[,Size,Timeout])
TCPPing (HostName) Returns Milliseconds
If Milliseconds<0
   OK message TCPPing (Icon) {TCPPing to [HostName] failed.}
Else
   OK message TCPPing (Icon) {TCPPing to [HostName] succeeded.}
End If

; Test with an invalid domain name.
Calculate HostName as 'vencor.xyz'

TCPPing (HostName) Returns Milliseconds
If Milliseconds<0
   OK message TCPPing (Icon) {TCPPing to [HostName] failed.}
Else
   OK message TCPPing (Icon) {TCPPing to [HostName] succeeded.}
End If

The problem I have run into with using TCPPing is that numerous servers ignore TCP ping on purpose. e.g. Try pinging apple.com

You can not assume that a server is going to respond when you send it a TCPPing.

I was using TCPPing to test communication with a host before attempting to do an SMTPSend, and FTPConnect, or $logon to a database.

If the client computer is not connected to their local area network or the network is not connected to the internet a lot of time can be wasted attempting to send an email or $logon to a database. To test for a connection to the internet you could use a server which you know responds to TCPPing, and in case that server happens to be down, you could try a series of 2 or 3 servers which you know to respond to TCPPing.

; Test with the a host server that we know does not respond to TCPPing.
Calculate HostName as 'apple.com'

; (Hostname[,Size,Timeout])
; Cut the default size and timeout to reduce the TCPPing wait time.
Calculate Size as 256/4
Calculate Timeout as 3000/10
TCPPing (HostName,Size,Timeout) Returns Milliseconds
If Milliseconds<0
   
   ; Try another known domain.
   Calculate HostName as 'scsinternet.com'
   TCPPing (HostName,Size,Timeout) Returns Milliseconds
   If Milliseconds<0
      
      ; Test with the vencor.ca domain.
      Calculate HostName as 'vencor.ca'
      TCPPing (HostName,Size,Timeout) Returns Milliseconds
      
   End If
End If
If Milliseconds<0
   OK message TCPPing (Icon) {TCPPing to [HostName] failed.}
Else
   OK message TCPPing (Icon) {TCPPing to [HostName] succeeded.}
End If

Click the Run Demo button in the StudioTips Browser window to run the sample code.

Whois

You can use the TCP commands to get whois information on a domain.

; Samplecode to query the whois database with omnis
; based on the examples in the Omnis helpfile RRG / 08/03/14

; the whois server : more here : http://www.addspice2life.com/2008/02/whois-servers-list.html or http://www.mit.edu/afs/athena/contrib/potluck/Net-Services/whois-servers.list
; internic.net
; http://www.netdemon.net/tutorials/whois.txt
; http://www.iana.org/domains/root/db/index.html

Calculate WhoisDomain as 'whois.internic.net'
Calculate Port as 43 ;; Port for the whois server
Calculate TestDomain as 'omniscentral.com'
Calculate SendMssg as con(TestDomain,kCr,kLf) ;; append querystring for whois server

TCPConnect (WhoisDomain,Port) Returns Socket
If Socket<0
   OK message {Unable to TCPConnect with '[WhoisDomain]' on port [Port]}
Else
   
   ; Connected
   TCPSend (Socket,SendMssg) Returns CharCount
   TCPReceive (Socket,ReceiveMssg)
   TCPClose (Socket)
   
   Calculate ShortMssg as mid(ReceiveMssg,pos('Domain Name:',ReceiveMssg))
   
   OK message {Whois result for '[TestDomain]' is////[ShortMssg]}
   
End If

Ultra-Thin Client

Ultra-thin client is delivering html-based code from the Omnis web server to the clients. An ultra-thin client solution does not use the Omnis Web Client plugin.

The Omnis Web Server is sitting on the server listening on port 5912 (or whatever port you set it to). It can receive messages from html pages specifying the web client plug-in, or it can receive messages from html pages not using the web client plug-in.

Using the web client plug-in you can quickly create very rich browser windows. That is, browser windows which are similar to the window classes that you creating in Omnis Studio.

However, in my opinon, the Omnis Web Client solution is not great for the general public.

  1. It requires users to download and install the Web Client plug-in.
  2. Every time you use a new component, the plug-in asks the user if it is okay to download the component.
  3. Licensing can get expensive because each simultaneous Web Client connection requires a separate runtime license.

Where you have a web page that is targeted to the general public, it is quite easy to create an HTML form that can submit data to a remote task in your Omnis web application, and then from the remote task reply to the web page with HTML.

If you want to see an example of an HTML page which uses the ultra-thin client, go to www.vencor.ca/cemetery/wingham/search, or click the Ultra-Thin Client Demo button in the StudioTips Browser window.

Enter the letter Z and click the Search button. The html results page is dynamically generated by an Omnis Studio application.

Note

The StudioTips JS 201 tutorial takes you step-by-step through building an ultra-thin Omnis Studio web app.

Web Client

I started into my first Omnis Web Client job as a web server dummy. My knowledge of how the internet, browsers, and web servers worked was (and still is) pretty sparse. I had not written a single line of JavaScript and always depended on Adobe GoLive for doing all my website/HTML work.

Getting into all of this was intimidating because of my lack of knowledge and the thought of having to slow down and battle my way through yet another learning curve.

Well, hats off to OMST! The learning curve was pretty short and before I knew it my first Omnis Web Client page was up and running. Not bug free, but hey, it worked.

Two more days of digging around and I had a thin-client HTML search page communicating with a remote task in my application through the Omnis Web Server. I was impressed! (My wife's eyes glazed over when I communicated my excitement to her.)

So, if I can get the Omnis Web Server/Web Client/Thin-client stuff working, so can you!

This section doesn't try to replace the Developing Web Applications in OMST manual. Like other sections in StudioTips, this section is intended to expand on places where you might get stuck, things to watch out for, and examples and code you can that can help you when developing your own web client application.

Hope it helps!

DKVS

Web Client Testing

One of the first things to do before you start programming for the web client, is to make sure the web client is installed and working for your browser.

The easiest way to do this is to go to the web gallery at www.omnis.net and make sure your browser works with the demos provided by Omnis. If it doesn't work there, try downloading and reinstalling the web client plug-in.

If your browser won't work on the mother ship's examples, then it isn't going to work for anything you write either. Get it working there first!

Click the Go to Web Gallery button below to test your web browser web client plugin.

Web Client Programming

Since the web client uses remote forms which lose their connection with your Omnis Studio application you must pass the data to the remote form and cannot get real object-oriented fancy between the remote form and your application.

Web Client Gotchas

When you move in the Web Client world, there are some gotchas you need to be aware of. This list of gotchas is being added to as I run into them. You may find that more recent versions of Omnis Studio have solved some of these gotchas, so be sure to test them yourself.


  • Do method $cinst vs. Do $cinst

    In the remote form when you want to execute a remote task method or a remote form method you need to use Do method $cinst, rather than Do $cinst. If you are operating inside the same class, you should use Do method without the $cinst. prefix.

  • Do $cinst.$MethodDoesNotExist()

    In the Web Client world you can't get away with a line of code in your method that tries to call a method that does not exist. I had a line of code in table class that called a method which I had deleted. The code had been running for months without a problem, but when that same table class method was called during Web Client execution it generated a runtime error! You can't get away with sloppy notation when using the web client.

  • No OK Messages, No Breakpoints, No Modal Prompts.

    Hitting any of these things when working with the web client halts execution on the server and the client. The client is powerless to do anything since they can't see the OK message on your server nor hit the OK or Cancel button in the dialog window on your server.

    You might want to use an oPrompts object class for all your prompts. Make the oPrompts object sensitive to whether or not it is running as under a web server license or a development license and use the appropriate prompt so as to not halt the web server/client method execution.

  • Notation Path to Objects Inside Containers on Remote Forms

    When you use notation to an object inside a container, ignore the container. If you include the container in the notation path, the code will fail if you are operating the method as Execute on Web Client. There is no form objects hierarchy on the client. This was removed to save space in the client. All objects live at the root, $cinst.$obj, regardless of the container they are in.

  • Don't get too Fancy

    In Omnis Studio thick client you can get quite fancy with objects and item references, and fancy notation like $sendall. Out on the web client you have to keep it simple. If your code isn't working, simplify it, start from the basics and layer it up till you find out where it fails.

  • No $construct for Remote Form Objects

    You can add a $construct method to a remote form object but it doesn't do anything. Only the class method $constuct is called when a remote form is instantiated.

  • Set $event for the Events You Want to Trap

    Remember to set the event you want to trap in the F6 Property Manager for each event you want to trap in each field. It is easy to forget to do this and then wonder why your pushbtton $event method isn't picking up evClick events.

  • Remote Task $construct

    Don't end out of the remote task $construct with Quit method kTrue or kFalse. Doing so will cause the web client browser to be receive a kTrue or kFalse message and will empty the browser page.

    JavaScript for Setting Web Client Plug-in

    The following example uses JavaScript for adding the correct web client plugin.

    Variables are declared and set in the <head> section of the page and then used in the Javascript that sets the web client plugin. Using variables saves having to change the OmnisServer, OmnisLibrary, OmnisClass,... in multiple locations on the page.

    Feel free to copy, paste, and modify this HTML/Javascript for use in your own Omnis Web Client pages.

    <!-- Do not include this opening comment line in the actual page

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
            
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <script language="Javascript">

    // Declare and set the variables to be used in the Javascript.
    var PageTitle = "Omnis Web Client Javascript Using Variables"
    var ObjWidth = "755";
    var ObjHeight = "585";
    var OmnisServer = "5912";
    var OmnisLibrary = "swWebTests";
    var OmnisClass = "rfTest";
    var WebServerURL = "http://localhost";
    var WebServerScript = "/cgi-bin/nph-omniscgi";

    </script>

    <script language="Javascript">
    document.writeln("<title>"+PageTitle+"</title>");
    </script>
    </head>

    <body>

    <script language="Javascript">

    // Add the applicable Omnis Web Client plugin based on the browser.

    if(navigator.appName == "Microsoft Internet Explorer" && navigator.platform == "Win32") {

    // Web browser is Internet Explorer on Win32 platform. Use ActiveX plugin.
    document.writeln("<center>");
    document.writeln("<object classid='clsid:13510606-30FA-11D2-B383-444553540000' ");
    document.writeln("width='"+ObjWidth+"' ");
    document.writeln("height='"+ObjHeight+"' ");
    document.writeln(">");

    document.write("<param name='_Version' value='65536'>");
    document.write("<param name='_ExtentX' value='7161'>");
    document.write("<param name='_ExtentY' value='7373'>");
    document.write("<param name='_StockProps' value='0'>");
    document.write("<param name='OmnisServer' value='"+OmnisServer+"'>");
    document.write("<param name='OmnisLibrary' value='"+OmnisLibrary+"'>");
    document.write("<param name='OmnisClass' value='"+OmnisClass+"'>");
    document.write("<param name='WebServerURL' value='"+WebServerURL+"'>");
    document.write("<param name='WebServerScript' value='"+WebServerScript+"'>");

    document.writeln("</object><center>");

    } else {

    // Web browser is not Internet Explorer on Win32. Use Netscape plugin.
    document.writeln("<center><embed type='application/OMNIS-RCC-plugin' name='rcc1' ");

    document.writeln("width='"+ObjWidth+"' ");
    document.writeln("height='"+ObjHeight+"' ");
    document.writeln("OmnisServer='"+OmnisServer+"' ");
    document.writeln("OmnisLibrary='"+OmnisLibrary+"' ");
    document.writeln("OmnisClass='"+OmnisClass+"' ");
    document.writelin("WebServerUrl='"+WebServerURL+"' ");
    document.writelin("WebServerScript='"+WebServerScript+"'");

    document.writelin("></center>");

    }

    </script>

    </body>
    </html>

    Do not include this closing comment line in the actual page -->

    Paged Pane

    I ran into an interesting problem problem when trying to reference objects on a paged pane.

    In window classes the notation path to an object in a paged pane is as follows:

    $cinst.$objs.PagedPane.$objs.ObjectName

    But in a remote form the notation to the same object inside the PagedPane would simply be:

    $cinst.$objs.ObjectName

    The notation path to an object inside a paged pane on a remote form does not include the paged pane. Even thought you can visually group objects in containers on a remote form in design mode, at runtime they are flat. All the objects in a remote form are at the same level when it is instantiated.

    Printing Reports

    The web client plugin has a great component that allow web client to preview Omnis reports in their browser window and print then print them locally. (I believe you can print directly without print preview.)

    Click the Run Demo button to test printing a report to the web client.

    @BUG: The Page Count external component doesn't work with the web client printing control component. (Omnis v3.2)
    @BUG: I have not had any luck printing from the print component using Mac OS X.

    Show Message

    Omnis commands like OK, Yes/No, No/Yes, Prompt for input can not be used in any code that is executed by or for your web client or ultra-thin client. The reason is that the message prompt will show up on your server and until someone at the web server machine clicks the button on the prompt dialog the method execution will stop. (Not very handy).

    $showmessage displays a message dialog window in the client's web browser without halting method execution on the server.

    Do $cinst.$showmessage('Message','Title')

    Warning

    The behavior of $showmessage is different depending on whether the method is executing on the client or on the server.

    If $showmessage is in a method set to Execute on Client the message window will be modal. Method execution will halt until the user clicks the Okay button at which time method execution will continue.

    If $showmessage is in a method which executes on the server the message window will be modeless. The methods will first finish and then the message window will be opened. When the user clicks the Okay button it merely closes the message window.

    If you try to open multiple message windows from method(s) executing on the server only the last $showmessage window will be opened on the client browser.

    Click the Run Demo button in the StudioTips Browser to test variations of the $showmessage method.

    Subform Communication

    You can pass messages from subforms to the parent form and from the parent form to the subform.

    The trick is each of the methods involved must be set to Execute on Client.

    From the subform to the parent remote form: Do $cwind.$ParentMethodName

    From the parent remote form to the subform: Do $cinst.$obj.SubformFieldName.$SubformMethodName

    To communicate from one subform to another subform you pass the message through the parent remote form.

    Click the Run Demo button to see an example of subform/parent remote form communication.

    Subform Communication Treelist

    When I built my first web tree component subform I had a terrible time trying to get the evWTreeNodeClick events in the subform passed on to the parent remote from and on to other subforms.

    I finally decided to stop fighting with it in my real application and build a test demo of it from scratch in StudioTips. As often happens, things worked when I tried it step by step from scratch.

    Click the Run Demo button to see an example of subform treelist/parent remote form communication.

    Task Call Back

    You may have a situation where you want a remote task instance to be able to send messages to a remote form which has instantiated the task.

    Click the Run Demo button to see an example of how you can register a remote form with a remote task.

    Task Communication

    Communicating from the form to the task can be tricky if you start from a method which is set to Execute on Client.

    Click the Run Demo button to see an example of remote form to task communication.

    Web Tree Component

    I like using the web tree component for letting the user navigating menus and opening windows. There are a couple of gotchas that I ran into with the web tree component.

    1. $expandcollapse iconid is set to 613. If you don't load the MultiState2 icons with the remote form page, clicking on the icon nodes misbehaves. Be sure to load icon 613 with the remote form which contains the web tree component, or set the $expandcollapse iconid to 0 zero.
    2. If you want to open the treelist with any root nodes already open you need to set the $expandcollapse state column for the specified node to 2. The sample code below sets the Books node to expanded when the web tree component list is built.

    ; Define the treelist flatlist.
    Do iTreelist.$define()
    Do iTreelist.$cols.$add('root',kCharacter,kSimplechar,100)
    Do iTreelist.$cols.$add('child',kCharacter,kSimplechar,100)
    Do iTreelist.$cols.$add('iconid',kInteger,kLongint)
    Do iTreelist.$cols.$add('ident',kInteger,kLongint)
    Do iTreelist.$cols.$add('reserved',kInteger,kLongint)
    Do iTreelist.$cols.$add('expandcollapse',kInteger,kLongint)
    Do iTreelist.$cols.$add('textcolor',kInteger,kLongint)

    ; Add node items to the treelist.
    Do iTreelist.$add('Files',,614+k16x16,100,0,1,0)
    Do iTreelist.$add('Classes','Class 1',1700+k16x16,101,0,0,0)
    Do iTreelist.$add('Classes','Class 2',1701+k16x16,102,0,0,0)

    ; Set the 'Books' node to expanded. (expandcollapse=2)
    Do iTreelist.$add('Books',,615+k16x16,200,0,2,0)
    Do iTreelist.$add('Books','Book1',1705+k16x16,201,0,0,0)
    Do iTreelist.$add('Books','Book2',1706+k16x16,202,0,0,0)

    Web Tree with Tags

    The F6 Property Manager > Custom tab, has a $datamode property which can be set to kTreeDataFlatListWithTags.

    You can add a character column up to 255 characters to your flat list and include whatever information you like. During event handling pTagID will return the value of your tag column for the current node.

    Very handy!

    Web Server

    The Omnis Web App Server process is activated by a CGI installed on the web server. The CGI listens for requests on the $serverport specified in your Omnis Studio preferences (default 5912). When an HTTP POST or HTTP GET is received on the specified port the CGI forwards the request to the Omnis library and remote task class specified in the HTTP request. (OmnisLibrary, OmnisClass) The Omnis Web App Server process instantiates the remote task passing along the HTTP POST or HTTP GET parameters to the $construct method of the remote task.

    Web Server Setup - Linux

    Note

    The following information is outdated. You will need to interpolate the information and use at your own discretion.

    I ran into some problems installing and setting up the Omnis Server on the Linux box which I use for serving the Vencor web site. The problems were inflicted because I downloaded the RPM from omnis.net rather than installing from the CD supplied by Omnis Studio. The downloaded RPM didn't automatically copy the .so files from the rainingdata folder to /usr/lib folder.

    Here are the steps I followed for installing the Omnis Web Server onto my Linux box.

    1. Using a Linux web browser download the omnisserver.rpm file from Omnis Softwre.
    2. Save the rpm file to the home directory.
    3. Go to terminal mode.
    4. Go to the home directory.
    5. Switch to super user. Enter: su
    6. Install the packger. Enter: rpm-i omnisserver.rpm

      This creates the necessary directories and puts the files in /usr/local/rainingdata/os321web. (321represents the Omnis version. This will vary depending on the version you are using.)
    7. Copy the nhp-omniscgi file to the cgi-bin directory.
    8. Go to the cgi-bin directory to make sure it exists. Enter: cd /var/www/cgi-bin
    9. Make sure the nhp file exists. Enter: ls /usr/local/rainingdata/os321web/webserver
    10. Copy the file to the cgi-bin directory.
      Enter: cp /usr/local/rainingdata/os321web/webserver/nhp-omniscgi nhp-omniscgi
    11. Copy the .so files to the /usr/lib directory
    12. Go to the os321web directory. Enter: cd /usr/local/rainingdata/os321web
    13. List the .so files. Enter: ls *.so
    14. Copy the .so files to usr/lib. Enter: cp *.so /usr/lib

    All going well you should be able to startup the Omnis Studio server as follows:

    Enter: /user/local/rainingdata/o321web/omnis &

    The '&' ampersand spawns the task in the background.

    The first time you run Omnis Studio you will need to serialize it.

    In the Omnis Studio File menu > select Server Configuration... and set Server Port to 5912 (or whatever port you choose to have the Omnis Server listen on.)

    Auto Restart Omnis Server and Open Omnis Libraries

    You will likely want Omnis Studio to automatically startup and open your web server application so that if the web server computer is restarted, the Omnis server and your libraries will automatically be reopened.

    One of the option for doing this is to add this to the rc.local file. Steps are as follows:

    1. Go to the rc.d directory. Enter: cd /etc/rc.d
    2. Edit the rc.local file. Enter: pico rc.local
    3. Go to the end of the file and add the following text:
      /usr/local/rainingdata/os321web/omnis &
    4. Exit the file and save changes. Enter: Ctrl+X
    After Linux reboots, the rc.local file will now automatically restart Omnis Studio. In order to get your Omnis web application libraries automatically opened, you simply need to store the libraries in the /os321/startup folder.

    Web Server Setup - Mac OS X

    Setting up personal web serving on Mac OS X is simple. The steps are as folllows:

    1. Select System Preferences > click Sharing.
    2. Services tab > check Personal Web Sharing.

      Your computer is now a web server. (Easy eh!?) The URL address for your computer's web sites are specified below the Services tab checklist.
    3. Finder > Applications > Omnis Studio application folder > webclient folder > server folder.
    4. Right-click on the nph-omniscgi file and select Copy.
    5. Finder > Library/WebServer/CGI-Executables folder.
    6. Right-click and select Paste to copy the nph-omniscgi file into the CGI-Executables folder.
    That's it, your Mac OS X computer is ready for full testing as an Omnis web app server for both the web client and ultra-thin client.

    Web Server Setup - WinXP

    I installed IIS (Internet Information Services) on WinXP Pro from the Microsoft CD, however, the version which I got was IIS 5.1, which does not have the Web Service Extension option. It turns out I need IIS 6.0 or higher to get that option.

    I tried to upgrade to IIS 6.0 but that failed. I decided to change course and install Apache for WinXP instead.

    First I had to remove IIS 5 & 6

    1. Start menu > Control Panel
    2. Add or Remove Programs > Add/Remove Windows Components
    3. Select Internet Information Services and follow the process.
    4. WinXP crashed part way through the remove. I had to restart.
    5. Running through the process a second time worked fine.

    Next I went to http://httpd.apache.org and worked my way to the download for the latest stable version of Apache - Win32 Binary (MSI Installer). The installer did all the work for me.

    There were a few fields I have to fill in:

    1. Network Domain: 127.0.0.1
    2. Server Name: localhost
    3. Administrator's Email Address: doug@vencor.ca (Fill in your own email address)
    4. Installation type: Typical Install

    After the installer had done its work I restarted WinXP. Using my web browser enter localhost as the URL and a simple page came up with the text It works!. That was good news.

    The Apache folder where http://localhost points to located at: C:\Program Files\Apache Software Foundation\Apache 2.2\htdocs\

    Apache 2.2 in the preceding file path would be replaced with the version of Apache which you downloaded.

    The next step was to install the CGI.

    1. Go to the clientserver folder inside the Omnis executable folder. The folder path would be something like:

      C:\Program Files\Raining Data\OS42\clientserver
    2. Look for the nph-omniscgi.exe file. The path from the clientserver folder should be:

      \clientserver\server\cgi\nph-omniscgi.exe
    3. Copy the nph-omniscgi.exe to the cgi-bin folder inside the Apache folder. The path will be something like:

      C:\Program Files\Apache Software Foundation\Apache 2.2\cgi-bin\
    That's it! You are ready to test your WinXP localhost Apache web server.

    Web Server Testing

    Sometimes I have trouble figuring out what is going wrong with my Omnis Web App and want to do a simple check to see if the Omnis Web App Server is up and running and listening on the specified port.

    I created a tiny library called pingWebApp.lbs and a simple HTML page called pingwebapp.html which I use for testing communication between the web page, the web server, the Omnis Web App Server, and my Omnis Studio library. The files are available to Omnis Studio developers for free.

    Here's the steps I recommend you follow for testing Omnis Web App Server communication.

    1. Make sure your web server is running. This could be a web server running as localhost on your computer or a web server a remote computer. Test the web server by opening its home page over your web browser. e.g. http://localhost/index.html
    2. Download the pingWebApp zip file from www.studiotips.nets/downloads and unzip the files.
    3. Open the pingwebapp.lbs library with a developer version of Omnis Studio on your web server.
    4. Check to make sure the $serverport property has been set. You will find it under the General tab of Omnis Studio Preferences. If the $serverport property is empty, set it to 5912 or another port, and then quit and reopen the pingwebapp.lbs library with your developer version of Omnis Studio.

      Note

      You can not have more than one instance of Omnis Studio running on the same web server with the same port number. Each instance must use a different port number.

    5. Open the pingwebapp.html file with your browser. (FireFox is recommended for testing.)
    6. Read the instruction on the page and set the values in the fields as per the instructions.
    7. Click the Ping Omnis Web App button. All going well you should receive a reply from the rtPing remote task in the pingWebApp library.
    Tip

    Copy the rtPing task to all of your OM web apps. You can then ping any of your open Omnis Studio web apps at any time to test communication.

    Web Server Serialize

    While testing the Omnis server you can use your single user web developer license serial number. Once you are ready to go live, you will need to purchase sufficient web client run-time license(s). If you are using the ultra-thin client you will be able to go a long way on a single Omnis Web App Server license. If f you are using remote forms you will need one license for each simulateous user.

    After you receive the new serial number you will need to reserialize the Omnis server software. The simplest way to do this is to delete the omnis.cfg file located in the studio folder of your Omnis application.

    You will be prompted to enter the new serial number when you reopen Omnis Studio.