Sending two POST Ajax requests, Server handling them at once - php

I am trying to send two values to my server to be input into a database in the same row, the problem I have is that it isn't possible to send both values in one request. So what I want to do is send both the values in separate requests but handle them on the server at once so I can add the values into a database as one entry. My php isn't very strong, and I have no idea how to go about doing this. Is it possible? How would I do it?
Here's what I have so far:
<?php
$user = "user";
$pass = "pass";
$table = "database";
if(isset($_POST['currentUser']))
{
$userID = 'currentUser';
}
if(isset($_POST ['e.regid']))
{
$regid = 'e.regid';
}
if ($regid && $userID != null)
{
$con = mysqli_connect("localhost", $user, $pass);
mysqli_select_db($con, $table);
if (mysqli_connect_errno$con))
{
echo "Error connecting to the DB: " . mysqli_connect_errno());
}
else
{
"INSERT INTO gek_devices('regid', 'pin') VALUES ($regid, $userID)";
}
}

No, due to network latency and unreliability there's not even any guarantee that both requests will ever arrive at the server, let alone within a minute apart, let alone that you could run code once handling both requests. In practice chances are over 90% that both requests will not even be handled by the same Apache process on the server, given that a default Apache install on *nix will prefork 10 'spare' instances.
If you need to process the data 'simultaneously` you need to send them in the same request, that's the only way to guarantee atomicity.
Your intended solution is completely impossible, but also a glaring XY problem. Solve why you can't send the values simultaneously right now instead of focusing on hacky workarounds following that.

Related

Start session get session id and write it into database

i try to create a little login+survey and try to write all data to a database. Especially it is important, to get a session id for each user in order to add information of each page of the survey to the right line of the database.
My problem is here, that it seems that the session is either not started or i can not create a session id. Writing in the database already works, but not if i include the lines about the session.
After google'ing a lot that always took me to the same answer (which is not working for me) i try it here. Here is my code, first the callDatabase.php is called, in this file a session id is created and the database entry is made (idk if this is the best solution though, i guess not xD):
<script type="text/javascript">
$.post( 'callDatabase.php', { 'entry[]': ["init"]} );
</script>
callDatabase.php:
<?php
header('Content-Type: text/json');
$test = $_POST['entry'];
session_start();
$sID = session_id();
$timestamp = time();
$servername = "local";
$username = "root";
$password = "rootpw";
$conn = new mysqli($servername, $username, $password);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
mysqli_select_db($conn, 'myDb');
$sql = "INSERT INTO myTable (sID, timestamp, t1, rating, start, end, color, fight, completed)
VALUES ('$sID', '$timestamp', '-', '4', '_', '_', '_', '_', 'false')";
mysqli_query($conn, $sql);
mysqli_close($conn);
session_unset();
session_destroy();
$_SESSION = array();
?>
Like i said, without the session stuff, it is working fine, with it, the browser is running forever and i get no entry in my database. Since i get no error message i did not find any solution about how to fix it.
It is running locally, with XAMPP and a mysql database.
Problem is caused by Xampp, since some ports might be blocked, code is working with virtual machine, linux and apache server together with phpmyadmin for example. Checking the errorlogs will help to find out if the blocked ports are causing the problem.
To solve the problem together with xampp, it is recommended to deactivate all tools that might block the needed ports (skype, connection via vpn, antivirus tool, ...) or change the ports to have no conflicts there.

Notifications of new messages. Long polling

Help me please to realise notifications of new messages for users.
Now i have this client code:
function getmess(){
$.ajax({
url:"notif.php",
data:{"id":id},
type:"GET",
success:function(result){
$("#count").html(result);
setTimeout('getmess',10000);
}
});
}
and this server code:
$mysqli = new mysqli('localhost', 'root', '', 'test');
if (mysqli_connect_errno()) {
printf("error: %s\n", mysqli_connect_error());
exit;
}
session_start();
$MY_ID = $_SESSION['id'];
while (true) {
$result = $mysqli->query("SELECT COUNT(*) FROM messages WHERE user_get='$MY_ID'");
if (mysqli_num_rows($result)) {
while ($row = mysqli_fetch_array($result)) {
echo $row[0]."";
}
flush();
exit;
}
sleep(5);
}
I have the problem that this script is not updating in real time when new message was added to database. But if I press button with onclick="getmess();" it works.
First, you check your database every 5 seconds, so you can't achieve real time - you have at least 5 seconds delay.
And second, there is no way you can achieve real-time by polling.
The way to deliver notifications nearly real time is to send the message by the same code that inserts into the database, e.g. you should not query the database for new records, but when there is a new record to send the data to the client. Even with a long-polling as a transport protocol.
How to achieve this? Unfortunately PHP is not a good choice. You need a non-blocking server to hold the connection, you need to know which connection waits for what data and you need a way from PHP (your backend) to notify this connection.
You can use the tornado-web server, node.js or nginx to handle the connections. You assign an identifier to each connection (probably you already have one - the userid), and when there is a new record added - the PHP script performs HTTP request to the notification server (tornado, node.js, nginx) saying what data to which user does this.
For nginx, take a look at nginx push stream

How to decrease connection count to mySql DB on a remote server? My system must send data every second or two

My first post, because I haven't found answer to this problem anywhere! And i looked way beyond Google.. :)
DESCRIPTION:
So I have a set-up where an arduino device is connected to a laptop via USB serial cable and the laptop is connected to internet.
Like this: http://postimg.org/image/cz1g0q2ib/
arduino ---USB---> laptop (transit.py) ---WWW---> server (insert.php)-> mysql DB
There is a python script (transit.py) on the pc running continuously and listening to the COM port, analyzing received data and forwarding it to a file (insert.php) on a remote server (a free hosting site)
See code to learn how that works...
Then there is the insert.php script that receives this data (still almost every second), analyzes it and stores it in the mySql database.
This, however, is not the only file that requires mySql connection, therefore i include connect.php at the beginning of every such file.
PROBLEM:
Warning: mysqli::mysqli() [mysqli.mysqli]: (42000/1226): User 'user' has exceeded the 'max_connections_per_hour' resource (current value: 1500) in /server/connect.php on line 8
As a result of all this data travel and it's frequency (and cheapness of the hosting) i run into a "maximum connections per hour exceeded" error. The limit is 1500 per hour and i can't change it (it's a remote server). And no, i don't want to pay for hosting to get a bigger allowance - that's not the point- the issue is inefficiency of my code. Can i have one, persistent connection? Like a service?
Sending data from python script straight to remote mysql is not an option, because i don't have access to this feature.
CODE:
transit.py:
try:
ser = serial.Serial('COM4',9600,timeout=4)
except:
print ('=== COULD NOT CONNECT TO BOARD ===')
value = ser.readline()
strValue = value.decode("utf-8")
if strValue:
mylist = strValue.split(',')
print(mylist[0] + '\t\t' + mylist[1]+ '\t\t' + mylist[2])
path = 'http://a-free-server.com/insert.php'
dataLine = {"table": mylist[0], "data": mylist[1], "value": mylist[2]}
toServer = requests.post(path, params=dataLine, timeout=2)
insert.php:
<?php
include 'connect.php';
//some irrelevant code here...
if (empty($_GET['type']) && isset($_GET['data'])) {
$table = $_GET['table'];
$data = $_GET['data'];
$value = $_GET['value'];
if($mysqli->connect_errno > 0){
die('Unable to connect to database [' . $mysqli->connect_error . ']');
}
else
{
date_default_timezone_set("Asia/Hong_Kong");
$clock = date(DATE_W3C);
if (isset($_GET['time'])) {
$time = $_GET['time'];
}
else{
$time = $clock;
}
echo "Received: ";
echo $table;
echo ",";
echo $data;
echo ",";
echo $value;
echo ",";
echo $time;
if ($stmt = $mysqli->prepare("INSERT INTO ".$table." (`id`, `data`, `value`, `time`) VALUES (NULL, ?, ?, ?) ON DUPLICATE KEY UPDATE time='".$time."'"))
{
$stmt->bind_param('sss', $data, $value, $time);
$stmt->execute();
$stmt->free_result();
$stmt->close();
}
else{
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
}
}else{
echo " | DATA NOT received!";
}
?>
connect.php:
<?php
define("HOST", "p:a-free-host.com"); // notice the p: for persistence
define("USER", "user");
define("PASSWORD", "strongpassword1"); // my password. don't look!
define("DATABASE", "databass");
$GLOBALS["mysqli"] = new mysqli(HOST, USER, PASSWORD, DATABASE, 3306);
$count = intval(file_get_contents('conns.txt'));
file_put_contents('conns.txt', ++$count); //just something i added to monitor connections
?>
P.S. Everything works fine and all data is handled in a rather desirable manner, except for exceeding the limit and perhaps some other hidden caveats.
Any suggestion on how to decrease the connection count but still receive data every second?
If I have understood your issue correctly, your web host sucks. If you are limited to 1500 connections / hour, and each page requires a connection, that means you can never exceed 1500 page views per hour; that's not very much.
Many programming languages support connection pooling; in this model, the server opens one or more connection at start-up, and individual page requests get one of those connections when they need them. This reduces the overhead of opening and closing connections. See here for a discussion of connection pooling and PHP. You may be able to use one of the answers without too much trouble.
The alternative - and probably better - solution is to batch up data in your Python scripts so you don't have to connect to the web server so often. The classic waty to do this for applications that aren't time critical is to use a message bus. I'm not a Pythonist, but this should do the job...
Did you try to create a script that is all the time alive(here you make the connection)(S1) and then the rest?
(S2)
In the script that you are doing the operations first check if the connection is alive and if is not redo connection.
Close the connection in S1 at the end of the script.

will my data collide?

I post data to remote php file and there using post method am saving data to remote mysql database as simple as it is.
But my worry is am getting data every 30sec to 1minute and sending to server via http post from android mobile i.e from 'N' no of mobiles so, will data collide? is there a chance of loosing data? ex: from 100mobiles
currently am using 000webhost.com free hosting, am planning to move for paid one.
But do I need to buffer all incoming data and then save will it avoid data loss? or continue with my same approach and have high speed server?
I dont have much knowledge about maximum at what speed server can process incoming data. what if many data comes from many mobiles at same time? do I need to manually buffer or server does for me.
if manual buffer please share some code so that I can understand better.
(battery of android mobile I have taken care and am using gps and network provider)
<?php
$longitude = $_POST['lon'];
$latitude= $_POST['lat'];
$imei= $_POST['imei'];
$speed = $_POST['sp'];
$date = $_POST['date'];
if($longitude != "" && $latitude != "")
{
$mysql_host = "xxx";
$mysql_database = "xxx";
$mysql_user = "xxx";
$mysql_password = "xxx";
$con=mysql_connect($mysql_host,$mysql_user,$mysql_password ) OR DIE ("Unable to select db".mysql_error());
if($con)
{
mysql_select_db($mysql_database);
//check if imei number already exists
$sql="select emp_name from mob_reg where imei='$imei'";
$result=mysql_query($sql);
if((mysql_num_rows($result))== 0)
{
echo "invalid";
}
else
{
$sql="insert into details(imei,lon,lat,speed,date) values('$imei','$longitude','$latitude','$speed','$date');";
mysql_query($sql) or die("couldnt insert");
}
}
else{
echo 'invalid';
}
}
?>
I don't think you need to worry about buffering in your code.
Your code should deal with each request as efficiently as possible.
Your infrastructure should be set up according to how much traffic you expect.
If your service is going to be very busy, then you can think about load-balancing (having more than one web-server and/or database server handle the incoming requests, depending on where the bottlenecks are)

How can I get php pdo code to keep retrying to connect if there are too many open connections?

I have an issue, it has only cropped up now. I am on a shared web hosting plan that has a maximum of 10 concurrent database connections. The web app has dozens of queries, some pdo, some mysql_*.
Loading one page in particular peaks at 5-6 concurrent connections meaning it takes a minimum of 2 users loading it at the same time to spit an error on one or both of them.
I know this is inefficient, I'm sure I can cut that down quite a bit, but that's what my idea is at the moment is to move the pdo code into a function and just pass in a query string and an array of variables, then have it return an array (partly to tidy my code).
THE ACTUAL QUESTION:
How can I get this function to continue to retry until it manages to execute, and hold up the script that called it (and any script that might have called that one) until it manages to execute and return it's data? I don't want things executing out of order, I am happy with code being delayed for a second or so during peak times
Since someone will ask for code, here's what I do at the moment. I have this in a file on it's own so I have a central place to change connection parameters. the if statement is merely to remove the need to continuously change the parameters when I switch from my test server to the liver server
$dbtype = "mysql";
$server_addr = $_SERVER['SERVER_ADDR'];
if ($server_addr == '192.168.1.10') {
$dbhost = "localhost";
} else {
$dbhost = "xxxxx.xxxxx.xxxxx.co.nz";
}
$dbname = "mydatabase";
$dbuser = "user";
$dbpass = "supersecretpassword";
I 'include' that file at the top of a function
include 'db_connection_params.php';
$pdo_conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
then run commands like this all on the one connection
$sql = "select * from tbl_sub_cargo_cap where sub_model_sk = ?";
$capq = $pdo_conn->prepare($sql);
$capq->execute(array($sk_to_load));
while ($caprow = $capq->fetch(PDO::FETCH_ASSOC)) {
//stuff
}
You shouldn't need 5-6 concurrent connections for a single page, each page should only really ever use 1 connection. I'd try to re-architect whatever part of your application is causing multiple connections on a single page.
However, you should be able to catch a PDOException when the connection fails (documentation on connection management), and then retry some number of times.
A quick example,
<?php
$retries = 3;
while ($retries > 0)
{
try
{
$dbh = new PDO("mysql:host=localhost;dbname=blahblah", $user, $pass);
// Do query, etc.
$retries = 0;
}
catch (PDOException $e)
{
// Should probably check $e is a connection error, could be a query error!
echo "Something went wrong, retrying...";
$retries--;
usleep(500); // Wait 0.5s between retries.
}
}
10 concurrent connections is A LOT. It can serve 10-15 online users easily.
Heavy efforts needed to exhaust them.
So there is something wrong with your code.
There are 2 main reasons for it:
slow queries take too much time and thus serving one hit uses one mysql connection for too long.
multiple connections opened from every script.
The former one have to be investigated but for the latter one it's simple:
Do not mix myqsl_ and PDO in one script: you are opening 2 connections at a time.
When using PDO, open connection only once and then use it throughout your code.
Reducing the number of connections in one script is the only way to go.
If you have multiple instances of PDO class in your code, you will need to add that timeout handling code you want to every call. So, heavy code rewriting required anyway.
Replace these new instances with global $pdo; instead. It will take the same amount of time but it will be permanent solution, not temporary patch as you want it.
Please be sensible.
PHP automatically closes all the connections st the end of the script, you don't have to care about closing them manually.
Having only one connection throughout one script is a common practice. It is used by ALL the developers around the world. You can use it without any doubts. Just use it.
If you have transaction and want to log something in database you sometimes need 2 connections in one script

Categories