Bidirectional communication between a web page and Processing using websockets

I made a simple example of communicating a web page and a Processing sketch using websockets. It requires the Processing library called Websockets.

Why would you want to do this? There’s many possible reasons, but one of them is that it’s very easy to make a GUI in HTML. Maybe you want to have a GUI on your phone or in a tablet.

What I like about this approach is that if you are running it locally you don’t need a web server. So it’s just double clicking on an HTML file, running your Processing sketch, and then the two can interact.

Here’s the Processing code:

import websockets.*; // remember to install this library!

WebsocketServer ws;
color bg;
int x = 0;

void setup() {
  size(200, 200);
  ws = new WebsocketServer(this, 8025, "/processing");
  bg = color(random(255), random(255), random(255));
}

void draw() {
  background(bg);
  line(x, 0, x, height);
}
void mousePressed() {
  ws.sendMessage("/mouse/" + mouseX + "/" + mouseY);
}

void webSocketServerEvent(String msg) {
  println(msg);
  String[] cmd = msg.split("/");
  switch(cmd[1]) {
    case "background":
      bg = color(random(255), random(255), random(255));
      break;
    case "x":
      x = Integer.parseInt(cmd[2]);
      break;
  }
}

Here’s a simple HTML page with some JavaScript for handling the websocket connection.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
      <meta http-equiv="Content-Security-Policy" 
           content="connect-src * 'unsafe-inline';">
        <style>
            div { margin-bottom: 20px; }
        </style>
    </head>
    <body>
        <div id="disconnected">
            <input id="btnConnect" type="button" value="Connect" 
     onclick="openWSConnection('ws', 'localhost', 8025, '/processing');">
        </div>
       
        <div id="connected">
            <div>
            Pressing this button should change the 
            background color in Processing<br/>
            <input type="button" id="btnSend" value="Change background" 
                   onclick="onSend('/background')">
            </div>
            
            <div>
            This slider will move a line in Processing<br/>
            <input type="range" id="size" min="0" max="127" 
                   oninput="onSend('/x/' + this.value);">
            </div>
            
            <div>
            This text will change when you click the mouse in Processing<br/>
            <input type="text" id="info" vlaue="">
            </div>
            
            <input id="btnDisconnect" type="button" value="Disconnect" onclick="webSocket.close();">
        </div>

        <script>
var webSocket = null;
var divDisconnected = document.getElementById('disconnected');
var divConnected = document.getElementById('connected');

function onConnectionChange(conn) {
    divConnected.style.display = conn ? 'block' : 'none';
    divDisconnected.style.display = conn ? 'none' : 'block';
}
onConnectionChange(false);

function openWSConnection(protocol, hostname, port, endpoint) {
    var webSocketURL = null;
    webSocketURL = protocol + "://" + hostname + ":" + port + endpoint;
    console.log("openWSConnection::Connecting to: " + webSocketURL);
    try {
        webSocket = new WebSocket(webSocketURL);
        webSocket.onopen = function(openEvent) {
            onConnectionChange(true);
        };
        webSocket.onclose = function (closeEvent) {
            onConnectionChange(false);
        };
        webSocket.onerror = function (errorEvent) {
            console.log("WebSocket ERROR: " + JSON.stringify(errorEvent, null, 4));
        };
        webSocket.onmessage = function (event) {
            if (event.data.indexOf("error") > 0) {
                console.log("WebSocket message error: " + event.data.error);
            } else {
                var cmd = event.data.split('/');
                switch(cmd[1]) {
                    case 'mouse':
                        document.getElementById('info').value = 'mouse clicked: ' + cmd[2] + ', ' + cmd[3];
                        break;
                }
            }
        };
    } catch (exception) {
        console.error(exception);
    }
}

function onSend(val) {
    if (webSocket.readyState != WebSocket.OPEN) {
        console.error("webSocket is not open: " + webSocket.readyState);
        return;
    }
    webSocket.send(val);
}            
        </script>
    </body>
</html>
5 Likes