Khu nghỉ dưỡng theo sơ đồ thông báo cũ ICMP Timestamp. Nó khá tầm thường để thực hiện trong JavaScript và PHP.
Dưới đây là một thực hiện chương trình này sử dụng JavaScript và PHP:
// browser.js
var request = new XMLHttpRequest();
request.onreadystatechange = readystatechangehandler;
request.open("POST", "http://www.example.com/sync.php", true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send("original=" + (new Date).getTime());
function readystatechangehandler() {
var returned = (new Date).getTime();
if (request.readyState === 4 && request.status === 200) {
var timestamp = request.responseText.split('|');
var original = + timestamp[0];
var receive = + timestamp[1];
var transmit = + timestamp[2];
var sending = receive - original;
var receiving = returned - transmit;
var roundtrip = sending + receiving;
var oneway = roundtrip/2;
var difference = sending - oneway; // this is what you want
// so the server time will be client time + difference
}
}
Bây giờ cho mã sync.php
:
<?php
$receive = round(microtime(true) * 1000);
echo $_POST["original"] . '|';
echo $receive . '|';
echo round(microtime(true) * 1000);
?>
tôi đã không kiểm tra mã trên, nhưng nó phải làm việc.
Lưu ý: Phương pháp sau đây sẽ tính toán chính xác chênh lệch thời gian giữa máy khách và máy chủ với thời gian gửi và nhận thực tế giống nhau hoặc gần như nhau. Hãy xem xét các tình huống sau:
Time Client Server
-------- -------- --------
Original 0 2
Receive 3 5
Transmit 4 6
Returned 7 9
- Như bạn có thể thấy, client và server đồng hồ là 2 đơn vị tắt đồng bộ hóa. Do đó khi khách hàng gửi yêu cầu dấu thời gian, nó ghi lại thời gian ban đầu là 0.
- Máy chủ nhận được yêu cầu 3 đơn vị sau đó, nhưng ghi lại thời gian nhận là 5 đơn vị vì nó là 2 đơn vị phía trước.
- Sau đó, nó truyền dấu thời gian trả lời một đơn vị sau đó và ghi lại thời gian truyền là 6 đơn vị.
- Khách hàng nhận được trả lời sau 3 đơn vị (tức là tại 9 đơn vị theo máy chủ). Tuy nhiên, vì nó là 2 đơn vị phía sau máy chủ, nó ghi lại thời gian trả về là 7 đơn vị.
Sử dụng dữ liệu này, chúng tôi có thể tính toán:
Sending = Receive - Original = 5 - 0 = 5
Receiving = Returned - Transmit = 7 - 6 = 1
Roundtrip = Sending + Receiving = 5 + 1 = 6
Như bạn có thể nhìn thấy từ trên, gửi và nhận lần được tính toán sai tùy thuộc vào bao nhiêu client và server là tắt đồng bộ hóa. Tuy nhiên, thời gian khứ hồi sẽ luôn đúng bởi vì chúng ta lần đầu tiên thêm hai đơn vị (nhận + bản gốc), và sau đó trừ hai đơn vị (trả về - truyền).
Nếu chúng ta giả định rằng thời gian oneway luôn là một nửa thời gian khứ hồi (tức là thời gian để truyền tải là thời gian để tiếp nhận, sau đó chúng ta có thể dễ dàng tính toán sự khác biệt thời gian như sau):
Oneway = Roundtrip/2 = 6/2 = 3
Difference = Sending - Oneway = 5 - 3 = 2
Như bạn có thể thấy, chúng tôi tính toán chính xác chênh lệch thời gian là 2 đơn vị. Phương trình cho chênh lệch thời gian luôn là sending - oneway
. Tuy nhiên, độ chính xác của phương trình này phụ thuộc vào độ chính xác mà bạn tính toán theo thời gian. Nếu thời gian thực gửi và nhận tin nhắn không bằng hoặc xấp xỉ bằng nhau, bạn sẽ cần phải tìm cách khác để tính thời gian một chiều.Tuy nhiên, cho mục đích của bạn, điều này là đủ.
Tôi làm cách nào để gửi các gói ICMP từ javascript? Tôi đã nhìn thấy chỉ có một ActiveX được gọi là ActiveSocket để gửi các gói ICMP nhưng tôi không thể sử dụng ActiveX.It shoud làm việc trên webkit. – micred
Bạn không gửi gói ICMP. Bạn chỉ cần sử dụng cùng một phương thức mà ICMP sử dụng để đồng bộ hóa thời gian trên máy chủ và máy khách. Hy vọng rằng rõ ràng nghi ngờ của bạn. Chúc mừng. ;) –
Định dạng của bạn trong PHP có vẻ không đúng: 'microtime()' không có tham số trả về một chuỗi có dạng "0.uuuuuu ssssssssss". Tôi muốn 'echo vòng (microtime (true) * 1000)'. –