php get message from rabbitmq error - php

My amqp extension version is 1.0.1 & AMQP protocol version is 0-9-1
get messages from queue :
<?php
try {
$conn = new AMQPConnection() ;
$conn->setLogin('guest') ;
$conn->setPassword('guest') ;
$conn->connect() ;
if ($conn->isConnected()) {
$channel = new AMQPChannel($conn) ;
if ($channel->isConnected())
{
$queue = new AMQPQueue($channel) ;
$queue->setName('test_queue') ;
$queue->setFlags(AMQP_DURABLE | AMQP_AUTODELETE) ;
$queue->declare() ;
$messages = $queue->get(AMQP_AUTOACK) ;
print_r($messages->getBody()) ;
}
} else {
echo "connect failure ... " ;
}
$conn->disconnect() ;} catch (Exception $e) {
echo $e->getMessage() ;}?>
and it doesn't work ..
Server channel error: 406, message: PRECONDITION_FAILED - parameters for queue 'test_queue' in vhost '/' not equivalent

It seems to me that the queue already exists and it was declared (created) previously with different parameters in the vhost. Queues need to be declared exactly with the same parameters every time (or deleted and recreated with the desired parameters). Try deleting the queue via the management plugin (http://www.rabbitmq.com/management.html) and then running your script again

If your queue has already been created you don't need to create it (using 'declare' method) and bind with exchange once again. IMHO you shouldn't do it as a) these actions require administrative privileges b) it's enough to to it only once c) you might not have got administrative rights on production and your code would be broken.
I believe it's better to create and bind all required queues with management console or any other tool you like and then receive messages this way
// consider using connection more than once. that's only for illustration purposes.
$connection = new AMQPConnection([ put your credentials here ]);
$connection->connect();
if(!$connection->isConnected()) {
throw new Exception('Connection failed.');
}
$chnlObj = new AMQPChannel($connection);
$queObj = new AMQPQueue($chnlObj);
$queObj->setName('yourQueueName');
echo $queObj->get(AMQP_AUTOACK)->getBody();
// consider using connection more than once. that's only for illustration purposes.
$connection->disconnect();

Related

Why SMPP bind Transmitter return error 0x34 (ESME_RINVDLNAME)

It`s my first time to write PHP code that sends SMS through
SMPP [Short Message peer to Peer] protocol by onlinecity php-smpp library from gethub URL: **https://github.com/onlinecity/php-smpp**,
I used the code below which sending SMS, but its only response an error
**The return value is error 0x34 (ESME_RINVDLNAME) Invalid Distribution List Name.**
So please help me to resolve this error
<?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'].'/protocol/gsmencoder.class.php';
require_once $GLOBALS['SMPP_ROOT'].'/transport/tsocket.class.php';
// Simple debug callback
function printDebug($str) {
//echo date('Ymd H:i:s ').$str."\r\n";
}
try {
// Construct transport and client, customize settings
$transport = new TSocket('192.168.111.1',5016,false,'printDebug'); // hostname/ip (ie. localhost) and port (ie. 2775)
//print_r($transport);
$transport->setRecvTimeout(10000);
$transport->setSendTimeout(10000);
$smpp = new SmppClient($transport,'printDebug');
print_r($smpp);
// Activate debug of server interaction
$smpp->debug = true; // binary hex-output
$transport->setDebug(true); // also get TSocket debug
// Open the connection
$transport->open();
$smpp->bindTransmitter("username","password");
// Prepare message
$message = 'Hello world';
$encodedMessage = GsmEncoder::utf8_to_gsm0338($message);
$from = new SmppAddress(GsmEncoder::utf8_to_gsm0338('5672'),SMPP::TON_ALPHANUMERIC);
$to = new SmppAddress('967777841622',SMPP::TON_INTERNATIONAL,SMPP::NPI_E164);
// Send
$smpp->sendSMS($from,$to,$encodedMessage);
//print_r($smpp);
// Close connection
// print_r($smpp);
$smpp->close();
} catch (Exception $e) {
// Try to unbind
try {
$smpp->close();
} catch (Exception $ue) {
// if that fails just close the transport
printDebug("Failed to unbind; '".$ue->getMessage()."' closing transport");
if ($transport->isOpen()) $transport->close();
}
// Rethrow exception, now we are unbound or transport is closed
throw $e;
}
I found this issue belong into SMPP interface version , which php-smpp project from onlinecity on GitHub using v3.4 [0x34] , however, this version is blocked from SMSC.
when I changed the interface version from 3.4 [0x34] into 0.3 [0x03]
code working fine.

I'm unable to cross communicate with ReactPHP's Pawl and Ratchet

I'm currently attempting to connect to two different socket servers. One of them is essentially an IRC connection, the other is an interface server that I've made myself. These two loops need to be able to communicate with each other, but I'm having difficulty actually sending a message from one connection to another.
Here's what I've been trying as a simplified way of injecting the message, the comments are not very confident because I'm honestly not sure where I'm going wrong:
<?php
require __DIR__ . '/vendor/autoload.php';
// EventLoop the way I understand it is designed to split up your loops and
// run them one after another so you can kind of multithread, even though
// it's just one step of the loop at a time.
$loop = \React\EventLoop\Factory::create();
// Verbose defintion of connectors mainly trying to just gain extra control
// and so I could see how each thing was defined.
$reactConnector = new \React\Socket\Connector($loop, [
'dns' => '8.8.8.8',
'timeout' => 10
]);
$connector = new \Ratchet\Client\Connector($loop, $reactConnector);
// Connect as a client to the development Socket server. This is all just
// from the Pawl github essentially.
//
// The connection is successful every time.
$ws = $connector('ws://0.0.0.0:5069', [], ['Origin' => 'http://localhost']);
->then(function(Ratchet\Client\WebSocket $conn) {
// Simple echo on message received for the test.
$conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
echo "Received: {$msg}\n";
});
$conn->on('close', function($code = null, $reason = null) {
echo "Connection closed ({$code} - {$reason})\n";
});
$conn->send('Hello World!');
}, function(\Exception $e) use ($loop) {
echo "Could not connect: {$e->getMessage()}\n";
$loop->stop();
});
// Instead of including a second socket connector I decided to use a simple
// timer and try to get it to use the client connection above to send
// messages to the socket server.
//
// The problem is here, I can't get the socket server to send a message
// from outside of the ->then();
$loop->addPeriodicTimer(1, function () use ($ws) {
$ws->then(function (Ratchet\Client\WebSocket $conn) {
$conn->send('Figured out?');
});
});
$loop->run();
I'd really like to be able to send messages from one connection the the other through some sort of $ws->send('message');, but I can't for the life of me figure out how.
Ahhh Finally a question I can answer!! I spent most of yesterday working through my own Ratchet/Pawl client that had to have addPeriodicTimer loops to send content at periodic times. It took some poking around but I made it work by placing the $loop->addPeriodicTimer() call INSIDE of the connector block, after the ->then(function(Ratchet\Client\WebSocket $conn) part and before the $conn->on('message'...) calls. Also for the $loop->addPeriodicTimer calls make sure to add the use clause passing in the connection ... and make sure to add the use clause passing in the $loop to the connector.
<?php
require __DIR__ . '/vendor/autoload.php';
// EventLoop the way I understand it is designed to split up your loops and
// run them one after another so you can kind of multithread, even though
// it's just one step of the loop at a time.
$loop = \React\EventLoop\Factory::create();
// Verbose defintion of connectors mainly trying to just gain extra control
// and so I could see how each thing was defined.
$reactConnector = new \React\Socket\Connector($loop, [
'dns' => '8.8.8.8',
'timeout' => 10
]);
$connector = new \Ratchet\Client\Connector($loop, $reactConnector);
// Connect as a client to the development Socket server. This is all just
// from the Pawl github essentially.
//
// The connection is successful every time.
$ws = $connector('ws://0.0.0.0:5069', [], ['Origin' => 'http://localhost']);
->then(function(Ratchet\Client\WebSocket $conn) use ( $loop ) {
$loop->addPeriodicTimer(1, function () use ( $conn ) {
$conn->send('Figured out?');
});
// Simple echo on message received for the test.
$conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
echo "Received: {$msg}\n";
});
$conn->on('close', function($code = null, $reason = null) {
echo "Connection closed ({$code} - {$reason})\n";
});
$conn->send('Hello World!');
}, function(\Exception $e) use ($loop) {
echo "Could not connect: {$e->getMessage()}\n";
$loop->stop();
});
$loop->run();

ActiveMQ in failover with PHP/Stomp client

here is the goal: a PHP application connecting to an ActiveMQ failover cluster (Master/Slave) using Stomp.
Here are the versions:
ActiveMQ 5.7
PHP stomp 1.0.5 stable
PHP 5.4.4-14+deb7u14 (cli)
Here is the setup:
2 servers with ActiveMQ;
keepalived installed on both servers, sharing a VIP
the PHP script is the following
< ? php
$queue = '/queue/test';
try {
$stomp = new Stomp("tcp://VIP:61613");
} catch(StompException $e) {
die('Connection failed: ' . $e->getMessage());
}
$stomp->subscribe($queue);
while ($stomp->hasFrame())
{
$frame = $stomp->readFrame();
var_dump($frame);
print_r($frame->headers["message-id"]."\n");
if ($stomp->ack($frame))
print_r("Frame ACK!\n");
else
die("ACK Error");
}
?>
With a consequent number of messages, we get these kinds of error in the ActiveMQ debug log
2014-10-03 13:19:13,941 | DEBUG | Transport Connection to:
tcp://127.0.0.1:37125 failed: java.io.EOFException |
org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ
Transport: tcp:///127.0.0.1:37125#61613 java.io.EOFException
at java.io.DataInputStream.readByte(DataInputStream.java:267)
at org.apache.activemq.transport.stomp.StompWireFormat.readHeaderLine(StompWireFormat.java:155)
at org.apache.activemq.transport.stomp.StompWireFormat.readLine(StompWireFormat.java:148)
at org.apache.activemq.transport.stomp.StompWireFormat.parseAction(StompWireFormat.java:170)
at org.apache.activemq.transport.stomp.StompWireFormat.unmarshal(StompWireFormat.java:98)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:229)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:221)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:204)
at java.lang.Thread.run(Thread.java:745)
This causes the STOMP connection to drop, and leads us to other issues.
It seems that the ActiveMQ errors might be linked to the keepalived setup, and that the better configuration would be to use failover scheme in the client.
We tried these connection strings in the Stomp object creation:
> failover://tcp://IP1:61613,tcp://IP2:61613
> failover:tcp://IP1:61613,tcp://IP2:61613
> failover://(tcp://IP1:61613,tcp://IP2:61613)
> failover:(tcp://IP1:61613,tcp://IP2:61613)
But they all lead to Invalid broker URI error.
Can't find much doc/issues on the web about such thing..
Any recommandation or advise on implementing failover client side?
PHP Stomp does not support failover by default, you have to implement it yourself to support it, like shown in the following example:
$urls = array('ip1:61613','ip2:61613');
$conn = null;
foreach ($urls as $url) {
$url = "tcp://".$url;
try {
$conn = new \Stomp($url,$user,$passwd);
} catch(\Exception $e) {
}
if ($this->conn) {
break;
}
}

Messages not getting sent via ZMQ

Currently, i am trying a simple code of sending/receiving messages using ZMQ. The code is as below
/* Create new queue object, there needs to be a server at the other end */
$queue = new ZMQSocket(new ZMQContext(), ZMQ::SOCKET_REQ);
$queue->connect("tcp://127.0.0.1:5555");
/* Assign socket 1 to the queue, send and receive */
$retries = 5;
$sending = true;
/* Start a loop */
do {
try {
/* Try to send / receive */
if ($sending) {
echo "Sending message\n";
$queue->send("This is a message", ZMQ::MODE_NOBLOCK);
$sending = false;
} else {
echo "Got response: " . $queue->recv(ZMQ::MODE_NOBLOCK) . "\n";
echo 'Complete';
break;
}
} catch (ZMQSocketException $e) {
/* EAGAIN means that the operation would have blocked, retry */
if ($e->getCode() === ZMQ::ERR_EAGAIN) {
echo " - Got EAGAIN, retrying ($retries)\n";
} else {
die(" - Error: " . $e->getMessage());
}
}
/* Sleep a bit between operations */
usleep(5);
} while (--$retries);
When i run this script in console, my output is
Sending message
Got response:
Complete
I believe that though there are no errors thrown, but still my message is not actually sent. I also ran netstat command but i didn't found any process listening on port 5555. Ideally there should be one(current). But no exception is thrown while making connection.
Is there something which i am missing?
When you say no process is listening on port 5555, it probably means that your server is not up and running. Your client will not throw any errors even if there is no server, it just sets up and waits for the server to come online (with your particular setup here, at least).
In this case, since you're using non-blocking mode, it'll send your message on the first pass through the loop (why are you sending the message in the loop at all?), but it won't actually send anything because the server isn't there. Then it'll attempt to receive on the second pass through the loop, but since the socket isn't ready to receive it looks like it'll just fail silently, without throwing an exception. Since no exception is thrown, it gets to your break statement, quits the loop, and you're done.
First things first, your send call should happen before the loop, it's something you want to do only once.
Then, when you recv, store the result in a variable and test for emptiness. Leave the try/catch code. The result should be something like this:
/* Create new queue object, there needs to be a server at the other end */
$queue = new ZMQSocket(new ZMQContext(), ZMQ::SOCKET_REQ);
$queue->connect("tcp://127.0.0.1:5555");
/* Assign socket 1 to the queue, send and receive */
$retries = 5;
echo "Sending message\n";
$queue->send("This is a message", ZMQ::MODE_NOBLOCK);
/* Start a loop */
do {
try {
/* Try to receive */
$response = $queue->recv(ZMQ::MODE_NOBLOCK);
if (!empty($response)) {
echo "Got response: " . $response . "\n";
echo 'Complete';
break;
}
else {
echo "we probably haven't even sent the original request yet, retrying ($retries)\n";
}
}
catch (ZMQSocketException $e) {
/* EAGAIN means that the operation would have blocked, retry */
if ($e->getCode() === ZMQ::ERR_EAGAIN) {
echo " - Got EAGAIN, retrying ($retries)\n";
} else {
die(" - Error: " . $e->getMessage());
}
}
/* Sleep a bit between operations */
usleep(5);
} while (--$retries);
echo "END OF LINE";
... keep in mind this is a minor fix to the client code that makes it behave a little more rationally, I still believe your actual problem is that the server isn't running.
Please add the server code. You are showing the client code. Since the problem seems to be in the server, and you also state that the server is not visible with netstat, the problem is most probably there.

What is "New transaction is not allowed" error in PHP and SQLSRV driver for?

I'm working on a web application written with PHP and uses SQL Server 2008. To connect to database, I used SQLSRV driever of Microsoft. In a part of this application, I have to use SQL Transactions. As Microsoft suggested, I did it exactly based on this article. The main processes in my codes follow these steps:
1- starting sql transaction
2- send information to PHP files through jQuery and check the result sent by JSON
3- rollback if the result was false and go to the next query if it was true.
4- commit transactions if no error occurred and all results were ok.
// This is my pseudo code
if (sqlsrv_begin_transaction( $sqlsrv->sqlsrvLink ) === true) {
$firstQuery = sqlsrv_query($stmt1);
if (!$firstQuery) {
sqlsrv_rollback();
} else {
$nextQuery = sqlsrv_query($stmt2);
if (!$nextQuery) {
sqlsrv_rollback();
} else {
sqlsrv_commit();
}
}
} else {
print_r(sqlsrv_errors()); // Here is where I get the error below.
}
The problem I have is this error:
[Microsoft][SQL Server Native Client 10.0][SQL Server] New transaction is not allowed because there are other threads running in the session
I'm using SQLSRV driver ver.2.
What is this error for? How can I solve it?
I included the my own sqlsrv class to the first part of index.php containing the methods below:
function __construct($dbServerName,$dbUsername,$dbPassword,$dbName)
{
$connectionInfo = array("Database"=> $dbName, "CharacterSet" => "UTF-8");
$this->sqlsrvLink = sqlsrv_connect($dbServerName, $connectionInfo);
if ($this->sqlsrvLink === false) {
$this->sqlsrvError = sqlsrv_errors();
}
}
function __destruct()
{
sqlsrv_close($this->sqlsrvLink);
}
i think you should set MultipleActiveResultSets to true when you want to connect to sql server :
$conn = sqlsrv_connect('127.0.0.1', array
(
'Database' => 'Adventureworks',
'MultipleActiveResultSets' => true, // MARS ENABLED
));
http://php.net/manual/de/ref.pdo-sqlsrv.connection.php
From your error, It seems like $nextQuery = sqlsrv_query($stmt2); is starting a new transaction in the same session. Can you commit !$firstQuery before starting the second?

Categories