VBVoice netWorks provides integration with Web Browsers for LineStatus, Logging, and Statistics information. Each is implemented using an invisible Java applet in conjunction with JScript code on the web page to display the information.
LineStatus and Statistics data are provided by the Lstat.class Java applet. It receives status updates as changes occur from the VBVoice application monitor VBVRLOG.EXE, which must be running on the same machine as the one providing the web server. When new status information is received, it fires events in the web page so that the JScript code in the page can update the necessary fields.
The same Java applet also provides statistics data upon request using the get...Data methods.
Status updates are initiated when the web page calls the startStatusUpdates method on the applet, providing the start channel and number of channels for which information is required. This method can be called from the onload event in the page or from a function.
Three fields in the LineStatus database are UserData1, UserData2, and UserData3. These are string fields that can be set by code and are displayed by a LineStatus display using the Web browser or the ADO object data access methods.
To set the LineStatus user data fields, use the SetLineStatusExtra method in the Log object:
Sub SetLineStatusExtra(Channel as Integer, WhichUser as Integer, Data as String)
WhichUser can be an integer from 1 to 3, for UserData1, UserData2, or UserData3. Data can be any string up to 64 characters in length.
EXAMPLE |
Dim mylog as VBVLog Set mylog = new VBVLog mylog.SetLineStatusExtra(Channel, 2, Getting PIN) |
For greater efficiency, declare the mylog object as global to the form and initialize it once in Form.Load.
Sets the socket on which the data is received. The Default is 8081. It must match the port used by VBVRLOG.EXE.
(Statistics)
Statistics information is provided by the onSetChannel... and onSetGroup... events. These events are only fired when data is requested by the page, by calling one of the methods:
getChannelData(int start, int numch)
getGroupData(int start, int numch)
getTotalData()
EXAMPLE |
If the ID of the LStat applet is LineStat and the method is called on the applet, such as: LineStat.getChannelData(1,2) Then the events onSetChannelCallDuration, onSetChannelCallSpacing, and onSetChannelUserStats will be called repeatedly, once for every channel requested. Events that are not implemented on the page will be ignored: you need only implement events that provide needed data. Similarly, the Group events are called in response to getGroupData and the Total events in response to getTotalData. |
This parameter controls how often the data is updated. the default is 1000 (ms).
Note that event prototypes are shown with their type for clarity, although JScript variables do not have types and the functions are declared in JScript without types.
onSetConnectStatus(String msg) |
This event is used to signal changes in the connect status of the Lstat applet with the server.
onSetTimes(int chnl, String channelTime, String controlTime) |
|
onSetStatus(int chnl, String status) |
|
onSetControlName(int chnl, String controlname) |
|
onSetLineName(int chnl, String linename) |
|
onSetConnectStatus(String y) |
|
onSetUserData(int chnl, int which, String y) |
onSetChannelCallDuration(int chnl, int avg, int minval, int maxval, int last, int total) |
|
onSetChannelCallSpacing(int chnl, int avg, int minval, int maxval, int last, int total) |
|
onSetChannelUserStats(int chnl, int whichuser, int avg, int minval, int maxval, int last, int total) |
onSetGroupCallDuration(int group, int avg, int minval, int maxval, int last, int total) |
|
onSetGroupCallSpacing(int group, int avg, int minval, int maxval, int last, int total) |
|
onSetGroupUserStats(int group, int whichuser, int avg, int minval, int maxval, int last, int total) |
onSetTotalCallDuration(int avg, int minval, int maxval, int last, int total) |
|
onSetTotalCallSpacing(int avg, int minval, int maxval, int last, int total) |
|
onSetTotalUserStats(int whichuser, int avg, int minval, int maxval, int last, int total) |
addEvent(String dataType) The addEvent method requests events whenever data of the requested type changes. Possible event types are:
|
|
startStatusUpdates(int startch, int numch) startStatusUpdates method initiates status updates from VBVRLOG.EXE. As data is received, events are fired into the page as specified by the addEvent method. Only data requested by addEvent is provided. |
|
|
stopStatusUpdates() stopStatusUpdates method terminates status updates from VBVRLOG.EXE. |
getChannelData(int start, int numch) |
|
getGroupData(int start, int numch) |
|
getTotalData() |
Logging and Call Details data are provided by the Java applet Log.class. It receives logging data from the VBVoice application monitor VBVRLOG.EXE, which must be running on the same machine as that providing the web server. As new data is received, it is displayed in a list box provided by the applet.
Allows the web page designer to set the channel for which data is to be received. The default is 1.
Sets the categories of logs that are to be received. To reduce network traffic, you may want to limit which logs are transmitted. This parameter should be supplied as an 8 character hex number.
EXAMPLE |
<param name = Filter value = 00001CFC |
Sets the socket on which the data is received. The default is 8081 and it must match the port used by VBVRLOG.EXE.
None
Clears the log list display |
AgentX integration is provided by the AgentX.class java applet. The AgentX applet receives messages from the server and stores them in a queue. It also fires an event into the web page whenever a message arrives. Data from each message can be retrieved using the getNextMessage, getNextMessageKey, and getMessageData methods.
AgentX messages can also be sent to the server using the AddData and Send methods. Messages sent by the AgentX applet are received by any AgentX application running on the server. They are not automatically broadcast across the server network.
Sets the socket on which the data is received. The default is 700 and must match the port used by the ConversationServer on the server. The server can change the port number in use by changing this setting in vbvoice.ini:
[agentx]
port = 700
Restart your computer for this setting to take effect.
|
onMessage(int size) The onMessage event signals that an AgentX message has been received. The size parameter indicates how many key/value pairs are available in this message. The message data can be retrieved using the methods described below. |
onSetConnectStatus(String msg) The onSetConnectStatus event is used to signal changes in the connect status of the Lstat applet with the server. |
int AddData(String key, String data) See Send below. |
|
int Connect(String appid, int events) |
|
int Disconnect() Connect and Disconnect are used to connect the applet to the server and are equivalent to the Connect and Disconnect methods in the AgentX control. Messages cannot be sent or received until a connection is made. Connect and Disconnect return the value 0 if successful. Remember that if you expect a reply from the server, you should not disconnect until it has been received. It is a good idea to use a timer (SetInterval function) to ensure that the connection is always disconnected. |
|
int getNextMessage() See getMessageData. |
|
String getNextMessageKey() See getMessageData |
|
String getMessageData() These three methods are used to retrieve data from incoming AgentX messages. When an incoming message is signalled, the getNextMessageKey method can be used to retrieve the name of the first key from this message. The getMessageData returns the data associated with this key. These two functions can be called repetitively to retrieve all data associated with the message. The getNextMessageKey function will return a null string when all keys have been enumerated. The getNextMessage function will clear the current message from the queue. EXAMPLE This example is taken from admin.htm (where is this?) and it demonstrates the use of the AgentX control and the onMessage event. This event iterates through all waiting messages and for each message it prints the key and value names to a DHTML object agentxdata. function onMessage(sz) { var key; alert (sz + " messages received") vkey = agentx.getNextMessageKey(); var obj = document.all.agentxdata obj.innerHTML = sz + " messages received<BR>" do //iterate over all messages { while (vkey!= null) //iterate over all keys { vdata = agentx.getMessageData(); document.all.agentxdata.innerHTML = obj.innerHTML += "key: '" + vkey + "' - data: '" + vdata + "'<BR>"; vkey = agentx.getNextMessageKey(); } vkey = agentx.getNextMessageKey(); } while (agentx.getNextMessage()!= 0); } |
|
int Send() This method is used with the AddData method to send AgentX messages to the server. A message can be built by calling AddData repetitively, once for each key/value pair required. The Send method is then used to send the message to the server. Send returns 0 if successful. EXAMPLE: sending a message // connect with the appid "CALLME" var ret = agentx.Connect("CALLME", 1); if (ret) { alert("failed to connect: error code " + ret) return; } // add 2 keys, "dial" and "customer" agentx.AddData("dial", "aaa"); agentx.AddData("customer", "aaaaaa"); //send the message ret = agentx.Send(); if (ret) { alert("failed to send: error code " + ret) return; } // we don't want replies so disconnect now var ret = agentx.Disconnect(); if (ret) { alert("failed to disconnect: error code " + ret) return; } EXAMPLE: receiving a message event handler:
<script language="JScript" for="agentx" event="onMessage(sz)"> This function iterates through all the messages waiting and processes each key in each message. If a key Alert is found, a message box is displayed. The key and value are set to a DHTML element for display. function onMessage(sz) var key; alert (sz + " messages waiting from server") vkey = agentx.getNextMessageKey() var obj = document.all.agentxdata obj.innerHTML = sz + "messages received<BR>" for (i = 0; i < sz; i++) { while (vkey!= null) { vdata = agentx.getMessageData(); if (vkey == "Alert") { window.alert(vdata) } document.all.agentxdata.innerHTML = obj.innerHTML += "key " + vkey + " - data " + vdata + "<BR>"; vkey = agentx.getNextMessageKey(); } //delete cur message, get next agentx.getNextMessage(); } } |
The example web pages provided below make extensive use of JScript and DHTML (Dynamic HTML).
There are many references available to help you learn more about these subjects, including the JScript reference and the Microsoft Site Builder web page (both available from the Microsoft web site).
Example web pages are provided to show all the internet capabilities of VBVoice netWorks. These are:
|
Web Page |
Associated VB program |
See Page |
Statistics |
stats_1.htm |
admin.vbp |
?????? |
|
stats_2.htm |
admin.vbp |
|
|
stats_3.htm |
admin.vbp |
|
|
stats_all.htm |
admin.vbp |
|
AgentX |
agentx_callme.htm |
callme.vbp |
|
|
admin.htm |
admin.vbp |
|
LineStatus |
lstatbasic.htm |
admin.vbp |
|
|
lstatcfg.htm |
admin.vbp |
|
|
admin.htm |
admin.vbp |
|
Logs and Call Details |
logs.htm |
Any VBVoice application |
|
|
channellog1.htm |
Any VBVoice application |
|
|
channellog2.htm |
Any VBVoice application |
|
|
admin.htm |
admin.vbp |
|
This example page includes a basic linestatus display. It uses a fixed-size HTML table (4 channels) to display the data.
The applet is instantiated using the following code:
Applet Declaration |
<applet code="lstat.class" width=1 height=1 id="linestat"> Note that the parameter FiresScriptEvents must always be set to true to enable scripting events. The Updateperiod defines how often data on the page is refreshed. |
maketable function |
maketable(startchan, numchans) The maketable function is a general purpose function that creates a DHTML table. It creates the table based on parameters provided and initializes the LineStat class. |
Onload function |
The declaration for the page references the onload event, which initializes the applet:
<script language="JScript" for="window" event="onload()"> This code enables the events for changes in the LineName, Status, ControlName, ChannelTime, and ControlTime fields. |
startStatusUpdates |
It then initiates status updates by calling the startStatusUpdates function for channels 1 to 4. |
Table declaration |
The table declaration is declared with the id 'table1', and contains rows for each channel, and columns for each data type. Each cell has an id, such as Status1, or Linename2, so that it can be identified and modified in the applet events. |
onSetStatus event |
<script language="JScript" for="linestat" event="onSetStatus(chnl, status)"> Above is the event handler for the onSetStatus event from the applet. It in turn calls the onSetStatus function, declared as follows: function onSetStatus(chnl, status) { var objid; objid = "Status" + chnl.toString(10); var obj = document.all(objid); if (obj!= null) obj.caption = status; } This code finds the object associated with the Status field for the appropriate channel by using the ID (such as Status1) to reference the HTML object model: var obj = document.all(objid); The text for this cell is then changed using the caption property: obj.caption = status where status is the data provided by the applet event. |
This example is similar to the LStatBasic example, except that it dynamically creates the display grid to match the number of required channels. In addition, instead of using DHTML <span> fields to update the display, it uses a Label control for each field. This provides better response time for larger systems or systems with a lot of activity.
In addition, this page provides command buttons and spin buttons to adjust the number of channels to display.
The lstatcfg.htm page also displays one UserData column. The data is set by the Admin.vbp example to the mailbox selected and there can be up to four userdata columns in a linestatus display. Each is set using the SetLineStatusExtra function of the VBVLog object.
This is a basic display of statistics information, namely call counts and average call durations.
HTML body elements |
The body of the HTML page contains two elements, the lstat java applet and a table to display the data. |
Lstat applet |
The applet declaration is identical to the other examples and has been described previously. |
Table definition |
The table provides 3 columns, for average call duration, call count and total call count, and 4 rows, for channels 1 to 4. Each cell in the table has an ID, which is used to reference the cell when updating the data. Shown below is one row from this table:
<TR> The and <b> elements are for formatting only and have been removed from the sample above for clarity. |
SCRIPTING: |
|
refreshData |
function refreshData() { linestat.getChannelData(1,4) //get channels 1 to 4 linestat.getTotalData(); } This function calls the getChannelData function in the lstat applet which requests a data update from the server. When the data arrives, the onSetChannelCallDuration will be called. Similarly, the getTotalData function is called, which will result in an onSetTotalCallDuration event. |
Onload event |
The body declaration for the page references the onload event, which calls the refreshData function, and the setInterval function. This performs a one-time update of the required data, and sets up a timer to call refreshData every 5 seconds. <body onload="refreshData();setInterval('refreshData(),5000);"> <h2> Call Statistics Example - basic measurements</h2> |
settextvalue |
This is a utility function that sets a value to an HTML element, given a HTML id and a new value. |
onSetChannelCallDuration event |
This event is called by the lstat applet when new call duration data is received from the server. In this implementation, the new values are set into the table using the settextvalue function.
<script language="JScript" for="linestat" event="onSetChannelCallDuration(chnl, avgval, minval, maxval, last, total)"> |
onSetTotalCallDuration event |
This event is called by the lstat applet when new data for total call duration is received from the server. It is used to update the table in the same way as onSetChannelCallDuration.
<script language="JScript" for="linestat" event="onSetTotalCallDuration(avgval, minval, maxval, last, total)"> |
This page builds upon the foundation in Stats_1.htm. In this example, HTML is used to draw charts of the various values. The charts are created dynamically using HTML which both reduces the size of the page to download by having the page created on the client by code, and makes it easily configurable by parameter changes, and also avoids code duplication errors by defining each line of the table once.
This page also displays call frequency per channel as well as call durations.
The key elements in this page are:
the createChart function
the setvalue function
the placeholders for the charts
The createChart function dynamically creates a HTML table that displays the data. Each table uses a name which identifies both the placeholder, where the chart is to be drawn, and the name of the elements within it.
The table contains the following elements:
A header row containing the scale of the chart
Three <SPAN>elements, IDs = name + _avg, name + _min, name + _max which are drawn horizontally one above the other, for min, average and max values. Each is named using the ID tag so that the contents can be updated using DHTML
A text area, ID name + _value, used to display the text field containing the chart values
A text area, ID = name + _totalcnt, used to display the number of calls for that channel
As with Stats_1.htm, the refreshData function is used to request the data from the server.
This function is used to convert the call spacing values (in seconds) into call frequency (calls per hour).
This is an HTML input element used to manually refresh the statistics data using the refreshData function.
This page builds upon the foundation in Stats_1.htm and Stats_2.htm. It uses the Groups capability to sort the statistics data by mailbox. For automated testing purposes, the mailboxes are selected by a random number generator for channels 2 to 4 in the Admin example. Channel 1, which takes incoming calls, selects the mailbox based on user input.
The Groups capability allows us to show the number of calls for each mailbox, as total calls per mailbox, as call frequency per mailbox, and as call duration per mailbox.
A user-defined measurement is also used to perform timing on the call while the caller is in the Messages form. These timings are displayed for the mailbox selected by the caller.
Calls are assigned to groups using the AddCallToGroup function. In this case we have defined 4 groups for 4 different mailboxes, however there can be as many as you need.
Timing is performed by entering a CallTimer control ahead of the main messaging block on the Message page. The CallTimer is set to expire when the call leaves the page, and either disconnects or returns to the main page. The UserStat1 variables time is loaded from the DurationSecs property of the CallTimer to the User statistic 1 with the following code in the Count1 Exit event:
Dim myuserstat As VBVStat
Set myuserstat = mystats.ChannelStatistic(channel).UserStat(1)
myuserstat.Last = CallTimer1.DurationSecs(channel)
This page is a culmination of the stats_1.htm, stats_2.htm, and stats_3.htm examples. It is similar to stats_3.htm and shows usage of the LineStat java applet, DHTML charts, plus methods for combining data from channels, groups and total statistics. Explanations for individual components that make up the stats_all htm can be found in the previous 3 stats examples.
This page shows how to put a log window into your own web page, and also how to create new browser windows containing log displays.
To add a long window to an existing page, add the HTML below, substituting the required channel number:
<applet code=logwindow width=400 height=200>
<param name = "channel" value = "1">
</applet>
No additional code is required to display the log data.
Logs.htm contains three buttons which demonstrate how to create and show log windows as required, either using a predefined page or by dynamically using a template html file, logchan.htm.
The code for the Channel 1 button uses the window.open method to create a new Internet Explorer window, containing the required page. A different page is required for each channel to be displayed.
Only one file is required: logchan.htm. This file contains a placeholder SPAN element with ID=logapplet, which is used to create an instance of the log applet with the required parameters. In logs.htm, see the code for the click event for anychbut, and the makelogwindow() and makechannelwindow() functions.
This page shows how to integrate AgentX into a web page. It works with the CallMe.vbp Visual Basic project. The CallMe button on the page connects to the AgentX control using the AppId callme. A key dial with the value containing the number to dial, as entered on the page.
In the OnAgentX1Message event, the keys are enumerated until the correct key is found. The code then attempts to find a line that is not idle, and if found, initiates a call on that line. The number to dial is stored in a transfer property for use by the Dial control.
This page brings together most of the capability of VBVoice Web integration onto one page. It is a combination of the lstatcfg.htm page which contains the configurable linestatus display, remote control of a VBVoice application using Agentx commands, and logging.
The page contains a button to execute a StartSystem and StopSystem on the VBVoice application and also has implemented popup menu commands for the linestatus display to provide control over each channel, including start and stop channel, and log display commands.
This example shows how to use AgentX in conjunction with the NT Service control to allow a system administrator to start and stop VBVoice applications (or any other application) from a web page. Note that there are security considerations that should be taken into account - as you may need to control who can make changes to the system.
The AppStart.vbp Visual Basic project contains an AgentX control to receive messages from clients and an NT Service control to allow it to run as a service.
If the AgentX control receives a key called appstart on AppID application, it will run the application defined by the path in the value element. The application handle is returned to the client.
The best way to stop an application is by sending a message direct to the application using AgentX. Alternatively the application can be stopped by sending an appstop key to the AppSstart service.
Another way of stopping an application is to send an appstop key to the AppStart service, with the key value equal to the handle previously returned. AppStart will then send an F4 keystroke to the application which will normally close the application.