phpMQTT non-blocking publish & recieve - php

I am writing a program connecting a web service in PHP to an MQTT broker. The broker is running Mosquitto on a Raspberry Pi.
The idea is to have the web service send a request (a form is submitted) and then send a publish to the MQTT broker and then wait for a reply.
However, the problem is that the loop seems to cause a PHP fatal error due to the fact that it is an endless loop.
I've tried adding the quitstop() function to quit the loop after a message is received, but the program crashes before it reaches that point.
MQTT is still very new to me, but I need to send the request and then keep the loop open until I receive the answer in order to proceed with my program.
This is the code to handle the form submit:
require("phpMQTT.php");
$server = "xxx.xxx.xxx.xx"; // change if necessary
$port = 1883; // change if necessary
$username = "username"; // set your username
$password = "password"; // set your password
$client_id = "phpMQTT-request-1234"; // make sure this is unique for connecting to sever - you could use uniqid()
$mqtt = new phpMQTT($server, $port, $client_id);
$msg = $_POST['box'];
if (!empty($msg)) {
if ($mqtt->connect(true, null, $username, $password)) {
$mqtt->publish("dev/test", $msg, 0);
$mqtt->close();
}
subscribeToTopic($mqtt);
}
function subscribeToTopic($mqtt)
{
$topics['dev/test'] = array("qos" => 0, "function" => "procmsg");
$mqtt->subscribe($topics, 0);
while ($mqtt->proc()) {
}
$mqtt->close();
}
function procmsg($topic, $msg)
{
global $mqtt;
echo $msg;
quitstop($mqtt);
}
function quitstop($mqtt)
{
$mqtt->close();
}

Related

What could cause a PHP socket request to be blocked?

I'm using this PHP library to query a Minecraft server and get some information about it (players online, max players, etc.). It connects to the server via a socket and sends a request for the information, the server sends data back. When I was hosting the code on XAMPP on my personal computer, everything worked perfectly. Then I got a web host (Bluehost) and uploaded all the code and now the request times out every single time. I've used command prompt to ping the server address to ensure that it's up and responding, and it is.
Here's my code:
function pingPlayers($ip) {
try {
$Query = new MinecraftPing($ip);
$response = $Query->Query();
$players = $response['players']['online'];
$maxPlayers = $response['players']['max'];
$online = true;
}
catch(MinecraftPingException $e) {
$players = "0";
$maxPlayers = "0";
$online = false;
var_dump($e);
} finally {
$Query->Close();
}
return array("players" => $players, "maxPlayers" => $maxPlayers, "status" => $online);
}
The MinecraftPing class and all of it's functions can be found here.
I am getting a MinecraftPingException returned, and it says "Failed to connect or create a socket: 110 (Connection timed out)". My first guess was that the host is blocking outgoing requests, but I contacted them and they said nothing is being blocked. I'm not getting any other errors besides the MinecraftPingException.

Can't Save URL Parameters in HTTP Get Request PHP

I'm working with Arduino and its GSM Shield. This is a hardware device that allows me to make an HTTP GET request to any IP address or web URL.
So we build a PHP script that reads URL parameters, and submits that data to the database. It will be saving our Arduino data when it pings our server.
Right now, when I visit the URL with the parameters in my browser, it works great. Everything saves and can be accessed via DB. But when the Arduino makes the request or I ping the URL with cURL, the record doesn't get saved.
The response I get shows that it is loading the page and spitting back the expected HTML. Why is my PHP not reading these URL parameters and saving them?
I've looked into sessions, etc no luck.
Thanks in advance!!
EDIT:::
handle_data.php (parses parameters, saves them to DB)
<?php
// Setup our DB login info
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "arduino";
if (!empty($_GET['lat']) && !empty($_GET['lon'])) {
function getParameter($par, $default = null){
if (isset($_GET[$par]) && strlen($_GET[$par])) return $_GET[$par];
elseif (isset($_POST[$par]) && strlen($_POST[$par]))
return $_POST[$par];
else return $default;
}
$lat = getParameter("lat");
$lon = getParameter("lon");
$person = $lat.",".$lon.",".$time.",".$sat.",".$speed.",".$course."\n";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO gps_data (latitude, longitude)
VALUES (".$lat.", ".$lon.")";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
// close connection
$conn->close();
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}
else {
};
?>
Here's the Arduino Code:
if(started) {
//GPRS attach, put in order APN, username and password.
//If no needed auth let them blank.
if (inet.attachGPRS("internet.wind", "", ""))
Serial.println("status=ATTACHED");
else Serial.println("status=ERROR");
delay(1000);
//Read IP address.
gsm.SimpleWriteln("AT+CIFSR");
delay(5000);
//Read until serial buffer is empty.
gsm.WhileSimpleRead();
//TCP Client GET, send a GET request to the server and
//save the reply.
numdata=inet.httpGET("http://cd5d6640.ngrok.io", 80, "/handle_data.php?lat=44.87654&lon=-88.77373", msg, 50);
//Print the results.
Serial.println("\nNumber of data received:");
Serial.println(numdata);
Serial.println("\nData received:");
Serial.println(msg);
}
Note - We're developing on localhost with MAMP, using ngrok to tunnel to localhost:8888. It works fine when you visit the ngrok url in the browser, but not when we hit it with a request. The url included is irrelevant and not active.

Send icq message via php

I need to send message to icq from php. I`m using WebIcqPro.
<?php
require_once('WebIcqPro.class.php');
$uin = '******';
$pass = '******';
$to_uin = '******';
$icq = new WebIcqPro();
$icq->debug = true;
$icq->setOption('UserAgent', 'miranda');
if ($icq->connect($uin, $pass)) {
$icq->sendMessage($to_uin, 'Hello! This is a test message');
} else {
die('ICQ connection error: ' . $icq->error);
}
This code fails with error: Error: Server close connection
P.S.: Maybe there are other working icq classes?
increase the limits.
edit file "WebIcqPro.class.php":
// $this->setTimeout(6, 0);
$this->setTimeout(60, 60000);

ldap auth with php fails intermittently

I have put together a basic web-app, the actual web-app itself works fine. However I wanted to add user authentication using our existing ldap server. The ldap script seems to work intermittently though, when logging in the first few attempts will fail with the 'access denied' message then it will authenticate. I ran the script stand alone without the app and the same behavior applies.
I cant seem to tie the problem down anywhere, I can only assume it is occuring on the ldap side and not the php side. I have included the script below, any help would be great.
While writing this, it failed to auth 3 times and passed twice...
<?php
$user = $_POST['login-name'];
$password = $_POST['login-pass'];
$ldap_user = 'uid='.$user.',ou=people,dc=ourdomain,dc=com,dc=au';
$ldap_pwd = $password;
$ldaphost = 'ldap://ldapserver.domain.com';
$ldapport = 389;
$ds = ldap_connect($ldaphost, $ldapport)
or die("Could not connect to $ldaphost");
if ($ds)
{
$username = $ldap_user;
$upasswd = $password;
$ldapbind = ldap_bind($ds, $username, $upasswd);
if ($ldapbind)
{
//print "Congratulations! $username is authenticated.";
header('Location: message.html');
}
else
{print "Access Denied!";}
}
?>
You probably should set the LDAP-protocol version to 3 using
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
before calling ldap_bind().
I've found this at http://php.net/manual/de/function.ldap-bind.php#72795

fsocketopen() Not connecting to server?

I've been trying to connect to a Twitch chat via IRC. I've added an echo function to test where I had connected or not as that page was blank and an account didn't join the IRC.
Here is my code:
<?php
set_time_limit(0);
ini_set('display_errors', 'on');
$datatwitch= array(
'server' => 'irc.twitch.tv',
'port' => 6667,
'nick' => 'greatbritishbgbot',
'name' => 'greatbritishbgbot',
'pass' => 'oauth:HERE',
);
?>
<?php
//The server host is the IP or DNS of the IRC server.
$server_host = $datatwitch['server'];
//Server Port, this is the port that the irc server is running on. Deafult: 6667
$server_port = $datatwitch['port'];
//Server Chanel, After connecting to the IRC server this is the channel it will join.
$server_chan = "#greatbritishbg";
//login password
$nickname = $datatwitch['name'];
$nickname_pass = $datatwitch['pass'];
//Ok, We have a nickname, now lets connect.
$server = array(); //we will use an array to store all the server data.
//Open the socket connection to the IRC server
$server['SOCKET'] = #fsockopen($server_host, $server_port, $errno, $errstr, 2);
if($server['SOCKET'])
{
//Ok, we have connected to the server, now we have to send the login commands.
echo "connected";
SendCommand("PASS $nickname_pass \n\r"); //Sends the password not needed for most servers
SendCommand("NICK $nickname\n\r"); //sends the nickname
SendCommand("USER $nickname USING PHP IRC\n\r"); //sends the user must have 4 paramters
while(!feof($server['SOCKET'])) //while we are connected to the server
{
$server['READ_BUFFER'] = fgets($server['SOCKET'], 1024); //get a line of data from the server
echo "[RECIVE] ".$server['READ_BUFFER']."<br>\n\r"; //display the recived data from the server
/*
IRC Sends a "PING" command to the client which must be anwsered with a "PONG"
Or the client gets Disconnected
*/
//Now lets check to see if we have joined the server
if(strpos($server['READ_BUFFER'], "422")) //422 is the message number of the MOTD for the server (The last thing displayed after a successful connection)
{
//If we have joined the server
SendCommand("JOIN $server_chan\n\r"); //Join the chanel
}
if(substr($server['READ_BUFFER'], 0, 6) == "PING :") //If the server has sent the ping command
{
SendCommand("PONG :".substr($server['READ_BUFFER'], 6)."\n\r"); //Reply with pong
//As you can see i dont have it reply with just "PONG"
//It sends PONG and the data recived after the "PING" text on that recived line
//Reason being is some irc servers have a "No Spoof" feature that sends a key after the PING
//Command that must be replied with PONG and the same key sent.
}
flush(); //This flushes the output buffer forcing the text in the while loop to be displayed "On demand"
}
} else {
echo "connection failed";
}
function SendCommand ($cmd)
{
global $server; //Extends our $server array to this function
#fwrite($server['SOCKET'], $cmd, strlen($cmd)); //sends the command to the server
echo "[SEND] $cmd <br>"; //displays it on the screen
}
?>
It appears I can't Get passed if($server['SOCKET']). Is there anyway I can diagnose this? As I have directly connect with the details in hexChat.
The server had actually been preventing me to use fsocket. After contacting my host and moving away from a shared host it started to work.
Please take a look at this answer: https://stackoverflow.com/a/24835967/1163786
Especially:
$socket = fsockopen($bot["Host"], $bot["Port"], $error1, $error2);
if(!$socket) {
echo 'Crap! fsockopen failed. Details: ' . $error1 . ': ' . $error2;
}
To get the details about the socket error = reason for socket not connecting.
Currently, you have $errno, $errstr on fsockopen, but echo only "connection failed".

Categories