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.
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 CRLFThe 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
