12 min read

What Is a WebSocket and How Does It Differ from HTTP?

Learn what WebSocket is, how it differs from HTTP, when to use each, and how to expose a local WebSocket server to remote clients using a Localtonet HTTP tunnel.

🔌 WebSocket · Real-Time · HTTP · Networking Concepts · Developer Guide

What Is a WebSocket and How Does It Differ from HTTP?

HTTP gets the job done for most of the web. You ask, the server answers, the connection closes. But for live chat, multiplayer games, stock tickers, and collaborative editors, that model breaks down. You cannot build a real-time feed by asking the server a question every second. WebSocket was designed to solve exactly this and understanding how it works explains a lot about why modern applications are built the way they are.

🔄 Persistent connections explained ⚡ Full-duplex communication 🆚 HTTP vs WebSocket comparison 🌍 Exposing WebSocket apps with Localtonet

The HTTP Request-Response Model

HTTP; the protocol that powers the web follows a simple pattern. A client sends a request. The server sends a response. The connection closes. Every interaction starts fresh. The server has no way to reach out to the client unless the client asks first.

This works perfectly for most of what the web does: loading a page, submitting a form, fetching data from an API, uploading a file. The client is always the initiator, the server always responds, and neither side needs to stay connected in between.

But some applications need something fundamentally different. A chat message does not wait for you to refresh the page. A stock price update does not need you to ask for it. A collaborative document edit from a remote user should appear on your screen immediately. In all of these cases, the server needs to push data to the client without waiting for a request. HTTP alone cannot do this cleanly.

What Is WebSocket?

WebSocket is a communication protocol that provides a persistent, full-duplex channel between a client and a server over a single TCP connection. Once the connection is established, both sides can send messages to each other at any time without either side having to wait for the other.

It is standardised in RFC 6455 and supported natively in every modern browser via the WebSocket JavaScript API, as well as in server-side environments through libraries in every major language; Node.js, Python, Go, Java, and others.

The key difference in one sentence

HTTP: client asks, server answers, connection closes.
WebSocket: client and server connect once, then both can talk whenever they want for as long as the connection stays open.

How a WebSocket Connection Works

A WebSocket connection starts as a regular HTTP request. The client sends a special HTTP upgrade request to the server asking to switch protocols. If the server supports WebSocket, it agrees and the connection is upgraded. From that point on, the TCP connection stays open and both sides communicate using the WebSocket protocol instead of HTTP.

1

Client sends an HTTP upgrade request

The initial request looks like a normal HTTP GET but includes special headers: Upgrade: websocket and Connection: Upgrade. This tells the server the client wants to switch to the WebSocket protocol.

2

Server responds with 101 Switching Protocols

If the server supports WebSocket, it responds with HTTP status 101 and the same upgrade headers. The HTTP phase is now complete and the protocol switches.

3

The connection stays open

The underlying TCP connection remains open. Both client and server can now send frames small packets of data to each other at any time. There is no request-response cycle. Either side initiates a message independently.

4

Either side closes the connection when done

When either party is finished, they send a close frame and the connection is terminated. Unlike HTTP, this does not happen after every message the connection can stay open for hours or days.

Because the connection starts as HTTP, WebSocket works through standard firewalls, proxies, and load balancers that allow HTTP traffic. It uses the same port 80 (or 443 for secure connections). The URL scheme uses ws:// for unencrypted and wss:// for encrypted connections, analogous to http:// and https://.

HTTP vs WebSocket: A Direct Comparison

HTTP WebSocket
Connection Opens and closes per request Persistent, stays open
Direction Client initiates, server responds Either side can send at any time
Overhead per message High (full HTTP headers each time) Low (small WebSocket frame headers)
Server push Not natively supported Built in
Latency Higher (new connection setup each time) Lower (connection already open)
Best for Requests, responses, REST APIs, file transfers Real-time data, live updates, bidirectional communication
Stateless Yes No, connection carries state
URL scheme http:// / https:// ws:// / wss://
HTTP
ConnectionOpens and closes per requestDirectionClient initiates onlyBest forREST APIs, file transfers
WebSocket
ConnectionPersistent, stays openDirectionEither side, any timeBest forChat, live data, games

When to Use HTTP and When to Use WebSocket

The two protocols are not competitors. They solve different problems and most applications use both. HTTP handles the bulk of the work. WebSocket handles the parts that need to be live.

✅ Use HTTP for

Loading pages, fetching data, submitting forms, uploading files, REST API calls, authentication, anything that follows a request-response pattern, and anything where the client asks once and needs a single answer.

✅ Use WebSocket for

Live chat and messaging, multiplayer game state synchronisation, collaborative document editing, real-time dashboards and monitoring, live sports scores and financial data, push notifications, live code editors, and any feature where either the server or client needs to send data without waiting for the other to ask.

💬 Chat applications Messages appear on all connected clients the moment they are sent, without any polling.
🎮 Multiplayer games Player positions and game state stay synchronised across all clients with minimal latency.
📊 Live dashboards Metrics, server stats, and monitoring data update in real time without page refreshes.
📝 Collaborative editors Changes from one user appear instantly for all others, like Google Docs.
📈 Financial data Stock prices, crypto tickers, and order book updates stream continuously to clients.
🤖 AI streaming responses LLM responses stream token by token to the client as the model generates them, rather than waiting for the full response.

WebSocket in Code

The browser's native WebSocket API is straightforward. Here is a minimal example of a client connecting to a WebSocket server and exchanging messages.

Browser client (JavaScript)

// Connect to a WebSocket server
const socket = new WebSocket('wss://example.localto.net');

// Connection opened
socket.addEventListener('open', () => {
    console.log('Connected');
    socket.send(JSON.stringify({ type: 'hello', message: 'Hi from the browser' }));
});

// Receive messages from the server
socket.addEventListener('message', (event) => {
    const data = JSON.parse(event.data);
    console.log('Message from server:', data);
});

// Handle disconnection
socket.addEventListener('close', () => {
    console.log('Connection closed');
});

// Send a message at any time
function sendMessage(text) {
    if (socket.readyState === WebSocket.OPEN) {
        socket.send(JSON.stringify({ type: 'message', text }));
    }
}

Server (Node.js with the ws library)

npm install ws
// server.js
const { WebSocketServer } = require('ws');

const wss = new WebSocketServer({ port: 8080 });

wss.on('connection', (socket) => {
    console.log('Client connected');

    socket.on('message', (data) => {
        const message = JSON.parse(data);
        console.log('Received:', message);

        // Broadcast to all connected clients
        wss.clients.forEach((client) => {
            if (client.readyState === 1) { // WebSocket.OPEN
                client.send(JSON.stringify({
                    type: 'broadcast',
                    text: message.text,
                    timestamp: Date.now()
                }));
            }
        });
    });

    socket.on('close', () => {
        console.log('Client disconnected');
    });
});

console.log('WebSocket server running on ws://localhost:8080');
node server.js

Exposing a Local WebSocket Server with Localtonet

WebSocket connections start as HTTP and upgrade to the WebSocket protocol on the same connection. Localtonet's HTTP tunnel handles this upgrade transparently it forwards the Upgrade header and keeps the connection persistent, so wss:// connections to your tunnel URL reach your local WebSocket server without any special configuration.

1

Start your WebSocket server locally

The Node.js example above runs on port 8080. Start it and confirm it is listening.

2

Create an HTTP tunnel for port 8080

Go to the HTTP tunnel page, set local IP to 127.0.0.1 and port to 8080. Click Create and start the tunnel. The dashboard shows a public HTTPS URL such as https://abc123.localto.net.

3

Connect using the wss:// scheme

Update your client to use the tunnel URL with the wss:// scheme. The Localtonet relay terminates TLS and forwards the WebSocket frames to your local server.

// Replace ws://localhost:8080 with your tunnel URL using wss://
const socket = new WebSocket('wss://abc123.localto.net');

Remote clients, other browsers, mobile apps, or external services can now connect to your local WebSocket server from anywhere in the world. The connection is encrypted end-to-end using the tunnel's TLS certificate.

HTTP and WebSocket on the same port

Most WebSocket servers also serve HTTP on the same port the upgrade happens on the same connection. A single Localtonet HTTP tunnel covers both. Your REST API endpoints and WebSocket connections both flow through the same tunnel URL.

Frequently Asked Questions

What is the difference between ws:// and wss://?

ws:// is unencrypted WebSocket, equivalent to http://. wss:// is WebSocket over TLS, equivalent to https://. Browsers block ws:// connections from HTTPS pages for security reasons, so in practice you almost always need wss:// for any production or publicly accessible setup. Localtonet HTTP tunnels use HTTPS, so clients must connect using wss://.

Is WebSocket better than HTTP for everything?

No. WebSocket is a persistent connection, which means server resources stay allocated for each connected client for the duration of the session. For applications with millions of occasional users, that resource cost adds up quickly. HTTP is stateless and scales more naturally for request-response workloads. Use WebSocket where the continuous connection adds real value live updates, bidirectional communication and HTTP everywhere else.

What is long polling and how does it compare to WebSocket?

Long polling is a workaround that simulates server push using HTTP. The client sends a request, the server holds it open until there is new data, then responds. The client immediately sends another request. It works but generates significant overhead a new HTTP connection for every update cycle. WebSocket eliminates this entirely by keeping one connection open. Long polling was common before WebSocket was widely supported; today there is rarely a reason to use it in new code.

What is Server-Sent Events and how does it compare?

Server-Sent Events (SSE) is a standard that lets a server push a continuous stream of data to the browser over a regular HTTP connection. It is simpler than WebSocket and works well for one-directional streams; news feeds, log tailing, AI response streaming. The key difference is that SSE is one-directional (server to client only), while WebSocket is bidirectional. For AI chat interfaces that stream responses, SSE is often a better fit than WebSocket because the client only needs to receive, not send continuously.

Do WebSocket connections work through firewalls and corporate proxies?

Usually yes, because the initial handshake looks like a normal HTTPS request on port 443. Most firewalls allow this. Some corporate HTTP proxies do not support the Upgrade header and will drop WebSocket connections. In those environments, libraries like Socket.IO fall back automatically to long polling, which works through any HTTP proxy. If you control the server, using wss:// on port 443 maximises compatibility.

Can I use WebSocket with frameworks like Socket.IO or Phoenix Channels?

Yes. Socket.IO (Node.js), Phoenix Channels (Elixir), Action Cable (Rails), and similar abstractions all use WebSocket as their primary transport. They add features on top rooms, namespaces, automatic reconnection, fallback transports. These higher-level frameworks work through Localtonet HTTP tunnels the same way raw WebSocket does, since the underlying upgrade mechanism is identical.

Share Your Local WebSocket App from Anywhere

Create a free Localtonet account, start your WebSocket server, open an HTTP tunnel, and connect remote clients using the wss:// tunnel URL. No deployment, no certificate setup, no proxy configuration.

Create Free Localtonet Account →

Localtonet is a secure multi-protocol tunneling and proxy platform designed to expose localhost, devices, private services, and AI agents to the public internet supporting HTTP/HTTPS tunnels, TCP/UDP forwarding, mobile proxy infrastructure, file server publishing, latency-optimized game connectivity, and developer-ready AI agent endpoint exposure from a single unified control plane.

support