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>
sleep(rand(2,10));
? untuk tidak melakukan apa pun, polling database setiap 100 milidetik? kapan itu memutuskan untuk mati?Saya punya contoh obrolan yang sangat sederhana sebagai bagian dari slosh .
Edit : (karena semua orang menempelkan kode mereka di sini)
Ini adalah obrolan multi-pengguna berbasis JSON lengkap menggunakan polling panjang dan slosh . Ini adalah demo cara melakukan panggilan, jadi silakan abaikan masalah XSS. Tidak ada yang harus menyebarkan ini tanpa membersihkannya terlebih dahulu.
Perhatikan bahwa klien selalu memiliki koneksi ke server, dan segera setelah ada yang mengirim pesan, semua orang akan melihatnya secara langsung.
sumber
getNewComments
callback di sana, jadi itu hanya menembakkannya pada akhir setiap permintaan ajax tanpa hentiTornado dirancang untuk polling panjang, dan menyertakan aplikasi obrolan yang sangat minimal (beberapa ratus baris Python) di / example / chatdemo , termasuk kode server dan kode klien JS. Ini berfungsi seperti ini:
Klien menggunakan JS untuk meminta pembaruan sejak (jumlah pesan terakhir), server URLHandler menerima ini dan menambahkan panggilan balik untuk menanggapi klien ke antrian.
Ketika server mendapatkan pesan baru, acara onmessage menyala, loop melalui callback, dan mengirim pesan.
JS sisi klien menerima pesan, menambahkannya ke halaman, lalu meminta pembaruan sejak ID pesan baru ini.
sumber
Saya pikir klien terlihat seperti permintaan AJAX asinkron normal, tetapi Anda mengharapkannya untuk "lama" untuk kembali.
Server kemudian terlihat seperti ini.
Jadi, permintaan AJAX masuk ke server, mungkin termasuk stempel waktu kapan terakhir diperbarui sehingga Anda
hasNewData()
tahu data apa yang sudah Anda dapatkan. Server kemudian duduk dalam loop tidur sampai data baru tersedia. Sementara itu, permintaan AJAX Anda masih terhubung, hanya menunggu di sana menunggu data. Akhirnya, ketika data baru tersedia, server memberikannya ke permintaan AJAX Anda dan menutup koneksi.sumber
Berikut adalah beberapa kelas yang saya gunakan untuk polling panjang di C #. Pada dasarnya ada 6 kelas (lihat di bawah).
sumber
Ini adalah screencast 5 menit yang bagus tentang cara melakukan polling panjang menggunakan PHP & jQuery: http://screenr.com/SNH
Kode sangat mirip dengan contoh dbr di atas.
sumber
Berikut ini adalah contoh polling panjang sederhana dalam PHP oleh Erik Dubbelboer menggunakan
Content-type: multipart/x-mixed-replace
header:Dan ini adalah demo:
http://dubbelboer.com/multipart.php
sumber
Saya menggunakan ini untuk memahami Comet, saya juga mengatur Comet menggunakan server Java Glassfish dan menemukan banyak contoh lain dengan berlangganan ke cometdaily.com
sumber
Lihatlah posting blog ini yang memiliki kode untuk aplikasi obrolan sederhana dengan Python / Django / gevent .
sumber
Di bawah ini adalah solusi polling panjang yang saya kembangkan untuk Web Inform8. Pada dasarnya Anda mengganti kelas dan menerapkan metode loadData. Ketika loadData mengembalikan nilai atau waktu operasi habis, itu akan mencetak hasilnya dan kembali.
Jika pemrosesan skrip Anda membutuhkan waktu lebih dari 30 detik, Anda mungkin perlu mengubah panggilan set_time_limit () menjadi sesuatu yang lebih lama.
Lisensi Apache 2.0. Versi terbaru di github https://github.com/ryanhend/Inform8/blob/master/Inform8-web/src/config/lib/Inform8/longpoll/LongPoller.php
Ryan
sumber
Terima kasih untuk kodenya, dbr . Hanya kesalahan ketik kecil di long_poller.htm di sekitar baris
Saya pikir seharusnya begitu
agar bisa bekerja.
Bagi mereka yang tertarik, saya mencoba setara Django. Mulai proyek Django baru, katakan lp untuk polling panjang:
Panggil aplikasi msgsrv untuk server pesan:
Tambahkan baris berikut ke settings.py untuk memiliki direktori template :
Tetapkan pola URL Anda di urls.py seperti:
Dan msgsrv / views.py akan terlihat seperti:
Terakhir, templates / long_poller.htm harus sama seperti di atas dengan kesalahan ketik diperbaiki. Semoga ini membantu.
sumber
"15000"
adalah kesalahan sintaksis. setTimeout mengambil integer sebagai parameter ke-2.Ini adalah salah satu skenario di mana PHP adalah pilihan yang sangat buruk. Seperti yang disebutkan sebelumnya, Anda dapat mengikat semua pekerja Apache Anda dengan sangat cepat melakukan sesuatu seperti ini. PHP dibangun untuk memulai, menjalankan, menghentikan. Itu tidak dibangun untuk memulai, tunggu ... jalankan, berhenti. Anda akan merobohkan server Anda dengan sangat cepat dan menemukan bahwa Anda memiliki masalah penskalaan yang luar biasa.
Yang mengatakan, Anda masih bisa melakukan ini dengan PHP dan tidak membunuh server Anda menggunakan nginx HttpPushStreamModule: http://wiki.nginx.org/HttpPushStreamModule
Anda mengatur nginx di depan Apache (atau apa pun yang lain) dan itu akan menjaga membuka koneksi bersamaan. Anda hanya merespons dengan payload dengan mengirim data ke alamat internal yang bisa Anda lakukan dengan pekerjaan latar belakang atau hanya mengirim pesan ke orang-orang yang menunggu kapan pun permintaan baru masuk. Ini menjaga proses PHP dari duduk terbuka selama pemungutan suara yang panjang.
Ini bukan eksklusif untuk PHP dan dapat dilakukan menggunakan nginx dengan bahasa backend apa pun. Beban koneksi terbuka bersamaan adalah sama dengan Node.js sehingga keuntungan terbesarnya adalah Anda keluar dari MEMBUTUHKAN Node untuk sesuatu seperti ini.
Anda melihat banyak orang menyebutkan perpustakaan bahasa lain untuk mencapai polling panjang dan itu dengan alasan yang bagus. PHP tidak dibangun dengan baik untuk jenis perilaku ini secara alami.
sumber
Mengapa tidak mempertimbangkan soket web alih-alih polling panjang? Mereka jauh lebih efisien dan mudah diatur. Namun mereka hanya didukung di browser modern. Berikut ini adalah referensi cepat .
sumber
Grup WS-I menerbitkan sesuatu yang disebut "Reliable Secure Profile" yang memiliki implementasi Glass Fish dan .NET yang tampaknya beroperasi dengan baik.
Dengan sedikit keberuntungan ada implementasi Javascript di luar sana juga.
Ada juga implementasi Silverlight yang menggunakan HTTP Duplex. Anda dapat menghubungkan javascript ke objek Silverlight untuk mendapatkan panggilan balik ketika terjadi push.
Ada juga versi berbayar komersial .
sumber
Untuk implementasi ASP.NET MVC, lihat SignalR yang tersedia di NuGet .. perhatikan bahwa NuGet sering kedaluwarsa dari sumber Git yang mendapatkan komitmen sangat sering.
Baca lebih lanjut tentang SignalR di blog pada oleh Scott Hanselman
sumber
Anda dapat mencoba icomet ( https://github.com/ideawu/icomet ), server komet C1000K C ++ yang dibuat dengan libevent. icomet juga menyediakan perpustakaan JavaScript, mudah digunakan sesederhana
icomet mendukung berbagai Peramban dan OS, termasuk Safari (iOS, Mac), IEs (Windows), Firefox, Chrome, dll.
sumber
NodeJS paling sederhana
Skenario produksi bijak di Express untuk exmaple yang akan Anda dapatkan
response
di middleware. Lakukan apa yang perlu Anda lakukan, dapat meringkas semua metode yang disurvei panjang untuk memetakan atau sesuatu (yang terlihat oleh aliran lain), dan memohon<Response> response.end()
kapan pun Anda siap. Tidak ada yang istimewa tentang koneksi yang disurvei lama. Istirahat adalah bagaimana Anda biasanya menyusun aplikasi Anda.Jika Anda tidak tahu apa yang saya maksud dengan membuang, ini harus memberi Anda ide
Seperti yang Anda lihat, Anda dapat benar-benar menanggapi semua koneksi, satu, lakukan apa pun yang Anda inginkan. Ada
id
untuk setiap permintaan sehingga Anda harus dapat menggunakan peta dan mengakses panggilan api khusus.sumber