Я пытаюсь создать систему проводки точно так же, как Facebook. Поэтому я немного поработал над тем, как Facebook это делает, Facebook использует длительный опрос, поэтому я искал вокруг, как его реализовать, я его реализую. И я, наконец, закончил, я открыл и Firefox, и Chrome, чтобы проверить его. После 2 или 3 сообщений он работал, но затем он будет дублировать результаты. Как вы можете видеть ниже:
Это первый пост, кстати.
И вот моя вкладка в сети. Во время этого процесса:
Он делает 3 запроса вместо одного.
И, наконец, вот мой код:
init.js, который содержит весь мой код JavaScript
function getNewPosts(timestamp) {
var t;
$.ajax({
url: 'stream.php',
data: 'timestamp=' + timestamp,
dataType: 'JSON',
})
.done(function(data) {
clearInterval( t );
// If there was results or no results
// In both cases we start another AJAX request for long polling after 1 second
if (data.message_content == 'results' || data.message_content == 'no-results') {
t = setTimeout( function() {
getNewPosts(data.timestamp);
}, 1000);
// If there was results we will append it to the post div
if (data.message_content == 'results') {
// Loop through each post and output it to the screen
$.each(data.posts, function(index, val) {
$("<div class='post'>" + val.post_content + "<div class='post_datePosted'>"+ val.posted_date +"</div> <br>" + "</div>").prependTo('.posts');
});
}
}
})
}
$(document).ready(function(){
// Start the autosize function
$('textarea').autosize();
// Create an AJAX request to the server for the first time to get the posts
$.ajax({
async: false,
url: 'stream.php?full_page_reload=1',
type: 'GET',
dataType: 'JSON',
})
.done(function(data) {
// Assign the this variable to the server timestamp
// that was given by the PHP скрипт
serverTimestamp = data.timestamp;
$.each(data.posts, function(index, val) {
$("<div class='post'>" + val.post_content + "<div class='post_datePosted'>"+ val.posted_date +"</div>" + "</div>").prependTo('.posts');
});
})
.fail(function() {
alert('There was an error!');
})
// When the form is submitted
$('#post_form').on('submit', function(event) {
$.ajax({
url: 'ajax/post.php',
type: 'POST',
dataType: 'JSON',
data: $('#post_form').serialize()
})
.done(function(data) {
// Reset the form values
$('#post_form')[0].reset();
})
.fail(function() {
// When there was an error
alert('An error occured');
})
// Prevent the default action
event.preventDefault();
});
// Start the actual long polling when DOM is ready
getNewPosts(serverTimestamp);
});
И мой stream.php
<?php
header('Content-type: application/json');
// If it was a full page reload
$lastId = isset($_GET['lastId']) && !empty($_GET['lastId']) ? $_GET['lastId'] : 0;
if (isset($_GET['full_page_reload']) && $_GET['full_page_reload'] == 1) {
$first_ajax_call = (int)$_GET['full_page_reload'];
// Create a database connection
$pdo = new PDO('mysql:host=localhost;dbname=test', 'akar', 'raparen');
$sql = "SELECT * FROM `posts`";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Output the timestamp since its full page reload
echo json_encode(array(
'fullPageReload' => 'true',
'timestamp' => time(),
'posts' => $posts
));
} else if (isset($_GET['timestamp'])) {
// The wasted time
$time_wasted = 0;
// Database connection
$pdo = new PDO('mysql:host=localhost;dbname=test', 'akar', 'raparen');
$timestamp = $_GET['timestamp'];
// Format the timestamp to SQL format
$curr_time = date('Y-m-d H:i:s', $timestamp);
$sql = "SELECT * FROM `posts` WHERE posted_date >= :curr_time";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':curr_time', $curr_time);
$stmt->execute();
// Fetch the results as an Associative array
$posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
// If there wasn't any results
if ( $stmt->rowCount() <= 0 ) {
// Create the main loop
while ($stmt->rowCount() <= 0) {
// If there is still no results or new posts
if ($stmt->rowCount() <= 0) {
// If we waited 60 seconds and still no results
if ($time_wasted >= 60) {
die(json_encode(array(
'message_type' => 'error',
'message_content' => 'no-results',
'timestamp' => time()
)));
}
// Helps the server a little bit
sleep(1);
$sql = "SELECT * FROM `posts` WHERE posted_date >= :curr_time";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':curr_time', $curr_time);
$stmt->execute();
$posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Increment the time_wasted variable by one
$time_wasted += 1;
}
}
}
// If there was results then we output it.
if ($stmt->rowCount() > 0) {
die( json_encode( array(
'message_content' => 'results',
'timestamp' => time(),
'posts' => $posts,
)));
exit();
}
}
И вот мой ajax/post.php
:
<?php
if ( isset($_POST['post_content']) ) {
$post_content = strip_tags(trim($_POST['post_content']));
if ( empty($post_content) ) {
/* If the user doesn't enter anything */
echo json_encode(array(
'message_type' => 'error',
'message_content' => 'It seems like your post is empty'
));
} else {
$pdo = new PDO('mysql:host=localhost;dbname=test', 'akar', 'raparen');
$sql = "INSERT INTO `posts` (`post_id`, `post_content`, `posted_date`) VALUES (NULL, :post_content, NOW());";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':post_content', $post_content);
$stmt->execute();
echo json_encode(array(
'message_type' => 'message',
'message_content' => 'Your post has been posted successfully.'
));
}
}
Если вы этого не понимаете, просто спросите меня. Я знаю этот грязный код, и я много повторил. Я сделал это для тестирования, так что это не имеет большого значения.
Спасибо!