Potential bug in PHP Stomp Client
walec51_me Dec 17, 2009 7:32 PMHi,
I think I stumbled upon a bug in the PHP Stomp Client 1.0. It seams sometimes I get two messages in one readFrame.
I have a PHP process subscribed to several topics and one queue on ActiveMQ 5.3. There are a dozens of remote JMS Java clients posting and listening to those topics and one JMS Java client posting to the queue. From time to time the the load gets high and readFrame returns two messages to one variable. When I do something like this with that message:
$msg = stomp->readFrame();
echo $msg;
I get:
MESSAGE
message-id: ID:server.xxx.pl-46732-1260956689799-0:0:2:3:470
destination: /queue/SITE.SERVER.REQ
timestamp: 1260987108641
expires: 0
priority: 4
#
#Wed Dec 16 19:11:48 CET 2009
client.2.score=3
client.1.id=4806
cmd=game_ended
win.code=1
game.time=30336
client.won.id=283
client.1.score=0
game.id=14754
client.2.id=283
^@
MESSAGE
message-id:ID:Sylwek-PC-61394-1260986134487-0:0:1:5:171
destination:/topic/LOBBY.EVENT.1
timestamp:0
expires:0
priority:4
#^M
#Wed Dec 16 19:10:02 CET 2009^M
client.name=mlody^M
cmd=lobby_ping^M
client.id=4084^@
Note that ^M and ^@ are non printable chars shown in vim. This coses my PHP client to stop listening to the LOBBY.EVENT.1 topic as I think ack only accepts the upper message.
My code that uses stomp looks something like this:
function run() {
try {
$this->log->info("Inicjalizowanie procesu");
$this->allConnect();
$this->connect_time = time();
$this->log->info("Rozpoczecie pracy ...");
while(!$this->stop) {
if((mktime() % 3) == 0)
$this->games->updateOnlinePlayers();
$msg = $this->con->readFrame();
$msgItr = 0;
while($msg) {
$this->log->debug("Otrzymano wiadomoĹ?Ä? ($msg)");
$params_raw = preg_split("/\n/", $msg);
$hash = array();
foreach($params_raw as $p) {
if(preg_match("/\s(+)\s=\s(.)/",
$p, $matches)
) {
$hash[trim($matches[1])] = trim($matches[2]);
}
}
$this->handleMessage($hash, $msg);
$this->con->ack($msg);
if($msgItr == 20) {
break;
}
$msg = $this->con->readFrame();
$msgItr += 1;
}
$this->nonInviteLobbyControl();
if(time() - $this->connect_time > 60*60) {
$this->log->info("Resetowanie poĹ?Ä?czenia");
$this->allDisconnect();
$this->allConnect();
$this->connect_time = time();
}
}
$this->log->info("Zakonczenie pracy");
$this->allDisconnect();
}
catch(Exception $e) {
$this->log->fatal($e->getMessage(), $e);
}
}
function allConnect() {
if(!$this->no_db) {
$this->log->info("Laczenie z baza $this->mysql_url, $this->mysql_name, $this->mysql_pass");
$this->link = mysql_connect($this->mysql_url, $this->mysql_name, $this->mysql_pass);
mysql_select_db($this->mysql_db, $this->link);
mysql_query('SET NAMES utf8 COLLATE utf8_general_ci;', $this->link);
$this->games = new mpg_games($this->link);
$this->params = new mpg_params($this->link);
}
else {
$this->games = new mpg_games_inmem();
}
$this->initStompConnection();
$this->initStompSubscription();
}
function allDisconnect() {
if(!$this->no_db) {
mysql_close($this->link);
}
$this->con->disconnect();
}
function initStompConnection() {
$this->con = new Stomp($this->stomp_url);
$this->con->setReadTimeout(1, 0);
$this->con->connect($this->stomp_name, $this->stomp_password);
}
function initStompSubscription() {
$this->con->subscribe("/queue/SITE.SERVER.REQ");
$this->con->subscribe("/queue/SITE.SERVER.RES");
$ls = $this->getLobbys();
foreach($ls as $l) {
$this->con->subscribe("/topic/LOBBY.EVENT.".$l);
$this->con->subscribe("/topic/LOBBY.SITE.EVENT.".$l);
$this->con->unsubscribe("/topic/LOBBY.SITE.EVENT.".$l);
$this->con->subscribe("/topic/LOBBY.CHAT.".$l);
$this->con->unsubscribe("/topic/LOBBY.CHAT.".$l);
}
}
I think this is a concurrency problem as it happens more as the load gets higher. I hope this info is of some help for the stomp developers.
Anyway thank you for the great software. I'm using ActiveMQJavaFXJavaPHPStomp in a small browser multilayer game Beside this every thing works great.