Nó đơn giản hơn tôi nghĩ ban đầu .. Về cơ bản, bạn có một trang không có gì, cho đến khi dữ liệu bạn muốn gửi có sẵn (giả sử, có tin nhắn mới đến).
Đây là một ví dụ thực sự cơ bản, nó sẽ gửi một chuỗi đơn giản sau 2-10 giây. 1 trong 3 cơ hội trả lại lỗi 404 (để hiển thị xử lý lỗi trong ví dụ Javascript sắp tới)
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));
?>
Lưu ý: Với một trang web thực, việc chạy này trên một máy chủ web thông thường như Apache sẽ nhanh chóng kết nối tất cả các "luồng công nhân" và khiến nó không thể đáp ứng các yêu cầu khác .. Có nhiều cách để khắc phục điều này, nhưng nên viết một "máy chủ thăm dò ý kiến dài" trong một cái gì đó giống như xoắn của Python , vốn không dựa trên một luồng cho mỗi yêu cầu. cometD là một ngôn ngữ phổ biến (có sẵn bằng nhiều ngôn ngữ) và Tornado là một khung công tác mới được tạo riêng cho các nhiệm vụ đó (nó được xây dựng cho mã bỏ phiếu dài của FriendFeed) ... nhưng như một ví dụ đơn giản, Apache là quá đủ ! Kịch bản này có thể dễ dàng được viết bằng bất kỳ ngôn ngữ nào (Tôi đã chọn Apache / PHP vì chúng rất phổ biến và tôi tình cờ chạy chúng cục bộ)
Sau đó, trong Javascript, bạn yêu cầu tệp trên ( msg_srv.php
) và chờ phản hồi. Khi bạn nhận được một, bạn hành động dựa trên dữ liệu. Sau đó, bạn yêu cầu tệp và đợi một lần nữa, hành động theo dữ liệu (và lặp lại)
Dưới đây là ví dụ về một trang như vậy .. Khi trang được tải, nó sẽ gửi yêu cầu ban đầu cho msgsrv.php
tệp .. Nếu thành công, chúng tôi sẽ thêm thông báo vào #messages
div, sau 1 giây chúng tôi gọi lại hàm WaitForMsg, mà kích hoạt sự chờ đợi.
1 giây setTimeout()
là một bộ giới hạn tốc độ thực sự cơ bản, nó hoạt động tốt mà không cần điều này, nhưng nếu msgsrv.php
luôn trả về ngay lập tức (ví dụ như có lỗi cú pháp) - bạn làm ngập trình duyệt và nó có thể nhanh chóng đóng băng. Điều này tốt hơn nên được kiểm tra nếu tệp chứa phản hồi JSON hợp lệ và / hoặc giữ tổng số yêu cầu mỗi phút / giây đang chạy và tạm dừng một cách thích hợp.
Nếu trang bị lỗi, nó sẽ thêm lỗi vào #messages
div, đợi 15 giây rồi thử lại (giống hệt như cách chúng tôi đợi 1 giây sau mỗi tin nhắn)
Điều tốt đẹp về phương pháp này là nó rất kiên cường. Nếu kết nối internet của máy khách bị chết, nó sẽ hết thời gian, sau đó thử và kết nối lại - đây là thời gian bỏ phiếu hoạt động trong bao lâu, không cần xử lý lỗi phức tạp
Dù sao, long_poller.htm
mã, sử dụng khung 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>