Understand WebSocket and You Can Build a Chatbot!
Now that the real-time Web has become the norm, WebSocket is something you will quickly hit a wall with if you only "connect it somehow."
Selection criteria, deep protocol mechanics, heartbeats, reconnection, backpressure, authentication, and reverse proxies—all of these are essential knowledge for delivering stable services in the field.
In this article, I will explain the key points of design and operation to elevate WebSocket from a mere technology to a "properly usable weapon" that turns your ideas into reality.
The True Nature of WebSocket: Why It Is Not Just "Awesome HTTP"
What sets WebSocket apart from previous technologies lies in its origins and the way it exchanges data. Let's look at its unique features, which are similar to but distinct from HTTP.
The Core is a "Telephone Line": Bidirectional, Full-Duplex Communication
The greatest appeal of WebSocket is that it is bidirectional and full-duplex. "Bidirectional" means communication can be initiated from both the client and the server, and "full-duplex" means that sending and receiving can occur simultaneously.
If conventional HTTP communication is like a "walkie-talkie" where you cut the connection after conveying your message, WebSocket can be compared to a "telephone line" that stays connected so you can talk at any time. This characteristic of "keeping the connection open" eliminates the overhead of establishing a connection every time communication occurs, achieving overwhelming low latency. This is precisely why WebSocket shines in applications where interaction is life, such as chats, online games, and collaborative editing tools.
The Beginning of Magic: Protocol Switch from HTTP
So, how does it switch from HTTP to a dedicated WebSocket communication path? The key is the handshake, which is performed only once at the start of the connection.
Expression of intent from the client: Communication begins with what looks like a normal HTTP request. However, the request header contains a special expression of intent (the Upgrade: websocket header) that says, "I would like to switch this communication path to WebSocket from now on; is that okay?"
Server response: If the server that received the request supports WebSocket, it returns the status code 101 Switching Protocols to mean, "Understood. From here on, this communication path will switch to the WebSocket protocol."
The moment this handshake succeeds, the protocol on that TCP connection is no longer HTTP, but transforms into a data tunnel dedicated to WebSocket. From then on, heavy HTTP headers are no longer included in the communication, and exchanges are performed using WebSocket's own lightweight data format.
How Data is Carried: The Secret of Small Packages Called "Frames"
Data after the tunnel is opened is exchanged in small packages of a fixed format called "frames." These frames not only carry the body of the message but also hold various information for controlling the communication.
Frames are assigned an identifier called an Opcode that indicates their role.
Text frame: Carries text data in UTF-8 format.
Binary frame: Carries arbitrary binary data such as images or audio.
Close frame: Notifies the other party of the termination of the connection.
Ping/Pong frame: Used for heartbeats to check if the connection is alive.
Also, a security mechanism worth noting is masking. The specification mandates that all frames sent from the browser to the server must be masked (a simple form of encryption). This is a crucial mechanism to prevent intermediate cache proxies from being contaminated by malicious data.
The Ultimate Showdown with SSE: Which is Best for Your App?
Alongside WebSockets, the name that almost always comes up in the context of real-time communication is SSE (Server-Sent Events). While both can push data from the server to the client in real-time, their characteristics differ significantly. Making the right technical choice is a critical step that can determine the success or failure of your project.
There is only one decision criterion: "Is frequent transmission from the client necessary?"
Which technology should you choose? It may seem like there are countless considerations, but in reality, most cases boil down to this simple question.
"Does your application need to send data from the client to the server frequently?"
If the answer is Yes, choose WebSocket without hesitation.
If the answer is No and information delivery from the server is the main focus, SSE is the optimal candidate.
This is the shortest and most accurate decision criterion. This is because the most essential difference between the two lies in the "directionality of communication."
SSE's Specialty: The Expert in One-Way Delivery
SSE is a mechanism like a "radio broadcast" where data flows only in one direction from the server to the client. Unlike WebSockets, it does not switch to a special protocol; instead, it maintains a regular HTTP connection to achieve continuous data transmission from the server.
SSE has unique advantages that WebSockets do not.
Simplicity: Because it is completed over HTTP, it has extremely high compatibility with existing Web infrastructure.
Automatic Reconnection: Even if the connection is lost, the browser will automatically attempt to reconnect. No special library is required.
Event ID: The server can assign an ID to each message. Upon reconnection, the browser notifies the server of the ID of the last received message. This allows the server to resend unreceived messages that occurred while the connection was down, easily preventing message loss.
Due to these characteristics, SSE demonstrates immense strength when the primary use case is delivery from the server.
WebSocket's Exclusive Domain: Applications Where Interaction is Key
On the other hand, a WebSocket is a "telephone" for two-way communication. The client and server are on equal footing and can send messages to each other whenever they like. For applications where actions from the client occur frequently and need to be communicated to the server or other clients immediately, it is hard to imagine any choice other than WebSocket.
Since SSE is strictly one-way, if you want to convey something from the client to the server, you must send a separate, regular HTTP request (such as a POST). This is fine if you only send information occasionally, but in scenarios requiring low latency and high-frequency transmission, such as chat message sending or game character control, the overhead of generating an HTTP request every time cannot be ignored.
How to Determine the Right Tool for the Job: Concrete Use Cases
Sometimes, a hybrid approach that combines both is also effective. For example, you could design a system where major notifications are delivered via SSE, while only the chat function uses WebSockets. The important thing is to correctly understand the characteristics of the technology and maintain an attitude of "choosing the best tool for each requirement."
The technology to "keep the connection alive": The heart of stable operation
Establishing a connection with WebSocket is actually just the beginning of the journey. The real challenge lies in how to maintain it stably. Factors that threaten the connection, such as no communication, momentary network interruptions, and server restarts, occur on a daily basis.
Silence is a signal of disconnection: The importance of heartbeats
If there is no message exchange between the client and server for a while, intermediate load balancers, firewalls, etc., may decide on their own that "this connection is no longer in use" and silently disconnect it. This is a phenomenon called idle timeout, and it is one of the biggest causes of instability in WebSocket applications.
The most effective technique to avoid this problem is the heartbeat. This is a mechanism that continuously informs both the relay equipment and the other party that "this connection is still alive" by periodically sending very small data (Ping frames) and confirming that a response (Pong frame) is returned from the other party.
It is standard practice to set the heartbeat interval to be sufficiently shorter than the idle timeout value of the network environment (generally 30 seconds to several minutes).
Don't fall without getting something: Reconnection using exponential backoff
If the connection is lost due to network problems, the client should attempt to reconnect. However, if you implement a simple "reconnect immediately if disconnected" logic here, it can cause major problems.
If the server is down, all clients around the world will continue to send reconnection requests at once, causing a "reconnection storm" that hinders recovery.
This is where an algorithm called Exponential Backoff is used. This is a method of persistently attempting recovery while reducing the load on the server by exponentially increasing the trial interval each time a reconnection fails.
Controlling overflowing data: A safety valve called backpressure
In real-time communication, people tend to focus only on "sending" data, but considering the convenience of the "receiving" side is just as important for building a stable system. If the sender continues to send data unilaterally without considering the processing capacity of the receiver, the system will eventually collapse. The concept for dealing with this problem is backpressure.
Why is sending too much dangerous?: The threat of memory leaks and crashes
If the pace of receiving data cannot keep up with the pace of data being sent from the server, for reasons such as a slow client network, the data that cannot keep up will accumulate in the buffer. Eventually, when the buffer overflows, new data will begin to be discarded, and in the worst case, the application will crash due to running out of memory.
This is a serious problem that threatens the health of the system. To properly control backpressure, it is essential to have a mechanism where the "sender" understands the situation of the "receiver" and adjusts the transmission pace. For example, measures such as monitoring the amount of data accumulated in the transmission buffer and temporarily stopping transmission when a certain threshold is exceeded can be considered.
Message design and security practices
The WebSocket protocol itself only defines how to "carry" data and does not care about the format of its "contents". What kind of data structure to use for communication is entirely left to the application developer.
Deciding the contents of the "pipe": Recommendations for a JSON-RPC style
A style widely adopted in practice is to make the messages sent and received JSON objects, and include keys such as type (type of processing) and payload (actual data) inside, similar to JSON-RPC.
This format has many advantages, such as the receiver being able to immediately determine the intent of the message and distribute it to the appropriate processing, making future functional expansion easier, and making debugging easier because it is easy for humans to read and understand.
Also, if you use a lot of text data, enabling compression via permessage-deflate is a valid option to reduce data transfer volume, but since compression and decompression incur CPU costs, you must consider that trade-off when deciding whether to implement it.
Protecting at the First Gate: Authentication, Authorization, and Defense
WebSocket servers exposed to the internet are constantly exposed to security risks.
Authentication: Since WebSockets cannot send HTTP headers every time once connected, it is standard practice to complete authentication at the handshake timing. If the user is already logged in, the most secure and common method is to have them include the Cookie automatically provided by the browser or an API token like JWT in the header and verify it on the server side.
Origin Verification: Connection requests from browsers include an Origin header. The server side must always check this value and reject connections from unauthorized websites at the handshake stage. Neglecting this could allow malicious sites to abuse your server.
Rate Limiting and DoS Countermeasures: To protect the server from DoS attacks where malicious users send a large number of connections or messages in a short period, it is important to implement rate limiting that sets an upper limit on the number of connections or message frequency from the same IP.
The Foundation Called Infrastructure: Reverse Proxies and Scalability
In production environments, it is common to place a reverse proxy (such as Nginx) or a load balancer in front of the WebSocket server. Integrating these with WebSockets requires specific configurations.
Bridge for Connections: Settings to Correctly Pass the Upgrade Header
The Upgrade: websocket header exchanged during the WebSocket handshake must be correctly interpreted by the reverse proxy and passed through to the backend WebSocket server. If this setting is neglected, the handshake will fail, and a connection cannot be established. Many problems where "it worked in the development environment but doesn't work when passing through a production proxy" are caused by this missing configuration.
The Path to Horizontal Scaling: Pub/Sub Architecture
As the service grows and the number of concurrent users exceeds thousands or tens of thousands, a single WebSocket server will no longer be able to handle the load. Horizontal scaling, which involves increasing the number of servers, becomes necessary, but a major wall stands in the way here. If User A is connected to Server 1 and User B is connected to Server 2, how do you deliver a message received on Server 1 to User B on Server 2? That is the problem.
The standard architectural pattern to solve this problem is the Pub/Sub (Publish/Subscribe) model. This is a configuration where a message broker (relay layer) such as Redis is placed between WebSocket servers. When one server receives a message, it publishes it to the message broker, and the message broker delivers that message to all servers that are subscribing to it.
With this configuration, you can exchange messages across the entire system without being aware of which client is connected to which server, making it possible to scale servers freely.
Common Pitfalls and Misunderstandings about Socket.IO
There are also several typical problems that many developers face when introducing WebSockets.
Is Socket.IO not a WebSocket?: One common misunderstanding is thinking that Socket.IO is a WebSocket itself. Socket.IO is a library with its own protocol for achieving real-time communication. It uses WebSockets internally in environments where they are available, but automatically falls back to HTTP long-polling or similar in environments where they are not. Therefore, you must combine a Socket.IO server with a Socket.IO client, and a standard WebSocket server with a standard WebSocket client; you cannot mix the two.
Summary: A Checklist for Making WebSockets Your "Field Weapon"
WebSocket is not just a "technology for connecting," but a "collection of designs and philosophies for keeping connections alive." Finally, I will summarize the points made so far as a checklist.
Are the selection criteria clear?: Have you established the decision criteria of using SSE for one-way delivery and WebSockets if two-way interaction is the core?
Have you incorporated the lifeline of operations into your design?: Have you implemented heartbeats for idle timeout management and exponential backoff reconnection considering server load?
Is system health being maintained?: Have you considered measures for backpressure to prevent system crashes?
Have you built a fortress of security?: Are connection-time authentication, origin verification, and rate limiting fully secured?
Are you able to communicate with the infrastructure?: Have you remembered the reverse proxy ****Upgrade header transparency settings?
Are you looking ahead to future scaling?: In preparation for large-scale growth, are you considering a Pub/Sub architecture?
If you keep these perspectives in mind, the WebSocket application you build will become a robust and highly reliable communication channel capable of withstanding the rough seas of a production environment.
First, try writing down your application requirements on paper from the perspective of "Is it two-way communication that requires frequent transmission from the client, or is it centered on delivery from the server?"
Next, list the four items of "heartbeat," "reconnection," "origin verification," and "backpressure" as a design checklist, and specifically consider the implementation policy for each.
If you do this much, you should be able to eliminate most of the landmines you would encounter in production.
Knowledge is like a weapon, and it's like a Lego block—what is the answer?
Each piece of knowledge is a small Lego block.
But when combined, they become a weapon that can turn ideas that change the world into reality!
See you again at Knowledge Oasis.
Your guide was ko-fumi.
