|
NetAuto Objects and the NetAuto Protocol |
|||
![]() |
|||
| Version www.capesoft.com Updated 20 February 2008 |
|||
|
Learn
NetTalk
|
Examples
|
Common
Features |
NetAuto
Objects |
NetSimple
Objects |
Dial-Up
|
Support
|
Version
History
|
There are a number of ways of adding the NetTalk objects to your program. In this first section we will deal with the easiest way to add them to your applications. In the following sections we cover the rest of the NetAuto objects in more detail. The NetSimple objects are dealt with in the separate NetSimple documentation.
NetTalk provides you with a number of control templates which allow you to quickly use some of the NetTalk functionality. These controls are demonstrated in the example program.
![]()
JUMP START for ChatControls
This has been modeled in the NetDemo example application.

Example Screenshot
This control template allows you to add a Chat window to your application:
1) Open or create a new application.
2) Clarion 5 Users (only):2a) Go to the "Project" Menu click "Properties" this will load the Project Editor.
2b) Click on "Project:Generator" in the very top of the left-hand pane, then press the "Properties" button and make sure your application's "Target OS" is set to " Windows 32-bit". If it's not, change it to 32-bit. (NetTalk only works for 32-bit applications).
2c) (Optional but recommended - turn on logging options - only needed in Clarion 5, as the NetTalk template in more recent versions does this for you):
Go to the defines Tab and add
NETTALKLOG=>1
This will turn on the NetTalk logging option (for debugging).
Then press OK a number of times to return to the Application Tree3) Add the NetTalk Global Extension by going to the "Global" button, pressing "Extensions", then "Insert" and choose "Activate_NetTalk" from the list of extensions. Press OK a number of times to return to the Application Tree.
4) Go to the Window formatter of the window procedure that you want as the chat controls placed in.
5) Go to the "Populate" Menu and choose "Control Template...". Choose "ChatControls" in the Select Control Template Window under "Class NetTalk" and press Select
6) When the list box formatter appears press OK.
7) Resize your window so that you can see all the controls. Return to the Application Tree.
8) Right click on the procedure with the Chat control and click and choose extensions.
9) In the NetTalk extensions setting you will see three tabs. Click on the "Settings" tab and you will see the name of your application in the Unique Application Name field. You may need to change this to be the same as the Unique Application Name of any other applications that you want your chat window to be able to chat with. The chat window can only chat with other NetAuto chat applications that have the same Unique Application Name.
10) Save your work and Compile and Run your application. (If you get any Compiler Errors then you can diagnose what went wrong in the compiler errors section).
You can either run two copies of the program or run it on two different machines to try it out.
JUMP START for CloseAppControls
The CloseAppControls give you the controls for remotely closing down your application from anywhere on your LAN.
This has been modeled in the NetDemo example application.
The Close Remote Applications is a client/server feature. Your need to add both the server (NetAutoCloseServer) and the client (NetCloseApps) functionality to your application. This is very easy to do.
This Client part is added via a Control template in a similar fashion to the ChatControls.
The Server part is added by using a new NetTalk object instance in the main frame of your application based on the NetAutoCloseServer object. This Auto Close Server runs when your application is loaded. The client is only run when the network administrator wants to close down the applications. (Remember a client is the process that initiates the communication or task). So the server just sits and waits until the client sends the request to close down.

1) Open or create a new application.
Adding the Client part of CloseApp
2) Clarion 5 Users (only):2a) Go to the "Project" Menu click "Properties" this will load the Project Editor.
2b) Click on "Project:Generator" in the very top of the left-hand pane, then press the "Properties" button and make sure your application's "Target OS" is set to " Windows 32-bit". If it's not, change it to 32-bit. (NetTalk only works for 32-bit applications).
2c) (Optional but recommended - turn on logging options - only needed in Clarion 5, as the NetTalk template in more recent versions does this for you):
Go to the defines Tab and add
NETTALKLOG=>1
This will turn on the NetTalk logging option (for debugging).
Then press OK a number of times to return to the Application Tree3) Add the NetTalk Global Extension by going to the "Global" button, pressing "Extensions", then "Insert" and choose "Activate_NetTalk" from the list of extensions. Press OK a number of times to return to the Application Tree.
4) Go to the Window formatter of the window procedure that you want as the close applications controls placed in.
5) Go to the "Populate" Menu and choose "Control Template...". Choose "CloseAppControls" in the Select Control Template Window under "Class NetTalk" and press Select.
6) When the list box formatter appears press OK.
7) Resize your window so that you can see all the controls.
8) Go back to the Application Tree. Right-click on the procedure that you just added the CloseApp Controls to and choose Extensions.
9) Go to the "Settings" tab on the Add CapeSoft NetTalk Close Controls and type in a unique application name. This needs to be the same name as the one you will use on the Auto Close Server.
10) You can also go to the "Extra" tab and set the default warning message. (The AutoClose Server can override these this message, with it's default message).
We have now added the CloseAppClient (CloseAppControls) we now need to add a AutoCloseAppServer.
11) Go to main frame of the project and right-click and choose extensions. (Note: This frame (or window) needs to be open the whole time your application is open, otherwise you will not be able to shut it down, that's why it's best that the AutoClose Server is added to a Frame). When the Extension and Control Templates window opens, click on the Insert button. Choose "IncludeNetTalkObject" under Class NetTalk. Press Select.
Adding the AutoClose Server
12) In the "This Object Name" field type in "OurCloseServer".
13) Set the "Base Class" Combo box to "NetAutoCloseServer". Press OK.
What we have done here is chosen to create our own instance of a NetTalk object based on the predefined NetAutoCloseServer object.
14) You now need to set the "Unique Application Name" in the template extensions to the same name that you used in the Client extension template. These settings are found in the "Settings" tab in extensions for both the Client and the Server procedures.
15) You can set the default messages and length of times that the messages are displayed for on this tab as well.
16) Save your work and Compile and Run your application. (If you get any Compiler Errors then you can diagnose what went wrong in the compiler errors section).
You can either run two copies of the program or run it on two different machines to try it out.
JUMP START for UseRemoteMachineControls
This Control is added in a similar fashion to the ChatControls. (If you don't want to use a Control Template to connect to remote machine, then you can also use the NetAutoRemote DLL function)
Important: NetTalk also has a DIP (Dynamic IP) manager. This technology provides you the ability to get all your applications talking to each other over a WAN or the Internet without having to know the individual IP address. 9 times out of 10 if you use the DIP object and the DIP server you will not need to use the UseRemoteMachine control template or the NetAutoRemote function.
This has been modeled in the NetDemo example application.

1.)Open or create a new application.
2) Clarion 5 Users (only):2a) Go to the "Project" Menu click "Properties" this will load the Project Editor.
2b) Click on "Project:Generator" in the very top of the left-hand pane, then press the "Properties" button and make sure your application's "Target OS" is set to " Windows 32-bit". If it's not, change it to 32-bit. (NetTalk only works for 32-bit applications).
2c) (Optional but recommended - turn on logging options - only needed in Clarion 5, as the NetTalk template in more recent versions does this for you):
Go to the defines Tab and add
NETTALKLOG=>1
This will turn on the NetTalk logging option (for debugging).
Then press OK a number of times to return to the Application Tree3) Add the NetTalk Global Extension by going to the "Global" button, pressing "Extensions", then "Insert" and choose "Activate_NetTalk" from the list of extensions. Press OK a number of times to return to the Application Tree.
4) Go to the Window formatter of the window procedure that you want as the chat controls placed in.
5) Go to the "Populate" Menu and choose "Control Template...".
6) Choose "UseRemoteMachineControls" in the Select Control Template Window under "Class NetTalk" and press Select
7) When the list box formatter appears press OK.
8) Resize your window so that you can see all the controls.
9) Save your work and Compile and Run your application. (If you get any Compiler Errors then you can diagnose what went wrong in the compiler errors section).
The NetDIP object(suggested reading)
This object is demonstrated in the NetDemo example.
DIP stands for Dynamic Internet Protocol address, and enables you to detect other instances of your program (or those in the same "room" as yours) by connecting to a common application server. The server then groups the clients into "rooms", by the room-name specified in your program, informs you who's in the room and then the necessary connection can be made.
NetDIP will be extremely useful to you if you receive a Dynamic IP address from your ISP, or you want to co-ordinate a central server to tie all sorts of users together around a LAN or WAN or the Internet. NetDIP is demonstrated in the NetDemo example and we suggest having a look at the Internet Chat example of how you can connect through a single DIP server in the CapeSoft office to other people using the chat program.
NetDIP is actually a NetSimple object, but it's main use is the co-ordination of the IP addresses of machines using the NetAuto objects. That's why we've put it in the NetAuto object document (Document 2).
TIP - There's an excellent snippet of information you need to read in the FAQ on using WAN & Internet.
Note: In order to use the NetDIP object, which is a DIP client, your application will need to be able to communicate with a DIPServer. There is one permanently running at dip.capesoft.co.za or you can compile your own DIPServer (see the example code in clarion/3rdPart/Examples/NetTalk) or you can download the DIPServer.exe from the NetTalk download page on www.capesoft.com .
JUMP START for NetDIP
Important: To test this application you will need to create this application and then test it over the Internet or a WAN. To effectively test it you will need to run two copies of the application you create, but they should not share the same LAN if you want to test the DIP functionality. (If both applications are on the same LAN they will still work, but are able to communicate with each other by virtue of being on the same LAN and not because they identified each other through the DIP server).
To use the NetDIP objects you need to do the following: (You will find this section easier to understand if you have already worked through scenario one).

Example Screenshot
1. Add the NetTalk Global Template and all the usual basics (see steps 1 to 4 of Chat Control JUMP START).
2. Use the NetTalk extension template to create your own object based on the NetDIP class. You could call your object anything you like (e.g. ThisDIP).
3. In the 'Settings' tab you find some prompts which will enable you to customize your program.
3.1. The 'Room Name' is the name of the unique "room" that users of your program will be added to. You want your room name to be unique. You could set this to something like MyTest123
3.2. The 'Server Address' is the address of the registration program that your program will connect to. There is a permanent DIP server running in the CapeSoft office ('dip.capesoft.co.za'), to use this you need to be connected on the Internet. If you want to run your own DIP Server it's in the examples folder. (You need to use single quotes if you are telling it to use a string otherwise you can specify a variable (without quotes)).
3.3. If the 'Auto-AddMe on open window' is checked, the user will be added when the window (with the NetDIP object on) is opened.
3.4. If the 'Auto-connect to friends on AddMe' check box is checked, your program will automatically open a communications port to other instances of the program in the "room" when your program adds itself to the "room".
3.5. If the 'Auto-DeleteMe on close window' is checked, then the user will be deleted from the room in the registration server when the window (with the NetDIP object on) is closed.
3.6. If the 'Suppress Error Messages' is checked, no NetTalk errors will be displayed if things go wrong. We suggest leaving this checked, as if the person if unable to connect, it's as simple as that, they can't connect and displaying an error message will not make then connect. (Errors can be seem via the debug logs).
4. If you want to programmatically extend this object you may need to override whichever methods you need to use. But for most applications you won't.
5. To test this, also add the Chat Controls to this window and then try out two copies of the application over the Internet. Make sure that both applications are not on the same LAN, so that they are being forced to use the DIP server to connection to each other.
![]()
NetDIP Hand Coded Example Code
Some of these examples are demonstrated in the NetDemo.app example application.
For the most part NetDIP is merely a template driven object. For those who wish to do some hand coding we have supplied the following example code.
Example Code for communicating with the NetDIP Server using the NetDIP object:
! Call the AddMe() method after the object has been initialized and the
! connection to the server has been established .
ThisDIP.AddMe()
! At the next ThisDIP.Process, a <Ok> OK </Ok> will be returned to confirm
! that the user has been added to the "room" on the server.
! You can then find out who else is in the room.
! You don't need to call the AddMe method before the GetFriends() method.
ThisDIP.GetFriends()
! At the next ThisDIP.Process, a String in the following format will be
! returned:
! <Room> roomname
! <Guid> GUID1.GUID2 </Guid> <IP> IPNo </IP> <Date> ConnectedDate
! </Date> <Time> ConnectedTime </Time>
! .
! .
! .
! more users
! </Room>
! roomname is the name of the room (set in the NetTalk template).
! The users' details are then listed after the roomname (a line for each user)
! GUID1 and GUID2 is the DIP of the user connected.
! IPNo is the user's IP address.
! ConnectedDate and ConnectedTime indicate when the user connected to the server.
Once you have done both of the above 2 methods, you can make the connection to your "friends" like this (You will not need to call this method if you have the "Auto-connect to friends on AddMe" check box in the NetTalk Local Extension Template checked):
ThisDIP.ConnectToFriends()
Before closing the object you will need to delete the user from the room.
ThisDIP.DeleteMe()
You can also use NetDIP to determine what your IP address is. To do this call:
ThisDIP.WhoAmI()
then put the following code into your ThisDIP.GotWhoAmI() method:
Message ('My IP is ' & self.MyIPAddress)![]()
JUMP START for Send Email Control Template
Adding email sending functionality to you applications is easier than ever. See the Send Email Control Template section for all the details.
This has been modeled in the NetDemo example application.
![]()
JUMP START for FTP Control Templates
Adding FTP upload and download functionality to your applications is easier than ever. See the FTP Control Template section for all the details.
This has been modeled in the FTPDemo example application.
Activate_NetTalk
This Global Template must be added to your application to use any of the following features. Later on we'll explain how to do this.
Suppress_NetTalk - (only for DLL applications)
By Default NetTalk is part of ABC. If you are making a Multi-DLL app then NetTalk is automatically included in the "Root" DLL. This may not be desirable because NetTalk requires both the DOS and the NetTalk DLLs. This extension is designed to be added to your Root DLL. It removes NetTalk from the Root DLL. Use this ONLY if the application will NOT be using NetTalk in ANY of it's DLLs or EXEs.
Use_NetRefresh
Add this Global Template to use NetRefresh in your application. Again this is explained later on the Use_NetRefresh section.
JUMP START for Use_NetRefresh Global Extension Template
You can use this template to automatically refresh data on open windows (browses and forms) when data is changed in other instances of your program or in windows on other threads. This is really useful when multiple users use the same data set. On your forms and processes you can issue a refresh command when the records are saved and any window that is active (in it's thread) will immediately be refreshed with the correct data. A window that was not active (in it's thread) at the time when the refresh was issued, will be refreshed as soon as it becomes active on that thread. There is an example of the NetRefresh in the NetRefresh example application.
Important Note: The NetRefresh function will only work in Frame based applications. You must have a frame in your application, and you must not run windows on the same thread as the Frame's thread. Rather use the Start function to start windows on their own threads.
Adding the Auto-refresh function
1. Add the "Refresh All Windows on Update" global extension template to your application (for a Multi-DLL project you must do this for all the apps). To do this:
1.1. Open your application and click on the "Global" button.
1.2. Click on the "Extensions" button on the "Global Properties" window.
1.3. If you have not added the "Activate_NetTalk" extension, then you will need to do that now. Click "Insert" and select that "Activate_NetTalk" extension from the list of templates and click on the "Select" button.
1.4. Make sure that the "Activate_NetTalk" extension is highlighted and click the "Insert" button. Select the "Use_NetRefresh" extension template from the list box and click the "Select" button.
2. Customize the Global Extension to suite your needs:
General Tab3. Click "OK" a couple of times to return to the application tree.
2.1 Enter a Unique Application Name. This should be a name that uniquely differentiates your application from all the other NetRefresh enabled programs that may be running on your Network (for a Multi-DLL project this must be the same in all the apps).
2.2. Leave the "Auto send in forms and processes" set on (default) if you want to automatically send the refresh command on the "OK" button (forms) or when processes are completed. This option can be overridden on each form if you require.
2.3. You can choose to Suppress Error Messages if these get in your way. The default is to have Error Messages displayed. But on some applications you may choose to turn this off.
2.4. If you don't want to use the Auto-Refresh function, then check the "Disable NetRefresh" check-box.
2.5. If this app is part of a multi-DLL application and it is not the data DLL, then you need to check the 'Refresh object External'.
Advanced Tab
2.6. Minimum time between refreshes is useful for programs with heavy traffic, i.e. in a database where there are many changes being made, the screen can be constantly refreshing, causing confusion to the user. It may be helpful to perform multiple changes in one refresh every minute, rather than refreshing multiple times every minute.
2.7 Use Window.Reset(1) - should be on (default)
2.8 Use BRW.ResetFromBuffer() - should be turned on if you are using the ODBC Driver.
4. Add the Refresh command to the required places. This is automatically done on all forms and processes, if you checked the "Auto send in forms and processes" on.
4.1. This is not normally needed, except if you want to manually issue a SendRefresh command. Simply add the following line of code to wherever you need to issue a refresh (e.g.. after records have been changed/added or deleted):5. If you don't want a window to be refreshed when a refresh command is received, then you can disable the Refresh on that specific window.
ThisNetRefresh.send() ! refresh all the other windows with our data change.where ThisNetRefresh is the name of the object entered in the Global Extension template.
4.2. You can turn the Refresh command to forms and processes manually on in the local procedure extension template that is automatically populated by the "Use_NetRefresh" template. (Note this only applies to Forms and Processes not Browsers nor Windows)
4.2.1. Right-click on the form/process from, in the application tree, where you would like to issue the Refresh command.
4.2.2. Select "Extensions" from the popup menu that appears.
4.2.3. Highlight the "Refresh this Window on Update" template in the template list that appears.
4.2.4. In the Template's properties that appear on the right, you can change the status of the "Send Refresh Command" to "Use Global Default" (the setting in the Global Extension template), "Yes" or "No".
5.1. Do 4.2.1. to 4.2.3. to get to the local extension template for the window where the Refresh must be disabled.
5.2. Check the "Disable Net Refresh on this window" will ensure that this window is not updated when a Refresh command is posted to this application.
To harness all the power of NetTalk you need to use the NetAuto or NetSimple objects directly. This section looks at using the NetAuto objects. (For info on using the NetSimple objects please look at Document 3).
When you want to build your own application that can communicate over the network, you can use the two main NetAuto objects, NetServer and NetClient. NetTalk templates allows you to easily build your own instances of these objects. These objects provide you with the network communication. You can then tailor these objects to your needs. The details of how to do this are described in the three scenarios.
The rest of this section describes the NetAuto objects in more detail. If this is the first time you are reading this manual you may want to skip this section for now, but make sure you come back here later and read the rest of this section later, as it lays a foundation for NetTalk and object programming. If you choose to skip this section you can go to the next section (Programming Scenarios) which give you practical examples of how to use NetTalk.
NetAuto allows you to set up client and server services. To create your own NetAuto Service you will use either the NetServer or NetClient object. (The NetTalk template extensions help you do this). You will create your own instance based on one of the NetAuto objects and can override methods or derive your own methods and properties.
When you add a NetAuto object to your procedure using the extension template, you choose whether the object is private or public. See Scenario One for an example. Normally servers are public, because a public service is announced to other NetAuto services so that they can use the service. Most clients are private, as no other NetAuto services need to be seen. If your clients need to see other clients then you would create a public client. (Technically a client is also a server, in that it can respond to communication from another client).
When you want your client service to send a packet, you will override the Send() method or derive an Ask() method. See Scenario One for an example. NetAuto communication is done via packets. The NetAuto packet has various properties that should be set (more details in the What data must I set before sending a packet section) before it is sent. These include specifying the data you want to send, and who (which machine(s)) you want to send it to. You can choose to send it to any server, a particular server or all servers. When the packet properties are set you will call the parent.send() method, which will send the packet. If your data is too big to be sent in one packet, you can specify that you want to send a set of packets.
The packet has two data properties which you can set. The first is a long (32-bit) number called self.packet.command. This is a useful property to send command numbers to other processes. For example you could send command=1 when you want to request the time, or command=2 when you want to set the time. You can tailor this command for your own use. By convention a command of 0 means you are not using the command. The second is a string called BinData (binary data). The maximum amount of data you can place in the BinData string is a constant value of Net:MaxBinData (currently 16K). Scenario One demonstrates how to pack all sorts of data into BinData using groups defined over the string. (If you want to send more than 16K of data then you will need to send a set of packets, see Scenario Three).
Each process (or instance of your application) that uses NetAuto gets assigned it's own Name. This name is referred as the NetName. In the TCP/IP protocol each machine has it's own hostname and in NetTalk each application that uses at least one NetAuto object gets assigned it's own NetName based on the hostname. Your hostname is the name set in the Windows Networking Properties, from your control panel. Example: If I load up an application that uses NetAuto on my machine. It's hostname is 'spiff' and it's NetName is also 'spiff'. If I load a second copy of this application into memory (i.e. 2 copies running) the hostname for is still 'spiff', but it's NetName is 'spiff2'. The NetName is used to differentiate multiple NetAuto enabled applications running on the same machine. For an example see Scenario Two.
When you want to write the code that will receive a packet you will override the Process() method. See example Scenario One. This virtual method gets called for you when your NetAuto instance receives a packet. It allows you to read the data sent to you from other NetAuto applications. You can also use this method to send data back or to communicate with other instances. In fact there is no limitation in how you want to build your applications. NetAuto is very flexible. Should you wish to send off a set of packets then you will override the MultiPacketReply() method, which will allow you to prime one packet at a time, before they are sent. (The MultiPacketReply() method is only used when you are sending a set of packets, and not for single-packet transfer. You can send multiple single-packets which is different from sending a multi-packet set. Single-packets only need to use the Process() method. You only need to send a set of packets when the data you want to send is larger than one packet.)
You can look at the section that describes the methods and properties of the NetServer and NetClient objects. You should also look at the Handy Guide for what you need to set before sending a packet.
The following programming scenarios have been created as examples which will help you to create your own NetAuto applications.
Most network applications fall into one of three categories and we have modeled these three categories as three scenarios for you. To incorporate the NetAuto objects into your application, look at the following scenarios and find the one that closest matches what you are trying to do. You will then find it relatively easy to add NetAuto communication to your applications by following the example. To understand these scenarios you need to know that our definition of a client is, the process that initiates communication, whereas it is the server that responds to communication. See the Client / Server section for more detail.
Scenario One - Sending single packets with separate Client and Server processes. In this scenario we build a separate client and a separate server. (The client and the server could be two separate applications or both included in one application. But they are separate in functionality and design). The client will send single commands to the server and receive back some data. The example we build here is a time server and time client. The time client sends a request for the time and the server will respond to this by sending back the time. This example does not actually change the time on your PC, but you could easily change it to do this. In this example the client and server have been built into two separate applications, but you may need to build both your client and server into one application. That's fine. This is the example to look at when you want to send single packets from a client to a server.
Scenario Two - Broadcasting packets from one Client to another Client. The client behaves as a client and as a server. In this example we build a single process that acts as both a client and server. The example we have here is a Chat program where everybody is able to send each other a chat string. When a process sends this chat string the other machines display it on the screen. This example also makes use of the broadcast functionality, whereby all processes running this application receive the chat string. Broadcasting basically means instead of sending a message to one machine, you send it to all.
Scenario Three - Sending multi-packet sets with separate Client and Server processes. This is similar to Scenario One, but instead we will send multiple packets of data in a set. (i.e. Large data that needs to be broken into smaller packets and sent as a set of packets). We will demonstrate this by creating a client that requests a large (64K) string from a server. Since the size of a NetAuto packet is 16K this string will need to be sent as a four packet set. This is similar to the File Server and File Client which have been created in the NetDemo.exe program, explained in the examples section.
![]()
Note: The source code (in an app file) for this scenario can be found in your Clarion\3rdParty\Example\NetTalk folder.
In this example we build a Time Client and a Time Server. The Time Client will request the time from the Time Server, by sending a packet command of 1. The Server will return the time in the binary data portion of the packet.
1) Open or create a new application in Clarion. (You can turn off Quick Start and the Application Wizard for this example).
2) Clarion 5 Users (only):2a) Go to the "Project" Menu click "Properties" this will load the Project Editor.
2b) Click on "Project:Generator" in the very top of the left-hand pane, then press the "Properties" button and make sure your application's "Target OS" is set to " Windows 32-bit". If it's not, change it to 32-bit. (NetTalk only works for 32-bit applications).
2c) (Optional but recommended - turn on logging options - only needed in Clarion 5, as the NetTalk template in more recent versions does this for you):
Go to the defines Tab and add
NETTALKLOG=>1
This will turn on the NetTalk logging option (for debugging).
Then press OK a number of times to return to the Application Tree3) Add the NetTalk Global Extension by going to the "Global" Button, pressing "Extensions", then "Insert" and choose "Activate_NetTalk" from the list of extensions. Press OK a number of times to return to the Application Tree.
4) Open the window formatter for the window that will request the time. (You may need to create a new procedure to do this).
Creating the Client
5) Insert a button onto the window. Change the "Text" property of the button to "Get Time" and change the "Use" property of the button to "?GetTime"
6) Insert a string field onto the window. This will be the string field that will contain the time, when we get it from a server. Set the "Use" property to "?TimeStr"
7) Return to the Application Tree and rename your procedure to 'TimeClient'
8) Go to the procedure extensions for your (TimeClient) window. i.e. Right click on the procedure and choose extensions. Press the "Insert" button and choose the "IncludeNetTalkObject", press the "Select" button.
9) In the NetTalk template properties set the "This Object Name" to "ourTimeClient" and the "Base Class" field to "NetClient" (note we aren't going to use the NetGetTime object this example.). In the Settings tab, set the Service Name to "MyScenario1". Make sure that the Private Service checkbox is checked (ticked)
Explanation:
What we've done is created an instance of the NetClient object. This is our client object (called ourTimeClient) and it will be responsible for initiating the communication by requesting the time from the Server (which we will create later). The Service name is the name of all services that this client can communicate with. A NetAuto server and client can only communicate with each other if the service name is the same. The reason why we choose to define this service as a private service is that this service does not need to announce itself to other NetAuto programs. It's a client and no-one needs to know that it is running. It will find a server (which will be a publicly announced service) and it will communicate directly with the server.
10) Click on the "Advanced" tab and press the "Data Embed" button in the Override Existing Class Methods group. We are going to insert some code into the data section of one of the existing methods of the object.
11) The "Embedded Source" window appears. If the content of the main text box is empty go to the "view" menu and turn off "Show Filled Only"
12) Find the "Process Procedure" node under Local Objects - ourTimeClient and open the node. Click on the "Data" node and press the "Insert" button.
13) In the Select Embed Type Window choose Source. Paste the following code into the embed editor:
ourData group ! We make a group to store
time long ! the data we want to send
date long
end
ourString string(size(ourData)),over(ourData)
! then we create a string
! over it.
Press the "Exit!" button to return to the Embedded Source Window. Press the Close button to return to the Extensions Window.
14) Click on the "Advanced" tab and press the "Code Embed" button in the Override Existing Class Methods group. We are going to insert some code into the methods of the object we have just created. Find the "Send Procedure" node under Local Objects - ourTimeClient and open the node. Click on the "Parent Call" node and press Insert. In the Select Embed Type Window choose Source. Paste the following code into the embed editor:
self.getservers() ! check for a list of servers
if self.error <> 0
if self.error = -15 or self.error = -16
message ('No Time Servers could be found on your LAN.', |
'NetTime Demo',ICON:ASTERISK)
else
self.ErrorTrap ('An error occurred while attempting to get ' & |
'a list of time servers.', 'TimeClient.Send')
end
return ! Do not send a packet
! Do not let parent.send() get called
else ! if a server exists. (self.error = 0)
self.packet.ToNetName = '' ! We don't mind who serves us
self.packet.Command = 1 ! Send the server command 1
! (we use command 1 as Get the Time)
self.packet.BinDataLen = 0 ! the server doesn't take any data...
self.packet.Options = NET:SinglePacket ! Single packet
! Okay to send the message to a server
! The packet will be sent by the parent
! call that follows this code
end
Click on the Exit! button and you will be returned to the Embedded Source window.
Press the Close button to return to the Extensions Window.
Important! Make sure that the code you inserted has been placed before the parent call in the Send PROCEDURE node. If not click on the Source node that you just inserted and press the up arrow in the priority group box on the right of the window. This will move the source above the parent call.
Explanation:
Okay, we've overridden the Send() method. This is the method that gets called when we want to get the time from a server. This is achieved by sending the server a packet requesting the time and then waiting for a return packet.
The GetServers() command makes sure that we have a server to request the time from. If there aren't any servers it returns -15 or -16 and we raise an error.
The reason we call the return statement when the error occurs is to stop the parent.send() method being called. (If you click on the Source button in the Embedded Source Window, you can see how the code that we added and the parent call interact in the ourTimeClient.Send() method) The parent call is the call to send the packet, and if we don't want to send the packet, we must make sure it is not called, by returning from outTimeClient.Send() before parent.send() is called.)
15) Now repeat this process of inserting source code into the Code Embed of the "Process Procedure" node (can be either before or after the parent call - as parent.process() does not do anything):
if self.packet.command = 2 ! Server has sent us the time
ourString = self.packet.bindata[1:8] ! Store the data that
! the Server sent us
?TimeStr{Prop:Text} = format (ourData.date,@d17) & |
' ' & format (ourData.time, @t4)
! Display it
end
16) Return to the Application Tree
17) We just need to tell your application what to do when the user clicks on the "Get Time" button. Go to the window-formatter of the Get Time Window. Right-click on the "Get Time" button, choose embeds. Select the "Generated Code" under "Accepted", double-click this. Choose "Source" and then insert the following
ourTimeClient.Send() ! Send a packet requesting the time
18) Save your client application and create a new application (which will be your server application) and repeat points 1 to 5 for this new application.
Creating the Server
19) In the main window (which you could call something like TimeServer) add the "IncludeNetTalkObject" NetTalk extension.
20) Set the object name to "ourTimeServer" and the Base Class to "NetServer". In the Settings tab, set the Service Name to "MyScenario1". (Note this must be the same name that was used in the Client). Make sure the Private Service checkbox is unchecked. We want a public service. It must let other NetAuto applications know that it is available as a Time Server.
21) Click on the "Advanced" tab and press the "Data Embed" button in the Override Existing Class Methods group. We are going to insert some code into the data section of one of the existing methods of the object. Find the "Process Procedure" node under Local Objects - ourTimeClient and open the node. Click on the "Data" node and press Insert. In the Select Embed Type Window choose Source. Paste the following code into the embed editor:
ourData group ! We make a group to store
time long ! the data we want to send
date long
end
ourString string(size(ourData)),over(ourData)
! then we create a string
! over it.
22) Return to the Extensions Window and use the "Code Embed" button to insert the following in the Process() method: (can be either before or after the parent call - as parent.process() does not do anything).
! This method is triggered when a request is received
! from a client. All we have to do is prime the packet
! information with the correct data, the server object
! will do the rest.
if self.packet.command = 1 ! Client has requested the time
ourData.time = clock() ! prime our data in the ourString
ourData.date = today() ! which is "over" ourData
self.packet.bindata = ourString [1 : size(ourString)]
! set the data we want to send
self.packet.BinDataLen = 8 ! set the length of the data
self.packet.command = 2 ! 2 = I'm sending the time
self.packet.options = Net:SinglePacket ! Single packet
self.SendReply = 1 ! and tell the server object
! to send this packet
end
23) You can now compile and run these two applications. Should you need to debug your code, you can compare your code with the example in the Clarion/3rdParty/Examples/NetTalk directory. You can also consult the Error Codes sections and also the Logging section.
Note: The source code (in an app file) for this scenario can be found in your Clarion\3rdParty\Example\NetTalk folder.
In this example we build an Chat application which will only have a client object, but we will get the client object to operate as both a server and a client. (Remember a client is actually an advanced server). This example will also demonstrate broadcast communication, whereby a packet is sent to all listening servers.
1) Open or create a new application.
2) Clarion 5 Users (only):2a) Go to the "Project" Menu click "Properties" this will load the Project Editor.
2b) Click on "Project:Generator" in the very top of the left-hand pane, then press the "Properties" button and make sure your application's "Target OS" is set to " Windows 32-bit". If it's not, change it to 32-bit. (NetTalk only works for 32-bit applications).
2c) (Optional but recommended - turn on logging options - only needed in Clarion 5, as the NetTalk template in more recent versions does this for you):
Go to the defines Tab and add
NETTALKLOG=>1
This will turn on the NetTalk logging option (for debugging).
Then press OK a number of times to return to the Application Tree3) Add the NetTalk Global Extension by going to the "Global" Button, pressing "Extensions", then "Insert" and choose "Activate_NetTalk" from the list of extensions. Press OK a number of times to return to the Application Tree.
4) Create a window (you can call it something like "Chat") that we can use as the Chat Window. (You may need to create a new procedure to do this).
Creating the Combined Server & Client
5) Go to the Properties of this Chat Window (you may need to define it as a 'Window' procedure type). Press the Data button. Insert the following data types:
Name
Type
Base Type
Size
ConversationText
String
32000
OurText
String
100
ListOfServers
Queue
Net:AutoPublicServicesQType
6) Return to the procedure properties window. There is a little button marked '...' to the right of the window button. Click on this button and overwrite the following to define the window (normally you would use the window formatter to define your own window, but this speeds up the example):
Window WINDOW('Chat Example (Scenario 2)'),AT(,,399,185),|
FONT('MS Sans Serif',8,,FONT:regular),SYSTEM, |
GRAY,DOUBLE
PROMPT('Your &text'),AT(3,1,101,11),USE(?Prompt1)
ENTRY(@s100),AT(3,12,242,10),USE(ourText)
BUTTON('Send'),AT(254,10,50,15),USE(?Send),DEFAULT
TEXT,AT(3,33,243,148),USE(ConversationText),HVSCROLL,READONLY
LIST,AT(254,33,144,134),USE(?OtherChatters),HVSCROLL,|
FORMAT('80L(2)|M~Description~@s80@37L(2)|' & |
'M~NetName~@s80@4L(2)|M~IP Address~@s80@'), |
FROM(ListOfServers)
BUTTON('Close'),AT(348,169,50,15),USE(?Close),#SEQ(1)
End
Press the Exit! button to return to the Procedure Properties window. Return to the application Tree
7) Go to the procedure extensions for your (Chat) window. i.e. Right click on the procedure and choose extensions. Press the "Insert" button and choose the "IncludeNetTalkObject", press the "Select" button.
8) In the NetTalk template properties set the Object Name to "ourChat" and the Base Class field to "NetClient". In the Settings tab, set the Service Name to "MyScenario2Chat". Important: Make sure that you uncheck (no tick) the Private Service checkbox. We do not want this client to be a private client, it must be public.
Explanation:
What we've done is created an instance of the NetClient object. This is our server & client object all-in-one (called ourChat) and it will be responsible for sending Chat strings to other Chat processes as well as receiving Chat strings from other processes. It plays the role of both the client (initiator) and the server (the process that responds to the initiator). It must be defined as a public service as it needs to announce itself to the other applications that will use it. That way the Chatters list is updated and when you press the Send button it knows who to send the data packets to.
9) Click on the "Advanced" tab in the NetTalk extension and tick the "Derive?" check-box. We are going to add a new property to the object we have made. Click on the "New Class Properties" button. Click on the "Insert button" in the "New Class Properties" window that opens.
10) Set the property name to "myName" Set the property type to "String" and the size to 80. We will use this property to store the name our NetAuto NetName. (The NetName is usually the name of your machine. But a second instance of NetAuto on the same machine will have a NetName with a "2" appended to the end. A third instance will have a "3" etc.) Press OK twice to return to the Extension and Control Templates Window.
11) Click on the "Advanced" tab and press the "Code Embed" button in the Override Existing Class Methods group. We are going to insert some code into the data section of one of the existing methods of the object. The "Embedded Source" window appears. If the content of the main text box is empty go to the "view" menu and turn off "Show Filled Only". Find the "Init Procedure" node under Local Objects - ourChat and open the node. Click on the "Parent Call" node and press the "Insert" button. In the Select Embed Type Window choose Source. Paste the following code into the embed editor:
self.broadcast = 1 ! sets us up for sending
! each packet to everyone
self.myName = NetAutoGetNetName() ! Get the name of our process
Window{Prop:Text} = 'NetAuto Chat Example (' & |
clip (self.myName) & ')'
! Set the window title bar
self.servers &= ListOfServers ! set the object to use our
! queue, not it's own queue
Click on the Exit! button and you will be returned to the Embedded Source window.
Press the Close button to return to the Extensions Window.Important! Make sure that the code you inserted has been placed after the parent call in the Send PROCEDURE node. If not click on the Source node that you just inserted and press the down arrow in the priority group box on the right of the window. This will move the source below the parent call.
Explanation:
Okay, we've overridden the Init() method. This is the method that gets called when the object loads up. We are setting the window title property as well as telling NetAuto to use our Queue of available servers so that we can display a list of servers to the user. We get the NetName by calling the NetAutoGetNetName() DLL function. We store this NetName in the new myName property that we added to our object.
12) Now repeat this process of inserting source code into the Code Embed of the "Process Procedure" node (can be either before or after the parent call - as parent.process() does not do anything):
! This method receives packets from other Chat controls.
ConversationText = clip (|
self.packet.bindata[1 : self.packet.BinDataLen]) & |
clip(ConversationText)
! Add the text people send us to our
! Text Box on the Screen
display(?ConversationText) ! Refresh the Conversation Box
Explanation: This is the code for handling Chat strings that arrive from other processes.
13) Insert the following into the Code Embed in the Send() method (in the "Send Procedure" node) before the parent call.
self.getservers()
self.packet.ToNetName = '' ! Everyone (we are using broadcast)
self.packet.command = 0 ! We aren't using command
self.packet.BinData = clip(self.myName) & ': ' & |
ourText & '<13,10>'
! Send our name followed by the
! Text the user has typed in
self.packet.BinDataLen = len(clip(self.packet.BinData))
! Set BinDataLen to the
! length of BinData
self.packet.options = Net:SinglePacket ! Single packet
! packet will now be sent by parent call
14) Insert the following code after the parent call (in the Send() method)
self.process() ! This is a bit sneaky, all we do
! here is call our own process() and
! pretend that we received the data
! in our own packet, even though
! it wasn't sent to us. This
! updates the conversation text
! box on the screen for us.
Explanation: This is the code for sending Chat strings to all other processes. We are sending in broadcast mode and so we set the ToNetName to '' (all in broadcast mode).
15) Return to the application tree. We now need to tell the send button what to do when someone clicks on it. Open the window formatter for the Chat window. Double click on the Send button to open the "Embedded Source" window. Under "?Send" -> "accepted" double click on the "Generated Code" node. Choose "Source". Insert the following:
ourChat.Send() ! Call the send method of ourChat object
!Begin Optional
clear(OurText)
select(?OurText)
!End Optional
16) Return to the window formatter. Double click on the close button and insert the following source into the "?close" accepted embed point:
post (event:closewindow) ! Close down this window
17) Return to the application tree. Save and Compile and Run your application.
(If you application compiles but does not work (can't send messages to other chatters) please check step (8) to see if you did uncheck (no tick) the private service checkbox).
Note: If you want this application to be able to communicate with the Chat window in the NetDemo.exe you need to change the ServiceName from MyScenario2Chat to NetChatnetdemo in the extension template Settings tab. This is because the service names are different. But if you make them the same the two different chat programs can communicate with each other.
Note: The source code (in an app file) for this scenario can be found in your Clarion\3rdParty\Example\NetTalk folder.
In this example we build a Server and Client that will transfer a large string (in this case 128K, but it could be anything) via a set of packets. The point of this exercise is to demonstrate sending multi-packet sets. Sending sets of packets is very useful when transferring large amounts of data or when transferring files. (If you are interested in transferring files then you can look at the NetGetFile (Client) and NetFileServer (Server) objects that come with NetAuto. You can find their source code in the Clarion\LibSrc folder in the net*.clw and net*.inc files.)
This is the most complicated of the three scenarios and so it is recommended that you work through the first scenario before this one.
1. Open or create a new application. (You can turn off Quick Start and the Application Wizard for this example).
2) Clarion 5 Users (only):2a) Go to the "Project" Menu click "Properties" this will load the Project Editor.
2b) Click on "Project:Generator" in the very top of the left-hand pane, then press the "Properties" button and make sure your application's "Target OS" is set to " Windows 32-bit". If it's not, change it to 32-bit. (NetTalk only works for 32-bit applications).
2c) (Optional but recommended - turn on logging options - only needed in Clarion 5, as the NetTalk template in more recent versions does this for you):
Go to the defines Tab and add
NETTALKLOG=>1
This will turn on the NetTalk logging option (for debugging).
Then press OK a number of times to return to the Application Tree3) Add the NetTalk Global Extension by going to the "Global" Button, pressing "Extensions", then "Insert" and choose "Activate_NetTalk" from the list of extensions. Press OK a number of times to return to the Application Tree.
4) Rename the Main procedure window that to "LargeStringServer". We will use this window as the Server window.
Creating the Server
5) Go to the procedure extensions for your (LargeStringServer) window. i.e. Right click on the procedure and choose extensions. Press the "Insert" button and choose the "IncludeNetTalkObject", press the "Select" button.6) In the NetTalk template properties set the This Object Name to "ourStringServer" and the Base Class field to "NetServer". In the Settings tab, set the Service Name to "MyScenario3". Uncheck (no tick) the Private Service checkbox.
Explanation:
What we've done is created an instance of the NetServer object. This is our server object (called ourStringServer) and it will be responsible for providing the large String to any clients that request it. It is a public service as the clients will need to know about it.
7) Click on the "Advanced" tab in the NetTalk extension and then tick the "Derive?" check-box. We are going to add a new property to the object we have made. Click on the "New Class Properties" button. Click on the "Insert button" in the "New Class Properties" window that opens. Set the property name to "LargeStr". Set the property type to "Other" and the other data type to "string(128000)". This will be the string we return to the client when they request it.
8) Also add a property called "progress" of type long. This will be used to keep a record of how much of the string we have sent, when we send the string. The string will need to be sent over a number of packets. Press OK twice to return to the Extension and Window.
9) Click on the "Advanced" tab and press the "Data Embed" button in the Override Existing Class Methods group. We are going to insert some code into the data section of one of the existing methods of the object. The "Embedded Source" window appears. If the content of the main text box is empty go to the "view" menu and turn off "Show Filled Only". Find the "Process Procedure" node under Local Objects - ourStringServer and open the node. Click on the "Data" node and press the "Insert" button. In the Select Embed Type Window choose Source. Paste the following code into the embed editor:
x long
10) Press the "Exit!" button to return to the Embedded Source Window. Press the Close button to return to the Extensions Window. Click on the "Advanced" tab and press the "Code Embed" button in the Override Existing Class Methods group. We are going to insert some code into the methods of the object we have just created. Find the &quo