AI Prompt Engineering

Getting ChatGPT to Write Accurate WebSocket Handlers Without Dropped Messages

June 27, 2026 7 min read 10 views

You paste a quick prompt into ChatGPT asking for a WebSocket handler, and it gives you something that looks complete. It connects, sends, receives β€” and the moment the network hiccups or a slow client falls behind, messages vanish silently. The code was never wrong on the surface; it just never accounted for the hard parts.

This article is about closing that gap. With the right prompting strategy you can get ChatGPT to output WebSocket code that handles reconnections, queues outbound messages during disconnects, respects backpressure, and keeps connections alive with proper ping/pong β€” all without writing the scaffolding yourself.

What You'll Learn

  • Why ChatGPT's default WebSocket output skips critical reliability concerns
  • How to structure prompts that surface reconnection, queuing, and backpressure logic
  • Concrete prompt templates with annotated output you can adapt immediately
  • The specific gotchas in AI-generated async WebSocket code and how to catch them in review

Prerequisites

This guide assumes you're comfortable with async Python (the examples use asyncio and the websockets library) and you have a basic mental model of how WebSocket connections work. The prompting principles apply equally if you're working in Node.js or Go β€” the patterns transfer even if the syntax doesn't.

Why ChatGPT's Default WebSocket Code Falls Short

ChatGPT is trained on a huge volume of tutorial-grade WebSocket examples. Those tutorials are designed to explain the protocol, not to survive a production environment. The typical output you get from a plain prompt looks roughly like this:

import asyncio
import websockets

async def handler(websocket, path):
    async for message in websocket:
        response = process(message)
        await websocket.send(response)

async def main():
    async with websockets.serve(handler, "localhost", 8765):
        await asyncio.Future()

asyncio.run(main())

This works in isolation. It breaks in four common ways in the real world: the client disconnects mid-stream and messages are lost; a slow client causes the send buffer to grow without bound; no keepalive means idle connections are silently dropped by load balancers; and there is no reconnection logic on the client side.

ChatGPT isn't hallucinating here β€” this code is correct. It just solves the happy path. Your job as the prompter is to force it out of happy-path mode.

Understanding What ChatGPT Gets Wrong by Default

Before writing better prompts, you need to know exactly which concerns ChatGPT omits. These fall into four categories:

  • Reconnection: Client-side code rarely includes exponential backoff. It either tries once and gives up, or hammers the server in a tight loop.
  • Message durability: If the connection drops while you're trying to send, the message is gone. No queue, no retry.
  • Backpressure: Servers that receive faster than they can process will accumulate work without bound. The model rarely introduces flow control unprompted.
  • Keepalive: The ping_interval and ping_timeout parameters exist in the websockets library, but ChatGPT frequently omits them or sets them without explaining the tradeoffs.

The pattern here is the same one that comes up in getting ChatGPT to write accurate async code without race condition blind spots: the model defaults to the simplest correct answer, and you have to explicitly surface the edge cases you care about.

Prompt Structure That Unlocks Reliable Output

A vague prompt like:

Write a Python WebSocket server.

tells ChatGPT almost nothing about your production requirements.

Instead, use prompts that explicitly describe operational expectations.

Example:

Write a production-ready asyncio WebSocket server.

Requirements:

- Automatic reconnection support
- Outbound message queue
- Backpressure protection
- Ping/pong keepalive
- Graceful shutdown
- Structured logging
- Message acknowledgements

Explain every reliability mechanism before generating code.

Notice that the prompt isn't asking for syntax.

It's asking for architecture.

That single change dramatically improves the quality of generated code.

Force ChatGPT to Identify Failure Modes First

One of the most effective prompt techniques is delaying code generation.

Ask:

Before writing code,
list every realistic failure scenario
for this WebSocket service.

Then explain how each one should be handled.

Only then generate the implementation.

Typical output becomes:

  • Unexpected disconnects
  • Slow consumers
  • Network partitions
  • Duplicate messages
  • Server restarts
  • Idle timeout
  • Authentication expiration
  • Queue overflow

The model starts reasoning about resilience before writing a single line of code.

Reconnection Logic Should Never Be Optional

Most AI-generated client examples look like:

async with websockets.connect(url) as ws:
    ...

If the connection closes:

The program exits.

Production clients rarely behave this way.

Prompt instead:

Assume temporary network failures.

Reconnect automatically using exponential backoff.

Avoid reconnect storms.

Preserve queued outbound messages.

A better implementation will include:

  • Retry delays
  • Maximum retry intervals
  • Jitter
  • Connection state tracking

instead of immediate reconnect loops.

Message Queues Prevent Silent Data Loss

Consider:

await websocket.send(message)

Looks harmless.

What happens if:

  • Wi-Fi disconnects
  • Server restarts
  • Mobile client sleeps
  • TCP connection resets

The message disappears.

A production-ready prompt should specify:

Queue outbound messages.

Retry transmission after reconnection.

Do not lose messages that have not been acknowledged.

Now ChatGPT is much more likely to introduce:

Queue
↓

Reconnect
↓

Resend
↓

Acknowledgement
↓

Remove from queue

rather than fire-and-forget delivery.

Ask for Backpressure Handling Explicitly

Another omission in tutorial-grade examples:

Unlimited message processing.

Example:

async for message in websocket:
    process(message)

If processing becomes slower than incoming traffic:

Memory usage grows continuously.

Eventually:

  • Latency spikes
  • Memory exhaustion
  • Crashes

Prompt:

Assume clients can send messages faster
than the server can process them.

Implement bounded queues
and backpressure handling.

Possible solutions include:

  • asyncio.Queue(maxsize=...)
  • Rate limiting
  • Flow control
  • Temporary rejection
  • Load shedding

Ping/Pong Is More Than Keepalive

Many generated examples omit:

ping_interval
ping_timeout

Without keepalive:

  • NAT gateways expire connections
  • Load balancers remove idle sessions
  • Firewalls silently drop TCP flows

Prompt:

Configure ping/pong.

Explain:

- ping interval
- timeout
- reconnect behavior
- false positives

Understanding why values are chosen matters more than copying defaults.

Separate Reading and Writing

ChatGPT often generates:

while True:
    message = await websocket.recv()

    response = process(message)

    await websocket.send(response)

Everything runs in one loop.

A slow send blocks reading.

A slow read blocks writing.

Prompt instead:

Separate inbound
and outbound processing
into independent async tasks.

Explain why.

This usually results in:

Receiver Task

↓

Queue

↓

Worker

↓

Sender Task

A much more scalable design.

Handle Cancellation Properly

Many examples ignore:

asyncio.CancelledError

during shutdown.

Result:

  • Hanging tasks
  • Resource leaks
  • Half-closed sockets

Prompt:

Support graceful shutdown.

Handle task cancellation correctly.

Close WebSocket connections cleanly.

Production services should stop predictably.

Ask ChatGPT to Design the Connection Lifecycle

Instead of immediately requesting code:

Ask for a lifecycle diagram.

Example:

Describe the entire connection lifecycle:

Connect

Authenticate

Receive

Process

Send

Disconnect

Reconnect

Shutdown

Reviewing the lifecycle often exposes missing states before implementation begins.

Authentication Edge Cases

Many generated servers authenticate:

Once.

Never again.

Real systems encounter:

  • Token expiration
  • Session revocation
  • Permission changes

Prompt:

Assume authentication tokens expire.

Support token refresh
without losing queued messages.

This produces significantly more realistic implementations.

Ordering Guarantees

Developers often assume:

Message 1

↓

Message 2

↓

Message 3

always arrive in order.

Reality is more complicated.

Reconnects.

Retries.

Multiple producers.

Distributed servers.

Prompt:

Explain whether ordering is guaranteed.

If not,
show how sequence numbers
or acknowledgements
can preserve consistency.

Testing Under Failure

One of the most valuable follow-up prompts:

Act as a reliability engineer.

Create tests that intentionally break
this WebSocket implementation.

Include:

- Network interruption
- Slow clients
- Queue overflow
- Duplicate messages
- Server restart
- Lost acknowledgements

The generated test plan is often as valuable as the implementation itself.

Common AI-Generated WebSocket Bugs

Fire-and-Forget Sends

Messages disappear during disconnects.


Infinite Receive Loops

No graceful shutdown.


Missing Backpressure

Queues grow forever.


No Reconnection Strategy

Clients terminate after one failure.


No Keepalive

Idle infrastructure silently disconnects sessions.


Shared Mutable State

Concurrent handlers corrupt in-memory data.


No Structured Logging

Production debugging becomes difficult.

Python asyncio Prompt Improvements

Instead of:

Write a WebSocket server.

Use:

Python 3.12

asyncio

websockets

Requirements:

- Automatic reconnection
- Outbound queue
- Backpressure
- Ping/pong
- Graceful shutdown
- Structured logging
- Connection metrics
- Message acknowledgements
- No message loss

This almost always produces significantly better architecture.

Node.js Prompt Improvements

Likewise:

Node.js 22

ws library

Assume production load.

Support:

- Reconnects
- Heartbeats
- Backpressure
- Queue durability
- Graceful restart

Explain every design decision.

Provider-specific context improves output quality substantially.

Ask ChatGPT to Audit Its Own Code

After generation:

Review your implementation.

Identify:

1. Message loss risks

2. Queue overflow risks

3. Race conditions

4. Deadlocks

5. Slow-client behavior

6. Reconnection failures

7. Resource leaks

Suggest improvements.

This second pass frequently catches issues missed during generation.

A Production Prompt Template

A reusable prompt:

Act as a senior distributed systems engineer.

Generate a production-ready WebSocket service.

Requirements:

- Automatic reconnection
- Exponential backoff
- Outbound message queue
- Acknowledgement tracking
- Backpressure
- Ping/pong keepalive
- Graceful shutdown
- Structured logging
- Metrics
- Connection lifecycle management

Assume:

- Network interruptions
- Slow clients
- Duplicate messages
- Temporary server failures
- High concurrency

Before generating code:

List all failure modes.

Explain the architecture.

After generating code:

Audit it for reliability weaknesses.

Using a prompt like this consistently produces more robust implementations than asking for a basic handler.

Final Thoughts

WebSocket examples generated by ChatGPT usually succeed on the happy path because that's exactly what they're designed to demonstrate. They connect, exchange messages, and disconnect cleanly. Real production systems spend far more time dealing with the unhappy path: dropped connections, overloaded clients, intermittent networks, duplicate deliveries, and infrastructure that silently closes idle sockets.

The difference between a tutorial-grade WebSocket handler and a production-ready one isn't the syntaxβ€”it's the assumptions. By explicitly asking ChatGPT to reason about reconnection strategies, message durability, backpressure, keepalive behavior, graceful shutdown, and failure recovery before it writes code, you transform it from a code generator into a design assistant.

Always remember that a WebSocket service isn't successful because it works when everything is healthy. It's successful because users don't notice when the network isn't.

πŸ“€ Share this article

Sign in to save

Comments (0)

No comments yet. Be the first!

Leave a Comment

Sign in to comment with your profile.

πŸ“¬ Weekly Newsletter

Stay ahead of the curve

Get the best programming tutorials, data analytics tips, and tool reviews delivered to your inbox every week.

No spam. Unsubscribe anytime.