If you need to make constant calls to server to fetch data (ie. for SPA app), instead of making the call over and over again you can implement Server Side Socket.
Server side socket is a listener/route/endpoint on server (ie php/laravel app) that runs a while loop constantly querying DB and returning the info in JSON.
Once you implement this you can make a call from frontend to the backend.
This call creates CONSTANT socket/steam connection to backend endpoint. ie. backend.com/file-status
This frontend is contantly listening for an update from backend.
When update comes from backend, the frontend stream code echoes it.
Useful when there’s other services/code/crons that might be populating the backend, so whenever backend updates, the data is returned.
This is opposite of a normal http connection where FRONTEND doesn’t even know that backend data has been updated until is explicitly make the request!
public function filesStatus($clientId) {
$resp = new StreamedResponse();
$resp->setCallback(function() use($clientId){
while(true) { // Keep connection alive
$data = ClientLink::where('client_id', $clientId)->get();
echo "data: " . json_encode($data) . "\n\n"; // Required format
ob_flush();
flush();
sleep(2);
}
});
$resp->headers->set('Content-Type', 'text/event-stream'); // Must have to start Server event
$resp->headers->set('X-Accel-Buffering', 'no');
$resp->headers->set('Cach-Control', 'no-cache');
$resp->send();
}
Then on frontend we create and Stream connection (as soon as backend return data, stream echoes it on page):
var clientId = document.getElementById('client_id').value;
var evtSource = new EventSource("/files-status/"+clientId, {withCredentials: true});
evtSource.onmessage = function (e) {
let d = JSON.parse(e.data);
const tb = document.querySelector('#files tbody');
tb.innerHTML = '';
d.forEach(function(item){
var data = `<tr>
<td><a href="${item.link}" target="_blank"> ${item.link}</a></td>
<td>${item.download_status}</td>
<td>${item.upload_status}</td>
<td>${item.filename}</td>
<td>${item.last_download}</td>
<td>${item.last_upload}</td>
<td>${item.last_download_file_hash}</td>
<td>${item.last_upload_file_hash}</td>
<td>
<form method="POST" action="/re-download/${item.id}">
{{ csrf_field() }}
<button type="submit">Download</button>
</form>
</td>
<td>
<form method="POST" action="/upload/${item.id}">
{{ csrf_field() }}
<button type="submit">Upload</button>
</form>
</td>
<td>
<form method="POST" action="/delete-link/${item.id}">
{{ csrf_field() }}
<button type="submit">Delete</button>
</form>
</td>
</tr>`;
tb.innerHTML += data;
});
};
Top comments (0)