Display Online users in a chat application - php

I have a chat application and in this application, i want to show online users in a chatroom. I have a database that records online users and it keeps changing whenever a new user comes. Whenever a users leaves, it is deleted from the database. Database consists of two columns: username and room. Database side works fine.
onlinelar.php:
<?php
$data = array();
$current = $_GET['current'];
$room = $_GET['room'];
$getRoomUsers = mysql_query("SELECT * FROM `chat_users_rooms` WHERE `room` = '".$room."'");
if(mysql_num_rows($getRoomUsers) != $current)
{
$data['numOfUsers'] = mysql_num_rows($getRoomUsers);
}
else
{
$data['numOfUsers'] = $current;
}
echo json_encode($data);
?>
online.js:
var numOfUsers = 0;
var room;
function chat(room2)
{
room = room2;
}
$.ajaxSetup({
cache: false
});
function getuserlist() {
$.ajax({
type: "GET",
url: "onlinelar.php",
data: {
'room': room,
'current' : numOfUsers
},
dataType: "json",
cache: false,
success: function(data) {
if (numOfUsers != data.numOfUsers) {
numOfUsers = data.numOfUsers;
$('#bu').html($("<strong id='bu'>"+ numOfUsers + "</strong>"));
}
setTimeout(getuserlist(),1);
},
});
}
And finally, the initializer of it in index.html:
----something
<script type="text/javascript">
var chat = new Chat(<?php echo $room;?>);
chat.getuserlist();
</script>
<strong id="bu">
<?php
echo $numOfUsers;
?>
</strong>
------something
In here, i want to check database situation(rows of the certain room), and change the number of chatters in that room simultaneously. 'current' is for number of users and 'room' is for the name of the room.But there is no change even though the num of rows of database is changing. Which part i am missing?
Note: I have added online.js in index.php

$('#bu').html($("<strong id='bu'>"+ numOfUsers + "</strong>"));
This line places a new element under your old one, what you want to do is replace the old one by calling
$('#bu').html(numOfUsers);
Also setTimeout() takes milliseconds so 1 is a really low value, you might want to start with 1000 and work from there.
Edit:
And setTimeout() takes a function as a param so you want to call:
setTimeout(getuserlist, 1000);

Related

execute update or insert query to multiple databases at same time by using ajax

I use date("h:i:s") for example. I've tried to execute the update query against multiple databases at same time, but the time could be different 1 or 2 seconds or maybe more, depends on the update process from one database to the others. I knew, my coding wouldn't work because I used recursive function and it proceed the queries one by one. I wonder if there were another ways to execute it at same time without looping or proceed the queries to all databases at once..
this is my script
<script type="text/javascript">
<!--
function updateTimer() {
var db = "1,2,",
dbindex = db.split(","),
countdb = 2;
function retrieve(id) {
if(id < countdb) {
$.ajax({
url: 'update.php',
type: 'post',
data: {
idx : dbindex[id]-1
},
success: function (output) {
id++;
retrieve(id);
},
error: function () {
alert("Error Update");
}
});
}
}
retrieve(0);
}
//-->
</script>
update.php
$idx = $_POST["idx"];
$conn = $db[$index[$idx]]; // testdb and test2db
$timer = date("h:i:s");
mysqli_query($conn,"update table set timer='".$timer."'");

AJAX how to grab returning value AND database connections

I am quite new to jQuery and AJAX.
I am sending the request via AJAX to check file 'test' every 5 seconds which works fine. 'test' stands for test.php file.
<script>
$(document).ready(function () {
function load() {
var test = "<?php echo $test; ?>/";
$.ajax({ //create an ajax request to load_page.php
type: "GET",
url: test,
dataType: "html", //expect html to be returned
contentType: "text/html",
success: function (response) {
$("#responsecontainer").html(response);
setTimeout(load, 5000)
}
});
}
load(); //if you don't want the click
// $("#display").click(load); //if you want to start the display on click
});
</script>
<div id="responsecontainer"></div>
test.php
$id = $this->session->userdata('UserID');
$get_friends_notification = $this->friends_model->get_friends_alert_by_ID($id);
if(isset($get_friends_notification) && !empty($get_friends_notification))
{
?>
<div id="test" style="width:200px; height:auto; border:1px solid red;">
<h3>Friend invitation from:</h3>
<?php
foreach($get_friends_notification as $key => $value)
{
$new_id = $get_friends_notification[$key] = $value["FrieInviter"];
$new_name = $get_friends_notification[$key] = $value["UserName"];
echo ''.$new_name.'<br />';
}
?>
</div>
<?php
}
Then it just displays it in the div # responsecontainer which works fine too.
$("#responsecontainer").html(response);
In the file 'test' I am checking database if there were any updates.
So I am pulling the information from DB and return to #responsecontainer. As it runs every 5 seconds, after it ran for the first time I would like to grab the last ID that I pulled and before it runs again and save it in variable and then I would like to pass that ID to the 'test' or process it differently. Basically I want to be able to use it. How can I do that??
EXAMPLE:
ajax checks test.php file and find 5 rows. returns these 5 rows with 5 IDs. The last ID is number 5. In the meantime there were some other rows inserted so next time it will find more rows.
Before it checkes again I want to tell it to not to check ID 1,2,3,4,5 but start from ID 6.
Also how does this method works with DB connections? Assuming that I have for example 500 users, and on all of theirs profiles that check would run every 5 seconds wouldnt it kill database connections?
Basically you need to add a pgination effect in here. Pass a parameter in the ajax request for example : if you are getting 5 records at a time,
then initialize a variable say
current_page = 0 , increment the same as you request via ajax
var current_page=0;
function load() {
var test = "<?php echo $test; ?>/";
$.ajax({ //create an ajax request to load_page.php
type: "GET",
url: test,
data : current_page
dataType: "html", //expect html to be returned
contentType: "text/html",
success: function (response) {
if(response.length!==0){
$("#responsecontainer").html(response);
current_page+=1;
}
setTimeout(load, 5000)
}
});
}
in the php page make the necessary changes (hope you know how pagination is done).

onchange F(x) to php to Highchart on same page

I am continuing a previous question that was asked onclick -> mysql query -> javascript; same page
This is my onchange function for a drop down of names. it is called when each drop down is changed. The idea is to send each runners name into the php page to run a mysql query then return 3 arrays to be entered into javascript.
function sendCharts() {
var awayTeam = document.getElementById('awayRunner').value;
var homeTeam = document.getElementById('homeRunner').value;
if(window.XMLHttpRequest) {
xmlhttp14 = new XMLHttpRequest();
}
else {
xmlhttp14 = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp14.onreadystatechange = function() {
if(xmlhttp14.readyState == 4 && xmlhttp14.status == 200) {
var parts = xmlhttp14.responseText.split(','); //THIS IS WHAT IS RETURNED FROM THE MYSQL QUERY. WHEN I ALERT IT, IT OUTPUTS IN THE FORM 14,15,18,16,17,12,13
... code that generates the chart
series: [ {
name: document.getElementById('awayRunner').value,
data: [parts,','], //THIS IS WHERE AN ARRAY MUST BE ENTERED. THIS OUPUTS ONLY ONE NUMBER
type: 'column',
pointStart: 0
//pointInterval
},
{
name: document.getElementById('homeRunner').value,
data: parts, // TRIED THIS
type: 'column',
pointStart: 0
//pointInterval
},
{
name: 'League Avg',
data: [], //THIS IS WHERE 3rd ARRAY MUST BE ENTERED
type:'spline',
pointStart: 0
//pointInterval
},
]
});
}
}
xmlhttp14.open("GET", "getCharts.php?awayRunner="+awayRunner+"&homeRunner="+homeRunner, true);
xmlhttp14.send();
}
my php code looks like this. As you'll see, there are 3 arrays that must be returned to be entered into different spots in the javascript to generate the code.
$away=$_GET['awayRunner'];
$home=$_GET['homeRunner'];
$db=mydb;
$homeRunner=array();
$awayRunner = array();
$totalOverall= array();
$getHome="select column from $db where tmName = '$home'";
$result2 = mysql_query($getHome);
while($row = mysql_fetch_array($result2)){
$homeRunner[]= $row['column'];
}
$getAway="select column from $db where tmName ='$away'";
$result22 = mysql_query($getAway);
while($row2 = mysql_fetch_array($result22)){
$awayRunner[]= $row2['column'];
}
$week = 0;
while($week<20){
$week++;
$teamCount = "select count(column) from $db where week = $week";
$resultTeam = mysql_query($teamCount);
$rowTeam = mysql_fetch_array($resultTeam);
$t = $rowTeam['count(column)'];
$getLeague = "select sum(column) from $db where week = $week";
$resultLeague = mysql_query($getLeague);
while($row3 = mysql_fetch_array($resultLeague)){
$totalOverall[]=$row3['sum(column)']/$t;
}
}
echo join(',',$awayRunner);
currently, by doing it this way, the chart only outputs the second value in the array. for instance, if var parts is equal to 23,25,26,24,23...only 25 is shown.
A previous question resulted with the following answer -
Load the page.
User chooses an option.
An onChange listener fires off an AJAX request
The server receives and processes the request
The server sends back a JSON array of options for the dependent select
The client side AJAX sender gets the response back
The client updates the select to have the values from the JSON array.
I'm lost on #'s 5 - 7. Can someone provide examples of code that gets this done? Normally, I would just ask for direction, but I have been stuck on this problem for days. I'm about ready to scrap the idea of having charts on my site. Thanks in advance
EDIT
this is the first change that I have made to send and receive just one request
<script>
$(function(){
$("#awayRunner").change(function(){
$.ajax({
type: "POST",
data: "data=" + $("#awayRunner").val(),
dataType: "json",
url: "/my.php",
success: function(response){
alert(response);
}
});
});
});
The data displayed in the alertbox is in the form 12,15,16,15. Now, when I enter in
data: response,
only the second number from each is being displayed in the chart. Any ideas?
EDIT
OK, so i figured out that the info in response is a string. It must be converted to an INT using parseInt to be usable in the chart. currently, I have
$("#awayTeam").change(function(){
$.ajax({
type: "POST",
data: "away=" + $("#awayTeam").val(),
dataType: "json",
url: "/getCharts.php",
success: function(response){
var asdf = [];
asdf[0] = parseInt(response[0]);
asdf[1] = parseInt(response[1]);
asdf[2] = parseInt(response[2]);
asdf[3] = parseInt(response[3]);
alert(asdf);
will have to write a function to make this cleaner.
I can't believe it, but I finally got it. here is how I used an onchange method to stimulate a MYSQL query and have the Highchart display the result. The major problem was that the returned JSON array was a string that needed to be converted into an INT. The resultArray variable is then used in the data: portion of the highChart.
$(function(){
$("#awayTeam").change(function(){
$.ajax({
type: "POST",
data: "away=" + $("#awayRunner").val(),
dataType: "json",
url: "/getCharts.php",
success: function(response){
var arrayLength = response.length;
var resultArray = [];
var i = 0;
while(i<arrayLength){
resultArray[i] = parseInt(response[i]);
i++;
}
In the PHP code, the array must be returned as JSON like this
echo json_encode($awayRunner);

Why is my long polling code for a notification system not updating in real time? PHP MYSQL

I am making a notification system similar to the red notification on facebook. It should update the number of messages sent to a user in real time. When the message MYSQL table is updated, it should instantly notify the user, but it does not. There does not seem to be an error inserting into MYSQL because on page refresh the notifications update just fine.
I am essentially using code from this video tutorial: http://www.screenr.com/SNH (which updates in realtime if a data.txt file is changed, but it is not written for MYSQL like I am trying to do)
Is there something wrong with the below code:
**Javascript**
<script type="text/javascript">
$(document).ready(function(){
var timestamp = null;
function waitForMsg(){
$.ajax({
type: "GET",
url: "getData.php",
data: "userid=" + userid,
async: true,
cache: false,
success: function(data){
var json = eval('(' + data + ')');
if (json['msg'] != "") {
$('.notification').fadeIn().html(json['msg']);
}
setTimeout('waitForMsg()',30000);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
setTimeout('waitForMsg()',30000);
}
});
}
waitForMsg();
</script>
<body>
<div class="notification"></div>
**PHP***
<?php
if ($_SERVER['REQUEST_METHOD'] == 'GET' )
{
$userid = $_GET['userid'];
include("config.php");
$sql="SELECT MAX(time) FROM notification WHERE userid='$userid'";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
$currentmodif = $row['MAX(time)'];
$s="SELECT MAX(lasttimeread) FROM notificationsRead WHERE submittedby='$userid'";
$r = mysql_query($s);
$rows = mysql_fetch_assoc($r);
$lasttimeread = $rows['MAX(lasttimeread)'];
while ($currentmodif <= $lasttimeread) {
usleep(10000);
clearstatcache();
$currentmodif = $row['MAX(time)'];
}
$response = array();
$response['msg'] = You have new messages;
echo json_encode($response);
}
?>
there is a problem with your javascript line below
url: "getData.php",
data: "userid" + userid,
async: true,
remove the = sign and try again.
i have not read the whole code but found this is the cause test and feel free to reply if still got more issues.
You're not re-executing the SQL statement in the loop so the value in "$row['MAX(time)']" is never going to change.
If you re-execute the query in the loop this example may work--but executing a query every 10ms is not going to be a very efficient way to implement real-time notification.
Also, if the PHP script runs longer then the time configured in php.ini (max_execution_time, 30 secs by default), you'll get an error.

How to handle multiple ajax requests

NOTE:
I gave up on trying to do the processing in one go, and just let it return after every x number of sends.
Two paths,
/sms?action=send
/sms?action=status
Let's say that the send path starts sending 10,000 sms messages via REST api calls.
I make a call to that page via ajax.
Then every few seconds, I make a call to /sms?action=status to see how the progress is going, and to update a progress bar.
The status path returns false if no messages are being sent.
What ends up happening is that the ajax call to the SEND path gets the ajax success: function called almost instantly, even though I know the script is taking 1+ minute to complete execution.
My progress bar never gets shown because the status ajax call (which is in a set interval with a few second delay) never seems to actually get called until the send call completes.
I'm trying to put the relevant code in here, but it may not be as clear as it should be without all the context.
<script type="text/javascript">
var smsInterval = 0;
var smsSending = false;
$(document).ready(function() {
var charCount = 0;
var smsText = "";
var smsTotal = <?php echo $options["smsTotal"]; ?>;
<?php if($options["sending"]): ?>
smsStatus();
smsSending = true;
smsInterval = setInterval("smsStatus()", 5000);
<?php endif; ?>
$("span#smsadmin_charcount").html(charCount.toString());
//send button
$("div#smssend").click(function() {
if(smsSending == true) {
return false;
}
smsStatus();
var dataString = $("#smsadmin_form").serialize();
smsSending = true;
$("div#smssend").html("Sending...");
$.ajax({
type: "POST",
url: "<?php echo $base_url; ?>/admin/sms",
data : dataString,
success: function(data) {
},
error: function(request, error) {
$("div.notice.sms").html("ERROR "+error+ "REQUEST "+request);
}
});
});
});
function smsStatus() {
var dataString = "smsaction=status&ajax=true";
$.ajax({
type: "POST",
url: "<?php echo $base_url; ?>/admin/sms",
data : dataString,
success: function(data) {
//data being false here indicates the process finished
if(data == false) {
clearInterval(smsInterval);
var basewidth = $("div.sms_progress_bg").width();
$("div.sms_progress_bar").width(parseInt(basewidth));
$("div.sms_progress_notice").html(parseInt(100) + "% Complete");
smsSending = false;
$("div#smssend").html("Send To <?php echo $options["smsTotal"]; ?> Recipients");
} else {
var pcomplete = parseFloat(data);
$("div.sms_progress_bg").show();
var basewidth = $("div.sms_progress_bg").width();
$("div.sms_progress_bar").width(parseInt(basewidth * pcomplete));
$("div.sms_progress_notice").html(parseInt(pcomplete * 100) + "% Complete");
}
},
error: function(request, error) {
$("div.notice.sms").html("ERROR "+error+ "REQUEST "+request);
}
});
}
I might be missing the point, but inside the $("div#smssend").click you got this line:
smsStatus();
shouldn't it be:
smsInterval = setInterval("smsStatus()", 5000);
and INSIDE the success: function(data) for /admin/sms ?
If the send part is sending out 10k messages, and the status returns true if currently sending a message, and false if in between sending, then you have a design issue.
For example, what is status supposed to be showing?
If status is to show how many of a certain block have been sent, then what you can do is to submit the message to be sent (or addresses), and get back some id for that block.
Then, when you ask for a status, pass the id, and your server can determine how many of that group has been sent, and return back the number that were successful, and unsuccessful, and how many are still pending. If you want to get fancy, you can also give an indication how much longer it may be before finishing, based on how many other requests are also pending.
But, how you approach this really depends on what you expect when you ask for the status.

Categories