Vizard 7 » Reference » Graphical user interfaces (GUIs) » HTML and web browsers » WebSocket communication
7.7

WebSocket Communication

Real time bidirectional communication between Vizard and a web browser is supported using WebSockets. You can send and receive messages and find out when socket connections open or close. On the server (Vizard) side, the vizhtml module provides Vizard commands for sending messages and handling message and connection events. Similar functionality is provided on the client (browser) side using JavaScript functions through vizhtml's JavaScript library.

 

All the major web browsers support WebSockets. The minimum supported version for each browser is:

Vizard commands

Use the following commands to send WebSocket messages and get information about connected clients:

Command

Description

vizhtml.sendAll(event,

                     data)

Sends WebSocket data to all connected clients.

 

event: A string value that defines the event name.

 

data:  Any basic object type (e.g. int,  string , list, ...) or a viz.Data object.

vizhtml.getClientList()

Gets a list containing the currently connected clients. Each element in the list is an instance of the vizhtml.WebSocketClient class.

vizhtml.getClientCount()

Returns the number of currently connected clients.

Sending data to a specific client is accomplished through it's associated vizhtml.WebSocketClient object. You can get a handle to this object when a WebSocket event occurs (e.g. connection event) or by using the vizhtml.getClientList() command. Each object provides the client's IP address and a method to send it data:

Attribute

Description

<WebSocketClient>.address

The IP address of the client.

 

Method

Description

<WebSocketClient>.send(event,

                                  data)

Sends WebSocket data to the client.

 

event: A string value that defines the event name.

 

data:   Any basic object type (e.g. int,  string , list, ...) or a viz.Data object.

Handling events

The following events will get triggered when messages are received and connections are opened and closed:

Event

Description

vizhtml.MESSAGE_EVENT

Generated when a WebSocket message is received. It provides a single event structure e with the following attributes:

 

e.event: A string with the event name. This should match an event_name defined in a <VizardWebSocket>.send command (described in the JavaScript section below).

 

e.data: The data sent.

 

e.client: A vizhtml.WebSocketClient object.

vizhtml.CONNECT_EVENT

Generated when a WebSocket client connects. It provides a single event structure e with the following attribute:

 

e.client: A vizhtml.WebSocketClient object.

vizhtml.DISCONNECT_EVENT

Generated when a WebSocket client disconnects. It provides a single event structure e with the following attribute:

 

e.client: A vizhtml.WebSocketClient object.

Use the following commands to register callback functions for these events:

Command

Description

vizhtml.onMessage(event,

                          func,

                          *args,

                          **kw)

Registers a callback function for a message event:

 

event: A string with the event name. This should match an event_name defined in a <VizardWebSocket>.send command (described in the JavaScript section below).

 

func: The function being registered. An event object e, described in the table above (see vizhtml.MESSAGE_EVENT) will be passed to the callback function.

 

*args: Optional arguments to pass to the registered function.

 

**kw: Optional keyword arguments to pass to the registered function.

vizhtml.onConnect(func,

                         *args,

                         **kw)

Registers a callback function for a WebSocket connection event:

 

func: The function being registered. An event object e, described in the table above (see vizhtml.CONNECT_EVENT) will be passed to the callback function.

 

*args: Optional arguments to pass to the registered function.

 

**kw: Optional keyword arguments to pass to the registered function.

vizhtml.onDisconnect(func,

                             *args,

                             **kw)

Registers a callback function for WebSocket disconnection event:

 

func: The function being registered. An event object e, described in the table above (see  vizhtml.DISCONNECT_EVENT) will be passed to the callback function.

 

*args: Optional arguments to pass to the registered function.

 

**kw: Optional keyword arguments to pass to the registered function.

Javascipt commands

Use vizhtml's JavaScript library to create a WebSocket client that communicates with vizhtml's HTTP server. In order to access the library within your own JavaScript code, link to vizhtml.js as an external script:

<script type="text/javascript" src="vizhtml.js"></script>

To implement a WebSocket client create an instance of the viz.WebSocket class. Before creating a WebSocket, you can check whether the browser supports WebSockets by calling the viz.isWebSocketSupported() command. This provides a way to display a helpful error message to the user.

 

The following methods are available on the viz.WebSocket object:

Method

Description

<WebSocket>.onevent(event_name,

                                        func)

Registers a callback function for an event.

 

event_name: A string with the event name. For message events, this argument should match an event value defined in one of the server commands (either vizhtml.sendAll or <WebSocketClient>.send). Otherwise, see the table below for connection event values.

 

func: The JavaScript function being registered. An event object e with the following attributes will be passed to the callback function:

  • e.event: A string with the event name. This is the same as the event_name argument.
  • e.data: The event data.

<WebSocket>.send(event_name,

                                   event_data)

Sends data to the WebSocket server.

 

event_name: A string value that defines the event name.

 

event_data:  Any basic object type (e.g. int,  string , array, ...) or the return object from the viz.Data function.

The table below lists event_name values for connection events,

Value

'open'

'close'

'error'

Sending a viz.Data object to Vizard

If you want the JavaScript code to send an object that appears to Vizard as a viz.Data object, then you can use the viz.Data JavaScript function:

Command

Description

viz.Data(data)

Returns an object that will be converted to a viz.Data object when sent to the vizhtml server.

 

data: a JavaScript associative array that uses strings as keys.

In the following JavaScript code, the integer value stored in click_count is sent as the count attribute of a viz.Data object:

var click_count = 0;
function onButtonClick()
{
    click_count += 1;
    socket.send( 'button_click' , viz.Data({'count':click_count}) );
}

In Vizard, the following code retrieves and prints the value:

def OnButtonClick(e):
    data = e.data
    print('BUTTON CLICK',data.count)
vizhtml.onMessage('button_click',OnButtonClick)

Example

The following example script shows how to communicate between Vizard and a browser via WebSockets.

Note: If no communication occurs it's likely your browser does not support WebSockets.

For testing on a local browser use 'localhost' or the loopback address:

 

http://localhost:8080/vizhtml/websocket

http://127.0.0.1:8080/vizhtml/websocket

 

For remote browsers replace computer name or IP address with the Vizard machine's name or address

 

http://computer name:8080/vizhtml/websocket

http://IP Address:8080/vizhtml/websocket

import viz
import vizhtml
viz.go()

code = """
<html>
<head>
    <title>vizhtml WebSocket Example</title>
    <script type="text/javascript" src="vizhtml.js"></script>
</head>
<body>
<script language="javascript">

var socket = new viz.WebSocket();

socket.onevent('open', function(e){
    document.getElementById('status').innerHTML = 'connected';
    document.getElementById('my_button').disabled = false;
})

socket.onevent('close', function(e){
    document.getElementById('status').innerHTML = 'waiting for connection';
    document.getElementById('my_button').disabled = true;
    socket.reconnect();
})

socket.onevent('set_time', function(e){
    document.getElementById('script_time').innerHTML = e.data.time;
})

var click_count = 0;
function onButtonClick()
{
    click_count += 1;
    socket.send( 'button_click' , viz.Data({'count':click_count}) );
}

</script>

<div>Status:</div><div id='status'>waiting for connection</div></br>
<div>Time:</div><div id='script_time'></div></br>
<div><input id='my_button' type=button value="Send Message" onclick="onButtonClick();"></div></br>
</body>
</html>
"""

# http://localhost:8080/vizhtml/websocket
vizhtml.registerCode('websocket',code)

def ClientConnect(e):
    print('Client connected at',e.client.address)
vizhtml.onConnect(ClientConnect)

def ClientDisconnect(e):
    print('Client disconnected at',e.client.address)
vizhtml.onDisconnect(ClientDisconnect)

def SendTime():
    d = viz.Data(time='%.1f'%(viz.tick()))
    vizhtml.sendAll('set_time',d)
vizact.ontimer(0.1,SendTime)

def OnButtonClick(e):
    print('BUTTON CLICK',e.data.count,'from',e.client.address)
vizhtml.onMessage('button_click',OnButtonClick)

vizhtml introduction

HTML Forms in Vizard

HTML Forms in a remote browser

Collecting form data

Local HTTP server and URLs

WebSockets