Creating a WebSocket web application and setting up a proxy

September 11, 2023

Lang: cs en de es

The development of modern web applications is constantly moving towards greater interactivity and faster communication between client and server. Technology like WebSocket plays a key role in this direction. In this, you will learn how to create an application with WebSocket and how to properly configure proxies to make WebSockets work. With this, you will then be able to create and run a highly interactive application that will provide a good user experience.

WebSocket Protocol

WebSocket is a protocol that allows two-way communication between client and server, making it an ideal choice for applications, that require fast and reactive data updates.
WebSocket is a communication protocol designed for interactive communication between web browsers and web server applications. Its main purpose is to provide a persistent two-way connection between the client (browser) and the server that allows for immediate and efficient data transfer. WebSocket is often used in modern web applications that require fast and interactive communication between clients and server. Compared to traditional techniques such as AJAX or "long polling", WebSocket provides a more efficient and direct means for real-time data transfer.

Appropriate uses of WebSocket

Here are some examples of what WebSocket is suitable for:

  • Real-time applications:
  • WebSocket is suitable for developing applications that require instant and continuous communication between client and server. This is useful for chat applications, online games, collaborative tools, and other applications that need fast data synchronization between different users of the application.
  • Real-time updates:
  • WebSocket allows the server to send updates and alerts to clients without having to poll the server repeatedly. This reduces the load on the server and speeds up the response to events.
  • Data streaming, This allows large volumes of data or a continuous audio/video stream to be transmitted sequentially without requiring a complete load or dropping the connection.
  • Efficient communication:
  • WebSocket is designed to minimize communication overhead and allow efficient data transfer between client and server. The protocol is optimized to reduce latency and ensure low communication delay.

Inappropriate use of WebSocket

WebSocket is not suitable for every type of communication and there are situations where other protocols or technologies may be a better choice. Here are some examples where WebSocket may not be the best fit:
  • Traditional Websites: When it comes to regular static websites, that don't need instant two-way communication between client and server, using WebSocket is redundant. For these purposes, the regular HTTP protocol or its encrypted version of HTTPS, which secures the communication with a certificate.
  • One-way communication: when the application requires only one-way communication from the server to the client (for example, sending updates or information from the server), There are simpler alternatives, such as Server-Sent Events (SSE) or long polling techniques that may be a better fit.
  • High server load: if you have an application with a large number of concurrent users or expect high traffic, especially with a large volume of data traffic, using WebSocket can increase the load on the server. In such cases, you need to carefully consider the scalability and performance capabilities of the server.
  • Environments with limited support:While modern browsers support WebSocket, there are situations, where older browsers or environments are needed that may not fully support WebSocket. In such cases, it would be necessary to choose backwards compatible alternatives.
  • It is important to consider the requirements and needs of a particular application before deciding to use WebSocket or another technology. Sometimes a different protocol or approach may be a better choice to achieve optimal communication between client and server.

Websocket video demonstration

You can see how to use WebSocket virtually in this video with a demo application that communicates with each other using WebSocket and you can see the cursor of other users.

WebSocket application programming

When creating an application with WebSocket, it is essential to keep in mind that such an application consists of two main parts:
  1. Backend: This part of the application runs on the server side and can be implemented in various programming languages such as Python, JavaScript and others. In this case, we will show you how to create this part in JavaScript and run it using Node.js.
  2. Frontend: The frontend is usually written in JavaScript and runs directly in the web browser.

Server

The source code of the WebSocket Server application that sends the received message back to the client. The WebSocket (WS) library must be installed for functionality.

/// npm install ws
const WebSocket = require('ws');

// Create a WebSocket server on port 8080
const wss = new WebSocket.Server({port: 8080});

// Event that fires when the client connects
wss.on('connection', (ws) => {
    console.log('New connection established.');

    // Event that fires when a message is received from the client
    ws.on('message', (message) => {
        console.log('Client message received: ' + message);

        // Sending the message back to the client
        ws.send(message);
    });

    // Event that fires when the connection to the client is terminated
    ws.on('close', () => {
        console.log('The connection to the client has been closed.');
    });
});

console.log('WebSocket server is running on port 8080.');

You can simply run this program using Node.js to get a fully functional WebSocket server.

Client

The page contains an HTML and JavaScript program that automatically connects to the WebSocket server and allows you to send messages, while displaying received messages in real time.

<html>
<head>
</head>
<body>
<form id="input-form "v
<label for="message">Enter Message:</label>
  	<input type="text" id="message" name="message"><br><br>
  	<input type="submit" value="Send">
</form>
<div id="messages"></div>
<script>

    // direct connet to webSocket in nodeJS, not encrypted
    webSocket = new WebSocket('ws://localhost:8080');


    // ---- connet to webSocket in node JS via apache proxy
    // not encrypted
   // webSocket = new WebSocket('ws://localhost:81/'); //ok to apache and http
    //encrypted, i need to accept self-sing certificate
    //(open URL https://localhost:4441 and accpet certificate)
    //webSocket = new WebSocket('wss://localhost:4441/');

    // ---- connet to webSocket in nodeJS via nginx proxy
    // not encrypted
    //webSocket = new WebSocket('ws://localhost:82/'); //ok on apache and http
    //encrypted, i need to accept self-sing certificate
    //(open URL https://localhost:4442 and accpet certificate)
    //webSocket = new WebSocket('wss://localhost:4442/');

    webSocket.onmessage = (event) => {
        console.log(event)
        document.getElementById('messages').innerHTML +=
            'Message from server: ' + event.data + "<br>";
    };
    webSocket.addEventListener("open", () => {
        console.log("We are connected");
    });

    function sendMessage(event) {
        var inputMessage = document.getElementById('message')
        webSocket.send(inputMessage.value)
        inputMessage.value = ""
        event.preventDefault();
    }

    document.getElementById('input-form').addEventListener('submit', sendMessage);
</script>
</body>
</html>

In this example, the client establishes a connection with a WebSocket running on port 8080 without encryption.

Application demo

Complete source code is at: https://github.com/josefjebavy/docker/tree/master/proxy-websocket. There are configurations for docker and launching. So using docker-compose up you can prepare and run the whole sample project and test the WebSocket functionality.

Proxy

Web applications are nowadays commonly run behind a proxy. I described how to configure such a proxy in the article webapplications behind a proxy. However, if using WebSocket, the proxy still needs to be configured.

For this tutorial, I'm assuming the case you have linux server installed with an Apache or Nginx web server that will serve as a proxy.

Nginx proxy

To run Nginx as a proxy and with a working WebSocket, you need to configure the proxy as follows:
location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_set_header X-Forwarded-Host $host;
                
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://nodejs:8080;
}

Apache Proxy

Apache needs to enable support for proxy and WebSocket by activating the appropriate modules for the Apache web server. And rewrite support will also be needed. In Debian base distributions you can do this for example with the following command:

 a2enmod rewrite proxy proxy_http proxy_wstunnel
You can then add the following configuration to the configuration of the corresponding web application (virtualhost configuration), for example:
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://nodejs:8080/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
 RewriteRule /(.*) http://nodejs:8080/$1 [P,L]

This is what the infrastructure can look like when running a proxy application. For the purpose of testing and training I have created a demo application where as you can see in the image you can communicate:

  1. Directly - without proxy
  2. Through a proxy provided by the Apache web server
  3. Another server where the Nginx web server is configured as a proxy
proxy and websocket

Again, all configuration can be found on GitHub in the project: https://github.com/josefjebavy/docker/tree/master/proxy-websocket.

Encrypted WebSocket

What is the difference between WS and WSS that you specify when connecting to the server in the URL ws://localhost:808. The difference is security. WS indicates unencrypted traffic. WSS indicates encrypted communication using SSL or nowadays TSL For more on this, see HTTPS web security.

If a web application communicates over an encrypted websocket (wss), the browser must consider the certificate valid. For a server with an invalid certificate, it will refuse to connect to the WebSocket. For testing, you typically use some certificate you generated and thus the certificate is not valid, then the easiest solution is to open the URL of the web server and manually validate the certificate.

Video tutorial on WebSocket and Proxy

In this video you will see a complete demonstration and description of how to get a WebSocket application running as a client and server, and how to properly configure Apache and Nginx as a proxy including a working WebSocket.

Links

WebSocket example
Wikipedia: WebSocket -Proxy_traversal
developer mozilla: Writing_WebSocket_client_applications
nginx: websocket

Web Application Operation

Be sure to securely configure your server and design and program your application to be stable and secure. Because instability will compromise service availability. And if you don't pay attention to security, there is a risk that someone will steal or delete your data, putting your business at risk. However, there is no simple guide to security, so you need to hire a IT consultant.

Applications using WebSocket are more demanding on the necessary server performance and are also more complex. That's why you should before introducing they should have carried out in much more detail into public traffic load tests. And determine the expected user traffic a size servers accordingly and optimize application and infrastructure architecture. Otherwise, you cannot expect that after publishing the application can withstand the onslaught of access from users.

Články na podobné téma

Python program to control Docker using the API
How to use MailCatcher to test emails
Python OpenAI API
Project management: agile software development
How to run old PHP applications
What a good programmer should know
Rust programming language
NodeJS: development, server configuration
Nette security bug CVE-2020-15227
REST API: platform API
Custom web and mail hosting with ISP Config software
Programming in SQL: PostgreSQL, MySQL/MariaDB
HTTPS: secure web
NoSQL database Mongo DB
Connecting to Microsoft SQL Server from Linux
What is the job description of a programmer
Python application localization
Which mail and web hosting to choose
Digispark - Program Atmel ATtiny microcontroller with Arduino IDE
Development for ARM processors with Arduino IDE
How to program the ESP8266 WiFi processor
Open smartphone with Linux - Openmoko Neo FreeRunner

Newsletter

If you are interested in receiving occasional news by email.
You can register by filling in your email news subscription.


+