I'm establishing an SMPP connection via PHP using this free library. To receive a message, I'm using the following code, given in the example:
<?php
$GLOBALS['SMPP_ROOT'] = dirname(__FILE__); // assumes this file is in the root
require_once $GLOBALS['SMPP_ROOT'].'/protocol/smppclient.class.php';
require_once $GLOBALS['SMPP_ROOT'].'/transport/tsocket.class.php';
// Construct transport and client
$transport = new TSocket('your.smsc.com',2775);
$transport->setRecvTimeout(60000); // for this example wait up to 60 seconds for data
$smpp = new SmppClient($transport);
// Activate binary hex-output of server interaction
$smpp->debug = true;
// Open the connection
$transport->open();
$smpp->bindReceiver("USERNAME","PASSWORD");
// Read SMS and output
$sms = $smpp->readSMS();
echo "SMS:\n";
var_dump($sms);
// Close connection
$smpp->close();
?>
It works perfectly well, when I run the script in the browser window and send the SMS from my phone within given 60 seconds, but I don't quite understand how to make it work for a long time. I mean, like in real-life situation, when it should run on the background and trigger some events when receiving an SMS. How do I do that? Because now, I need to refresh the page every time to get an SMS, and it only works once. Thanks in advance.
If your solution needs to run within a browser, you shouldn't connect to the SMPP server directly from your script. It would lead to a single user scenario.
You should put a endless loop around the readSMS call and make it a console application which runs as a daemon. Then you write the result of readSMS into a database and read this from your web application. With this you could use html refresh or some fancy ajax querying the database and presenting the incoming sms.
Usually SMPP receiver connections run in blocking mode on the socket (no timeout), because either you receive either a SMS, or an enquire_link (which needs to be answered by a enquire_link_resp - your library does this automatically). Whenever you read a SMS, process it (put it in the database) and call readSMS again - it will block until the next SMS comes in.
You can try this.
<?php
set_time_limit(0);
$GLOBALS['SMPP_ROOT'] = dirname(__FILE__); // assumes this file is in the root
require_once $GLOBALS['SMPP_ROOT'].'/protocol/smppclient.class.php';
require_once $GLOBALS['SMPP_ROOT'].'/transport/tsocket.class.php';
// Construct transport and client
$transport = new TSocket('your.smsc.com',2775);
$transport->setRecvTimeout(60000); // for this example wait up to 60 seconds for data
$smpp = new SmppClient($transport);
// Activate binary hex-output of server interaction
$smpp->debug = true;
// Open the connection
$transport->open();
$smpp->bindReceiver("USERNAME","PASSWORD");
while(1) {
// Read SMS and output
$sms = $smpp->readSMS();
echo "SMS:\n";
var_dump($sms);
}
// Close connection
$smpp->close();
?>
Try to use another library
composer require glushkovds/php-smpp
To receive sms:
<?php
require_once 'vendor/autoload.php';
$service = new \PhpSmpp\Service\Listener(['your.smsc.com'], 'login', 'pass');
$service->listen(function (\PhpSmpp\SMPP\Unit\Sm $sm) {
if ($sm instanceof \PhpSmpp\Pdu\DeliverSm) {
var_dump($sm->message);
}
});
Related
I want to connect to IBM Bluemix through the MQTT protocol using PHP to subscribe to messages come from IoT Foundation.
I use this code:
<?php
require("../phpMQTT.php");
$config = array(
'org_id' => 't9m318',
'port' => '1883',
'app_id' => 'phpmqtt',
'iotf_api_key' => 'my api key',
'iotf_api_secret' => 'my api secret',
'device_id' => 'phpmqtt'
);
$config['server'] = $config['org_id'] .'.messaging.internetofthings.ibmcloud.com';
$config['client_id'] = 'a:' . $config['org_id'] . ':' .$config['app_id'];
$location = array();
// initialize client
$mqtt = new phpMQTT($config['server'], $config['port'], $config['client_id']);
$mqtt->debug = false;
// connect to broker
if(!$mqtt->connect(true, null, $config['iotf_api_key'], $config['iotf_api_secret'])){
echo 'ERROR: Could not connect to IoT cloud';
exit();
}
$topics['iot-2/type/+/id/phpmqtt/evt/+/fmt/json'] =
array("qos"=>0, "function"=>"procmsg");
$mqtt->subscribe($topics, 0);
// process messages
while ($mqtt->proc(true)) {
}
// disconnect
$mqtt->close();
function procmsg($topic, $msg) {
echo "Msg Recieved: $msg";
}
?>
But the browser show this message:
Fatal error: Maximum execution time of 30 seconds exceeded in /Library/WebServer/Documents/phpMQTT/phpMQTT.php on line 167
subscribe is not meant to run in the web browser as it has an infinite look, its best being run from the command line.
If you are using the subscribe method to receive messages you can look at persistent msgs and breaking out of the loop on msg receipt.
There is an example of how to use phpMQTT in the web browser in the file
web-app.php of this respository https://github.com/vvaswani/bluemix-iotf-device-tracker
You don't provide very much information about what you want to achieve by doing this; do you want to keep sending messages to the browser until the page is closed in the browser?
Server Sent Events or Websockets might be a better bet, and PHP might not be the best choice for this, because it uses up quite a lot of memory per connection (compared to node.js for example).
However if you just want to remove the 30 second PHP timeout, then you can use this function:
http://php.net/manual/en/function.set-time-limit.php
Or set max_execution_time in php.ini:
http://php.net/manual/en/info.configuration.php
Setting the maximum execution time to 0 should stop it from timing out.
But be warned that PHP and/or your webserver will have a limited number of concurrent HTTP connections.
I have something wrong with my notifications but i can't see where is the problem. I have an app that generates the token successfully, at first I was able to send a notification from my localhost to the device, but after i restored the device and and tested with the new device token to push a simple notification i couldn't get get it to work even though I didn't made any changes to php code nor my app code, here is my php code :
require_once 'ApnsPHP/Autoload.php';
// Instantiate a new ApnsPHP_Push object
$push = new ApnsPHP_Push(
ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,
'server_certificates_bundle_sandbox.pem'
);
// Set the Root Certificate Autority to verify the Apple remote peer
$push->setRootCertificationAuthority('entrust_root_certification_authority.pem');
// Connect to the Apple Push Notification Service
$push->connect();
// Instantiate a new Message with a single recipient
$message = new ApnsPHP_Message($token);
// Set a simple welcome text
$message->setText("GELLLOOOOOO");
// Play the default sound
$message->setSound();
// Add the message to the message queue
$push->add($message);
$push->send();
$push->disconnect();
// Examine the error message container
$aErrorQueue = $push->getErrors();
var_dump($aErrorQueue);
I think it have something to do with certificates but i'm not sure where is the issues since it was working before and there is nothing in $aErrorQueue , just an empty array.
Background
A desktop application on a user's computer gets the phone number from the modem and sends it to a PHP script once a phone call is recieved. At the moment, I am able to receive the data/packet on the specified port via PHP. I then have a scraper that connects to 411 databases and returns the address for the specified phone number.
Problem
After I retrieve the phone number in PHP through sockets, how can I automatically update the 411 parser page with the new phone number?
Code
socket_listener.php
set_time_limit(0);
$address = "127.0.0.1";
$port = 10629;
// create socket and bind with listener event
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $address, $port);
socket_listen($socket);
do {
$accept = socket_accept($socket);
$read = socket_read($accept, 1024) or die("Could not read input\n");
// parse phone number
$phone = substr($read, 19, 15);
$file = fopen("phone_numbers.txt", "a");
fwrite($file, $phone . "\r\n");
fclose($file);
} while (true);
phone_numbers.txt
(425) 555-1212
(123) 456-7890
Current Solution
My current solution is pretty quirky.
modem -> desktop application -> socket_listener.php -> data.txt -> 411_scraper.php
socket_listener.php listens on the port for incoming packets 24/7 and appends new phone numbers it receives to a text file
411_scraper.php checks text file for updates every 5 seconds. If file version is changed, then it reads the last phone number
Run code to query 411.com and retrieve data using phone number
Desired Solution
socket_listener.php listens on port for incoming packet containing phone number
Page automatically updates with new data retrieved from 411
Things I've Been Looking At
I've looked at node.js, Ratchet (www.socketme.com), and Pusher (http://pusher.com/) but they are all above my level of understanding. Pusher and Ratchet seems promising but I have not jumped into them yet.
I would use ajax or something along those lines. PHP isn't a real time thing. When you navigate to a website which uses PHP the code is executed before the page is rendered. It's processing the code on the server computer and giving you back the result as a string which you can send to the requesting client.
You're going to have the hold the data somewhere persistently. Once the php script is done executing the data is for that execution gone. Unless you use sessions.
I realise that batchEmail is no longer part of the new SwiftMailer. So I made this script:
<?
//
// GC PRESS EMAILER v5
//
ini_set('display_errors',1);
error_reporting(E_ALL);
require_once("config.php");
include_once("hawkmail/mail/lib/swift_required.php");
$c=mysql_connect($dbh,$dbu,$dbp);
function SendEmail(){
// DB
$s=mysql_query("SELECT * FROM `newgc`.`press_list`");
// Process Color Listing Loop
while($r=mysql_fetch_array($s)){
// ###########################
// START LOOP
// ###########################
$name=$r['name'];
$email=$r['email'];
$to=array(''.$email.''=>''.$name.'');
include("hawkmail/templates/press.php");
# Email subject
$str=$name;
$str=substr($str, 0, strrpos($str, ' '));
$subject='Dear '.$str.', you are invited to our Exclusive Party Collection Press Day!';
# send message
include("hawkmail/settings.php");
}
// ###########################
// END LOOP
// ###########################
}
SendEmail();
?>
The database has 200 records. And I ran the script and it sends a few emails and then times out
504 Gateway Time-out
The name and email records are like
John Smith
John.smith#site.com
Very plain. And my hawkmail/settings.php is this:
# mail
$smpturl="smtp.sendgrid.net";
$mailu="sitesitesite";
$mailp="sitessssssssssss";
$from=array("no-reply#site.com"=>"site.com");
# login credentials & setup Swift mailer parameters
$transport=Swift_SmtpTransport::newInstance($smpturl, 587);
$transport->setUsername($mailu);
$transport->setPassword($mailp);
$swift=Swift_Mailer::newInstance($transport);
# create a message (subject)
$message=new Swift_Message($subject);
# attach the body of the email
$message->setFrom($from);
$message->setBody($html, 'text/html');
$message->setTo($to);
$message->addPart($text, 'text/plain');
# actually send the message
if($recipients=$swift->send($message, $failures)){}else{}
Is there anyway to increase the limit of PHP time out (I use Ubuntu and Nginx) or is there an alternative to BatchMail() really don't understand why it was removed.
Can someone post examples of Batch mail scripts using the new swiftmailer?
Sending emails is the most complicated thing to do online.
It is the second most used service and the most abused.
I built my own custom email platform for sending bulk emails.
The timeout you experience is because of the Apache and PHP execution limits.
You need to run it as a CLI application with set_time_limit (0);
php /path/to/app/script.php something like this straight in the console.
If you do not have SSH access then run it with shell_exec like this:
shell_exec("php /path/to/app/script.php > /dev/null 2>/dev/null &");
This will ensure that the script that calls it does not hang around till it finishes.
I`m making an little php server that has 2 clients, on connects to the php (device a) and controls the other (device b).
device a makes a get request to the php. now i want to push that command to device b. is there any way to echo to device b? or to make an request to the device b?
(i only need to send one character to device b)
Pushing to device is possible but depends on your device.
A solution would be websockets, see the following links for further reading:
http://www.websocket.org/
http://code.google.com/p/phpwebsocket/
Another solution would be longpolling which is easy to implement in php:
http://en.wikipedia.org/wiki/Push_technology#Long_polling
Very simple implementation of longpolling on server-side:
$ts = time();
while(true) {
// if there's something new, send the response to the server
// if not, continue with the loop
if($response = getSuperAwesomeResponse()) {
print $response;
break;
}
// timeout after 60 seconds
if( ($ts + 60) > time()) {
break;
}
sleep(1);
}
On the client-side you just need to send some sort of ajax calls
No, unless device B is running a server of some kind (any software that accepts incoming connections really). If that's the case then you can easily make HTTP requests to the device (e.g. even with file_get_contents) or have your own custom connection protocol (with sockets). There are also other options that allow you the same functionality but work in slightly different ways.
If the device is not running any servers then the best you can do is poll the server continuously to see if there are any commands for it. This is easier to set up (the server is already there) but also not efficient.
Device B could open a client connection to the server and wait for incomming data. If data comes in, the client running on device B could echo it.
PHP offers access to network sockets, see http://www.php.net/manual/en/book.sockets.php
Some PHP example code making use of LibEvent and ZMQ, which allows a higher level of access to sockets and queues:
Event-driven Server:
<?php
// create base and event
$base = event_base_new();
$event = event_new();
// Allocate a new context
$context = new ZMQContext();
// Create sockets
$rep = $context->getSocket(ZMQ::SOCKET_REP);
// Connect the socket
$rep->bind("tcp://127.0.0.1:5555");
// Get the stream descriptor
$fd = $rep->getsockopt(ZMQ::SOCKOPT_FD);
// Define event callback function
$fnc = function ($fd, $events, $arg) {
static $msgs = 1;
echo "CALLBACK FIRED" . PHP_EOL;
if($arg[0]->getsockopt (ZMQ::SOCKOPT_EVENTS) & ZMQ::POLL_IN) {
echo "Got incoming data" . PHP_EOL;
var_dump ($arg[0]->recv());
$arg[0]->send("Got msg $msgs");
if($msgs++ >= 10) event_base_loopexit($arg[1]);
}
};
// set event flags
event_set($event, $fd, EV_READ | EV_PERSIST, $fnc, array($rep, $base));
// set event base
event_base_set($event, $base);
// enable event
event_add($event);
// start event loop
event_base_loop($base);
ZeroMQ Client:
<?php
// Create new queue object
$queue = new ZMQSocket(new ZMQContext(), ZMQ::SOCKET_REQ, "MySock1");
$queue->connect("tcp://127.0.0.1:5555");
// Assign socket 1 to the queue, send and receive
var_dump($queue->send("hello there!")->recv());
Source, Talk, Video (~22:00).