Ini lebih sederhana daripada yang saya pikir sebelumnya. Pada dasarnya Anda memiliki halaman yang tidak melakukan apa-apa, sampai data yang ingin Anda kirim tersedia (misalnya, pesan baru tiba).
Berikut ini adalah contoh yang sangat mendasar, yang mengirimkan string sederhana setelah 2-10 detik. 1 dalam 3 peluang untuk mengembalikan kesalahan 404 (untuk menunjukkan penanganan kesalahan dalam contoh Javascript mendatang)
msgsrv.php
<?php
if(rand(1,3) == 1){
/* Fake an error */
header("HTTP/1.0 404 Not Found");
die();
}
/* Send a string after a random number of seconds (2-10) */
sleep(rand(2,10));
echo("Hi! Have a random number: " . rand(1,10));
?>
Catatan: Dengan situs nyata, menjalankan ini di server web biasa seperti Apache akan dengan cepat mengikat semua "utas pekerja" dan membiarkannya tidak dapat menanggapi permintaan lainnya .. Ada beberapa cara untuk mengatasi ini, tetapi disarankan untuk menulis "server jajak pendapat panjang" dalam sesuatu seperti Python yang dipelintir , yang tidak bergantung pada satu utas per permintaan. cometD adalah yang populer (yang tersedia dalam beberapa bahasa), dan Tornado adalah kerangka kerja baru yang dibuat khusus untuk tugas-tugas semacam itu (ini dibangun untuk kode polling panjang FriendFeed) ... tetapi sebagai contoh sederhana, Apache lebih dari cukup ! Script ini dapat dengan mudah ditulis dalam bahasa apa pun (saya memilih Apache / PHP karena sangat umum, dan kebetulan saya menjalankannya secara lokal)
Kemudian, dalam Javascript, Anda meminta file di atas ( msg_srv.php
), dan menunggu jawaban. Ketika Anda mendapatkan satu, Anda bertindak berdasarkan data. Kemudian Anda meminta file dan menunggu lagi, bertindak berdasarkan data (dan ulangi)
Berikut ini adalah contoh halaman seperti itu .. Ketika halaman dimuat, itu mengirimkan permintaan awal untuk msgsrv.php
file .. Jika berhasil, kami menambahkan pesan ke #messages
div, maka setelah 1 detik kami memanggil fungsi waitForMsg lagi, yang memicu menunggu.
1 detik setTimeout()
adalah pembatas laju yang sangat mendasar, berfungsi dengan baik tanpa ini, tetapi jika msgsrv.php
selalu kembali secara instan (dengan kesalahan sintaks, misalnya) - Anda membanjiri peramban dan dapat membeku dengan cepat. Ini lebih baik dilakukan memeriksa apakah file tersebut berisi respons JSON yang valid, dan / atau menjaga agar total permintaan per menit / detik tetap berjalan, dan menjeda dengan tepat.
Jika halaman kesalahan, itu menambahkan kesalahan ke #messages
div, menunggu 15 detik dan kemudian mencoba lagi (identik dengan bagaimana kita menunggu 1 detik setelah setiap pesan)
Yang menyenangkan tentang pendekatan ini adalah sangat ulet. Jika koneksi internet klien mati, koneksi akan habis, kemudian coba dan sambungkan kembali - ini melekat dalam berapa lama polling bekerja, tidak diperlukan penanganan kesalahan yang rumit
Bagaimanapun, long_poller.htm
kodenya, menggunakan kerangka jQuery:
<html>
<head>
<title>BargePoller</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css" media="screen">
body{ background:#000;color:#fff;font-size:.9em; }
.msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
.old{ background-color:#246499;}
.new{ background-color:#3B9957;}
.error{ background-color:#992E36;}
</style>
<script type="text/javascript" charset="utf-8">
function addmsg(type, msg){
/* Simple helper to add a div.
type is the name of a CSS class (old/new/error).
msg is the contents of the div */
$("#messages").append(
"<div class='msg "+ type +"'>"+ msg +"</div>"
);
}
function waitForMsg(){
/* This requests the url "msgsrv.php"
When it complete (or errors)*/
$.ajax({
type: "GET",
url: "msgsrv.php",
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
timeout:50000, /* Timeout in ms */
success: function(data){ /* called when request to barge.php completes */
addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
setTimeout(
waitForMsg, /* Request next message */
1000 /* ..after 1 seconds */
);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
addmsg("error", textStatus + " (" + errorThrown + ")");
setTimeout(
waitForMsg, /* Try again after.. */
15000); /* milliseconds (15seconds) */
}
});
};
$(document).ready(function(){
waitForMsg(); /* Start the inital request */
});
</script>
</head>
<body>
<div id="messages">
<div class="msg old">
BargePoll message requester!
</div>
</div>
</body>
</html>