cf2:WebSocket

Purpose

This component provides a JavaScript API that enables web applications to use the WebSocket protocol for communication with remote hosts. WebSocket data frames can be sent between the client and the server in full-duplex mode (i.e. in two directions simultaneously) without relying on multiple HTTP connections. The mechanism uses the Origin-based security model. Please refer to WebSocket.org for more information about the WebSocket protocol.

The following API is based on the WebSocket API.

Exported Features

cf2:WebSocket

Imported Features

n/a

JavaScript

The V$.net.WebSocket object provides the following methods:

WebSocket(url, protocols)

The WebSocket object constructor.

Parameter Description Type
url The URL to connect to. String
protocols The name of the sub-protocol(s) that the client is intending to use (over the WebSocket protocol). The parameter, if present, is either an array of strings or a string, in which case it is equivalent to an array consisting of just that string. If it is omitted, it is equivalent to an empty array. Each string in the array is a sub-protocol name. The connection will only be established if the server reports that it has selected one of these sub-protocols. The sub-protocol names must all be non-empty ASCII strings without control characters and spaces. String or Array of Strings
void send(string data)

Transmits the data using the connection.

Parameter Description Type
data The data to send. String
void close()

Closes the connection.

void setOnOpen(openCallback)

Sets the callback function for the cf2:webSocketOpen event. The event is fired whenever a WebSocket connection is established.

Parameter Description Type
openCallback A callback function to be executed whenever the cf2:webSocketOpen event is fired. Function
Function getOnOpen()

Returns the callback function associated with the cf2:webSocketOpen event.

void setOnMessage(messageCallback)

Sets the callback function for the cf2:webSocketMessage event. The event is fired whenever the data are received from a server.

Parameter Description Type
messageCallback A callback function to be executed whenever the cf2:webSocketMessage event is fired. Function
Function getOnMessage()

Returns the callback function associated with the cf2:webSocketMessage event.

void setOnError(errorCallback)

Sets the callback function for the cf2:webSocketError event. The event is fired whenever a communication error occurs.

Parameter Description Type
errorCallback A callback function to be executed whenever a communication error occurs. Function
Function getOnError()

Returns the callback function associated with the cf2:webSocketError event.

void setOnClose(closeCallback)

Sets the callback function for the cf2:webSocketClose event. The event is fired whenever a WebSocket connection is closed.

Parameter Description Type
closeCallback A callback function to be executed when the cf2:webSocketClose event occurs. Function
Function getOnClose()

Returns the callback function associated with the cf2:webSocketClose event.

string protocol()

Returns the protocol name. Please note that until the connection is established, the method returns an empty string.

short readyState()

Returns the state of the connection. It can have the following values:

Numeric value Constant Description
0 CONNECTING The WebSocket connection has not yet been established.
1 OPEN The WebSocket connection is established and communication is possible.
2 CLOSING The WebSocket connection is closing down.
3 CLOSED The WebSocket connection has been closed.
long bufferedAmount()

Returns the number of bytes of UTF-8 text that have been queued but not yet sent using the send() method.

boolean isDisabled()

Devices that support the WebSocket protocol may allow users to disable the use of this protocol. The isDisabled() method verifies if WebSocket support is enabled on the requesting device. If it is enabled, the method returns 'false'; otherwise the method returns 'true'. Please note that the method can be used without creating a WebSocket connection instance.

Events

Whenever a WebSocket connection is closed, an instance of the cf2:webSocketClose event is created and passed to the closeCallback callback function.

cf2:webSocketClose
Property Description Type
code The WebSocket connection close code provided by the server. String
reason The WebSocket connection close reason provided by the server. String
target The WebSocket object whose connection was closed. WebSocket

Whenever an error in communication occurs, an instance of the cf2:webSocketError event is created and passed to the errorCallback callback function.

cf2:webSocketError
Property Description Type
data The message received from the server. String
target The WebSocket object whose connection encountered problems. WebSocket

Whenever the data are received from a server, an instance of the cf2:webSocketMessage event is created and passed to the messageCallback callback function.

cf2:webSocketMessage
Property Description Type
data The message received from the server. String
target The WebSocket object that received the message. WebSocket

Whenever a WebSocket connection is established, an instance of the cf2:webSocketOpen event is created and passed to the openCallback callback function.

cf2:webSocketOpen
Property Description Type
target The WebSocket object whose connection was opened. WebSocket

Example

The following example uses the echo server provided by WebSocket.org to illustrate the use of the API. Click the Connect button to connect to the server. Once connected, enter a message and press the Send button. The server will return the message.

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/2002/06/xhtml2"
  xmlns:ui="http://www.volantis.com/xmlns/2009/07/cf2/ui"
  xmlns:cf2="http://www.volantis.com/xmlns/2009/07/cf2"
  xmlns:cst="http://www.volantis.com/xmlns/2009/07/cf2/template"
  xmlns:mcs="http://www.volantis.com/xmlns/2006/01/xdime/mcs"
  xmlns:sel="http://www.w3.org/2004/06/diselect"
  xmlns:xforms="http://www.w3.org/2002/xforms"
  xmlns:si="http://www.volantis.com/xmlns/2006/01/xdime2/si">
  <head>
    <title>cf2:WebSocket</title>
    <style type="text/css">
      ui|button {
        padding: 2px 4px 2px 4px;
        margin-right: 4px;
        font-weight: bolder;
        color: #000000;
        border: 0px;
        font-family: sans-serif;
      }
      #connectBtn:disabled, #disconnectBtn:disabled, #sendBtn:disabled {
        color: #aaa;
      }
      #console {
        width: 80%;
        margin: 5px; 
        background-color: #ddd;
        padding: 1px;
        font-size: small;
      }
      #console_title {
        background-color: #444;
        padding: 2px;
      }
      #console_content {
        padding: 5px;
        height: 100px;
        overflow: auto;
      }
      .console_message {
        color: #000;
      }
      .date {
        padding: 0 5px;
      }
      .user {
        padding: 0 5px;
        font-weight: bold;
      }
      #console_input {
        padding: 5px;
        color: #000;
        text-align: center;
      }
      #console_buttons {
        padding: 1px 5px 5px 5px;
      }
      #msg {
        width: 99%;
        border: 1px solid #444;
        padding: 3px;
        font-size: small;
        margin: auto;
      }
    </style>
    <xforms:model>
      <xforms:instance>
        <si:instance>
          <si:item name="url">ws://echo.websocket.org</si:item>
          <si:item name="msg"></si:item>
        </si:instance>
      </xforms:instance>
      <xforms:submission id="submissionId"/>
    </xforms:model>
    <mcs:script src="/scripts/websocket.mscr"/>
    <mcs:script type="text/javascript">
      var msgPrototype;
      var container;
      V$C.starting(function(c) {
        msgPrototype = c.get('message_prototype');
        container = c.get('console_content');
        c.get('disconnectBtn').setEnabled(false);
        c.get('sendBtn').setEnabled(false);
      });
      var socket;
      function getCurrentDate() {
        var date = new Date();
        var minutes = date.getMinutes();
        var seconds = date.getSeconds();
        if (seconds &lt; 10){
          seconds = "0" + seconds
        }
        if (minutes &lt; 10){
          minutes = "0" + minutes
        }
        var result = date.getHours() + ':' + minutes + ':' + seconds;
        return result;
      }
      function printMessage(date, user, msg) {
        var p = msgPrototype.construct();
        var template = p.get('message_tpl');
        var m = p.outer();
        container.inner().appendChild(m);
        date = "[" + date + "]";
        template.setData({"date":date, "user":user, "message":msg});
        container.inner().scrollTop = container.inner().scrollHeight;
      }
    </mcs:script>
  </head>
  <body>
    <sel:select>
      <sel:when expr="mcs:feature('cf2:WebSocket')">
        <table>
          <tr>
            <td>Server: </td>
            <td>
              <xforms:input ref="url" id="url" size="10">
                <xforms:label/>
              </xforms:input>
              <ui:button id="connectBtn">
                Connect
                <cf2:on event="cf2:activate">
                  <cf2:param name="cBtn" component="connectBtn"/>
                  <cf2:param name="dBtn" component="disconnectBtn"/>
                  <cf2:param name="sendBtn" component="sendBtn"/>
                  if(V$.net.WebSocket.isDisabled()) {
                    printMessage(getCurrentDate(), 'WebSocket disabled!', '');
                  } else {
                    printMessage(getCurrentDate(), 'Connecting...', '');
                    socket = new V$.net.WebSocket(V$E('url').value);
                    cBtn.setEnabled(false);
                    dBtn.setEnabled(true);
                    sendBtn.setEnabled(true);
                    socket.setOnOpen(function(evt) {
                      printMessage(getCurrentDate(), 'Connected!', '');
                    })
                    socket.setOnClose(function(evt) {
                      printMessage(getCurrentDate(), 'Connection closed!', '');
                    })
                    socket.setOnMessage(function(evt) {
                      printMessage(getCurrentDate(), 'server: ', evt.data);
                    })
                    socket.setOnError(function(evt) {
                      printMessage(getCurrentDate(), 'Error! ' + evt.data, '');
                    })
                  }
                </cf2:on>
              </ui:button>
              <ui:button id="disconnectBtn">
                Disconnect
                <cf2:on event="cf2:activate">
                  <cf2:param name="cBtn" component="connectBtn"/>
                  <cf2:param name="dBtn" component="disconnectBtn"/>
                  <cf2:param name="sendBtn" component="sendBtn"/>
                    if (socket) {
                      cBtn.setEnabled(true);
                      dBtn.setEnabled(false);
                      sendBtn.setEnabled(false);
                      socket.close();
                      socket = null;
                    }
                </cf2:on>
              </ui:button>
            </td>
          </tr>
        </table>
        <div id="console">
          <div id="console_title">Console</div>
          <ui:prototype id="message_prototype">
            <cst:template id="message_tpl">
              <div class="console_message">
                <span class="date"><cst:value path="date"/></span>
                <span class="user"><cst:value path="user"/></span>
                <span class="message"><cst:value path="message"/></span>
              </div>
            </cst:template>
          </ui:prototype>
          <ui:box id="console_content"></ui:box>
          <div id="console_input">
            <xforms:input ref="msg" id="msg">
              <xforms:label/>
            </xforms:input>
          </div>
          <div id="console_buttons">
            <ui:button id="sendBtn">
              Send
              <cf2:on event="cf2:activate">
                var msg = V$E('msg').value;
                if(socket) {
                  printMessage(getCurrentDate(), 'you:    ', msg);
                  V$E('msg').value='';
                  socket.send(msg);
                } else {
                  printMessage(getCurrentDate(), 'Not connected!', '');
                }
              </cf2:on>
            </ui:button>
          </div>
        </div>
      </sel:when>
      <sel:otherwise>
        <div class="warning">
          The WebSocket protocol is not supported on this device.
        </div>
      </sel:otherwise>
    </sel:select>
  </body>
</html>

The websocket.mscr script policy must import the cf2:WebSocket feature.

Related topics