Created
October 15, 2024 22:48
-
-
Save missoxd/a356fcab47847155e391eb7a922d4200 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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