Ik ben bezig aan een simpele ajax chat en er kunnen zelfs images verstuurd worden.
Maar ik vraag me nu af is zo een ajax chat niet vrij belastend voor de server omdat er elke seconde data wordt opgehaald?
Mijn chat werkt dus via een timer.
Stel dat ik dit had gemaakt met php sockets was dit dan minder zwaar voor de server?
<?php
session_start();
/*
CREATE TABLE IF NOT EXISTS chat (
id int(11) NOT NULL AUTO_INCREMENT,
message varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
nick varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;
INSERT INTO chat (id, message, nick, created) VALUES
(1, 'My first message', 'Kris', CURRENT_TIMESTAMP);
*/
$con = mysql_connect('localhost', 'root', '');
mysql_select_db('phphulp', $con);
if($_SERVER['REQUEST_METHOD'] === 'POST') {
switch(isset($_GET['action']) ? $_GET['action'] : '') {
case 'login':
if (isset($_POST['login'])) {
// array met gegevens over de client. Doe hier eventueel meer mee ...
$_SESSION['login'] = array(
'login' => $_POST['login'],
'time' => time(),
'ip' => $_SERVER['REMOTE_ADDR']
);
}
header('location: index.php');
break;
case 'insert':
if (isset($_POST['message'])) {
$res = mysql_query(sprintf(
"INSERT INTO chat (message, nick, created) VALUES ('%s', '%s', CURRENT_TIMESTAMP);",
mysql_real_escape_string($_POST['message']),
mysql_real_escape_string($_SESSION['login']['login'])
));
$lid= mysql_insert_id($con);
file_put_contents('lid.txt', $lid);
echo 1;
}
break;
}
}
else {
switch(isset($_GET['action']) ? $_GET['action'] : '') {
case 'posts':
$res = mysql_query("SELECT id, message, nick, created FROM chat ORDER BY created DESC" );
while($row = mysql_fetch_assoc($res)) {
echo '<div class="post">
<div class="message">' . htmlentities($row['message']) . '</div>
<span class="nick">' . htmlentities($row['nick']) . '</span>
<span class="created">' . htmlentities($row['created']) . '</span>
</div>';
}
break;
case 'logout':
unset($_SESSION['login']);
header('location: index.php');
break;
}
}
?>
js.js
(function() {
// settings
var interval = 1000;
var posts = $('#posts');
var dt = new Date( );
// var loginForm = $('form.login');
// var chatForm = $('form.chat');
// hou het laatste id bij. Om de zoveel tijd gaan we controleren of dit id nog overeen komt met de laatste id op de server
var lastId = 0;
bindEvents();
getLastId();
// bind events
function bindEvents() {
$('form.chat').submit(function(e) {
e.preventDefault();
$.ajax({
url: 'posts.php?action=insert',
type: 'post',
data: $(this).serialize(),
success: function(data) {
}
});
setTimeout(blurred, 300);
});
}
function blurred() {
$('form.chat').find('input.message').val('');
}
/**
* deze functie doet maar 1 ding: het stuurt een Ajax request naar de server met als GET variabele: var lastId
*/
function getLastId() { //
$.ajax ({
url: 'lid.txt?t=' + dt.getTime().toString(), // om extra zeker te zijn dat de file wordt gelezen, en niet zomaar de cache, veranderen we telkens de url, met een dummy waarde, bv. de tijd
cache: false,
success: lastIdResponse // / success
});
}
/**
* De laatste id is van de server gehaald. Indien die niet overeenkomt met de waarde lokaal halen we de berichten op.
*/
function lastIdResponse(data) {
// data is een bericht van de server; antwoord van het Ajax request.
// data is de last id die op de server gevonden wordt.
data = Number(data);
if (data !== NaN && Number(data) == lastId) {
setTimeout(getLastId, interval); // Geen nieuw id gevonden. Een seconde later nog eens proberen
}
else {
// er is een verschil tussen de id op de server en die bij de client
// nu gaan we de data volledig halen.
// We sturen de last id van bij de client toch op naar de server. Eventueel haal je enkel de nieuwe posts op (alle posts met id > lastId)
$.ajax({
url: 'posts.php?action=posts&id=' + lastId,
success: dataResponse
});
// we zetten op deze plaats de id lokaal op de nieuwe waarde.
lastId = data;
}
}
/**
* De posts zijn in opgehaald
*/
function dataResponse(data) {
// data is hier de posts; volledig, in HTML formaat
// we steken die in de juiste div
posts.html(data);
// en uiteraard opnieuw de message loop op gang trekken
setTimeout(getLastId, interval);
}
})();
Ik heb je voorbeeld getest en het lijkt inderdaad te werken! Super!
Moet het alleen nog beetje aanpassen en integreren in mijn systeempje.
Ik hou je nog op de hoogte.
Bedankt!
UPDATE: Kris, ik heb het ondertussen geïntegreerd, en mijn voormalig probleem is nu dus opgelost! Niet meer steeds die inhoud refresh, alleen als er iets gepost wordt! Super bedankt!