Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save missoxd/a356fcab47847155e391eb7a922d4200 to your computer and use it in GitHub Desktop.
Save missoxd/a356fcab47847155e391eb7a922d4200 to your computer and use it in GitHub Desktop.
<?php
// @see: https://www.youtube.com/watch?v=6QnTNKOJk5A
// @see: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
// Define the default socket timeout
ini_set('default_socket_timeout', 360);
// Start Socket Server
$errno = 0;
$errstr = '';
$socket = stream_socket_server('tcp://0.0.0.0:8000', $errno, $errstr);
if (!$socket) {
die($errstr .'('. $errno .')');
}
// Listen to connections
echo 'Stream Socket Server Initialized!' . PHP_EOL;
while ($conn = stream_socket_accept($socket)) {
// Read HTTP request
$request = fread($conn, 2048);
// Get the Request Path
$requestPath = explode("\r\n", $request);
$requestPath = trim(preg_replace('#GET|HTTP/1.1#', '', $requestPath[0]), ' /');
// Handle special "event stream progress" requests
if ($requestPath == 'event-stream-progress') {
$body = implode("\n", [
'id: 1',
'event: onProgress',
'data: {"progress": 5}',
'', ''
]);
$initialHttpResponse = implode("\r\n", [
'HTTP/1.1 200 OK',
'Date: '. date('D, m M Y H:i:s \G\M\T'),
'Server: My Custom HTTP PHP Socket Server',
'Connection: keep-alive',
'Content-Type: text/event-stream',
'',
$body
]);
echo PHP_EOL . PHP_EOL . ' - - - - - ' . PHP_EOL;
echo $initialHttpResponse;
// Send HTTP response to client
fwrite($conn, $initialHttpResponse);
for ($i = 2; $i <= 20; $i++) {
usleep(500000); //500ms
$additionalEventStreamBody = implode("\n", [
'id: '. $i,
'event: ' . ($i < 20 ? 'onProgress' : 'done'),
'data: {"progress": '. ($i * 5) .'}',
'', ''
]);
// Log HTTP response to console
echo $additionalEventStreamBody;
// Send HTTP response to client
fwrite($conn, $additionalEventStreamBody);
}
// Close the income connection
fclose($conn);
// Move while loop forward
continue;
}
// Handle normal requests
$body = <<<HTML
<html lang="en">
<head>
<title>My Custom HTTP PHP Socket Server</title>
<!-- Disable favicon.ico request -->
<link rel="icon" href="data:,">
</head>
<body>
<h1>Welcome to My Custom PHP Server!</h1>
<p>We are currently responding to path: {$requestPath}!</p>
<p id="event-stream-update">This will be updated by the Event Stream progress.</p>
<script>
const eventSource = new EventSource("http://localhost:8000/event-stream-progress");
eventSource.addEventListener('onProgress', (event) => {
const data = JSON.parse(event.data);
document.getElementById('event-stream-update').innerText = data.progress + '% ' + '='.repeat(data.progress);
});
eventSource.addEventListener('done', (event) => {
const data = JSON.parse(event.data);
document.getElementById('event-stream-update').innerText = data.progress + '% done!';
eventSource.close();
});
</script>
</body>
</html>
HTML;
$httpResponse = implode("\r\n", [
'HTTP/1.1 200 OK',
'Date: '. date('D, m M Y H:i:s \G\M\T'),
'Server: My Custom HTTP PHP Socket Server',
'Connection: close',
'Content-Type: text/html',
'Content-Length: '. strlen($body),
'',
$body
]);
// Log HTTP response to console
echo PHP_EOL . PHP_EOL . ' - - - - - ' . PHP_EOL;
echo $httpResponse;
// Send HTTP response to client
fwrite($conn, $httpResponse);
// Close the income connection
fclose($conn);
}
fclose($socket);
/*
1. Run this script:
$ php -f http-socket-server-server-sent-events-sse.php
2. Browse to URL:
$ http://localhost:8000/event-stream-testing
3. Inspect browser network request for an Event Stream.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment