Mastering HTTP Chunked Transfer Encoding with Workerman and JavaScript

This guide explains the HTTP chunked transfer encoding mechanism, details its format, and provides a complete PHP Workerman server and JavaScript client implementation to stream data chunk‑by‑chunk, including installation steps, code examples, and expected output.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Mastering HTTP Chunked Transfer Encoding with Workerman and JavaScript

Introduction

HTTP chunked transfer encoding is a data‑encoding format defined by the HTTP protocol that allows a response body to be sent in a series of chunks, each preceded by its size in hexadecimal. This enables servers to start transmitting large or dynamically generated content without knowing the total length in advance, saving bandwidth and memory.

Transfer Format

The chunked message consists of a repeating sequence of:

chunk-size [;chunk-extension] CRLF
chunk-data CRLF

The final chunk has a size of 0 followed by an optional trailer and a terminating CRLF. Each chunk’s size is expressed in hexadecimal, and the CRLF sequence marks the end of the size line and the end of the data block.

Application Example

When using chunked transfer, both client and server must agree on the Transfer-Encoding: chunked header. The client includes this header in its request, and the server includes it in its response. The server then formats the payload according to the chunked specification.

Client adds Transfer-Encoding: chunked to the request header.

Server adds Transfer-Encoding: chunked to the response header.

Server streams the data, wrapping each piece in the chunk format.

Server Implementation

Workerman’s workerman/http-client library provides an asynchronous HTTP client that complies with PSR‑7. Install it via Composer: composer require workerman/http-client Below is a minimal PHP script that creates a Workerman worker, forwards a request to the Moonshot AI API, and streams the response back to the client using chunked encoding:

<?php
/**
 * HTTP chunked transfer response example
 */
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Connection\TcpConnection;
use Workerman\Http\Client;
use Workerman\Protocols\Http\Chunk;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
use Workerman\Worker;

$worker = new Worker('http://0.0.0.0:8782/');
$worker->onMessage = function (TcpConnection $connection, Request $request) {
    $http = new Client();
    $http->request('https://api.moonshot.cn/v1/chat/completions', [
        'method' => 'POST',
        'data' => json_encode([
            'model' => 'moonshot-v1-8k',
            'stream' => true,
            'messages' => [[
                'role' => 'user',
                'content' => 'PHP language implementation of bubble sort algorithm'
            ]]
        ]),
        'headers' => [
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer sk-xxxxxxxxxxxxxxxx'
        ],
        'progress' => function ($buffer) use ($connection) {
            // Send each received chunk to the client
            $connection->send(new Chunk($buffer));
        },
        'success' => function ($response) use ($connection) {
            // End of stream – send an empty chunk
            $connection->send(new Chunk(''));
        },
    ]);

    $response = new Response(200, ['Transfer-Encoding' => 'chunked'], '');
    $response->header('Access-Control-Allow-Origin', '*');
    $connection->send($response);
};
Worker::runAll();

Start the worker with: # php chunk.php start The server will listen on http://127.0.0.1:8782 and stream the AI model’s output chunk by chunk.

Client Implementation

A simple HTML page uses the Fetch API to request the chunked stream and appends each received piece to the page:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Stream Chunked HTTP Data</title>
</head>
<body>
    <h1>HTTP Chunked Transfer Demo</h1>
    <div id="data-container"></div>
    <script>
        const url = 'http://127.0.0.1:8782/';
        function fetchChunkedData() {
            fetch(url, {method: 'GET', headers: {'Accept': 'text/plain; chunks=true'}})
                .then(response => {
                    if (!response.ok) throw new Error('Network response was not ok ' + response.statusText);
                    return response.body;
                })
                .then(body => {
                    const reader = body.getReader();
                    processChunks(reader);
                })
                .catch(error => console.error('Fetch error:', error));
        }
        function processChunks(reader) {
            reader.read().then(({done, value}) => {
                if (done) { console.log('Stream complete'); return; }
                const chunk = new TextDecoder('utf-8').decode(value);
                document.getElementById('data-container').insertAdjacentHTML('beforeend', chunk);
                processChunks(reader);
            });
        }
        fetchChunkedData();
    </script>
</body>
</html>

Result

The server console shows the Workerman worker starting, and the browser displays the streamed AI response as it arrives.

Server output
Server output
Client output
Client output
Client output continuation
Client output continuation
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptBackend DevelopmentHTTPPHPWorkermanChunked Transfer Encoding
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.