xmppo / xmpp-php

PHP client library for XMPP (Jabber) protocol
https://github.com/xmppo/xmpp-php
MIT License
45 stars 23 forks source link

15/20 seconds to send a message #6

Closed dioobr closed 5 years ago

dioobr commented 5 years ago

Hi,

I need to understand what I'm doing wrong or what I need to improve in my code to speed up sending messages.

Here my PHP script:

<?php

namespace Norgul\Xmpp;

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

require __DIR__.'/vendor/autoload.php';

$options = new Options();
$options->setHost("xmpp.example.com");
$options->setPort(5222);
$options->setUsername("maria");
$options->setPassword("12345678@");

$client = new XmppClient($options);
$client->connect();
$client->iq->getRoster();

$client->message->send('Sample message', 'diogo@xmpp.example.com');

$response = $client->getResponse();
$client->prettyPrint($response);

$client->disconnect();

I can send messages, but every message takes 15 to 20 seconds to send, so I think something is wrong.

Here the log generated by the PHP script:

2019.06.10 03:06:30 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <?xml version='1.0' encoding='UTF-8'?><stream:stream to='xmpp.example.com' xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' version='1.0'>
2019.06.10 03:06:32 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 <?xml version='1.0'?><stream:stream id='5454702324109226903' version='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' from='xmpp.example.com' xmlns='jabber:client'><stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls></stream:features>
2019.06.10 03:06:32 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
2019.06.10 03:06:34 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
2019.06.10 03:06:34 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <?xml version='1.0' encoding='UTF-8'?><stream:stream to='xmpp.example.com' xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' version='1.0'>
2019.06.10 03:06:36 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 <?xml version='1.0'?><stream:stream id='1254184880686051019' version='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' from='xmpp.example.com' xmlns='jabber:client'><stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism><mechanism>SCRAM-SHA-1</mechanism><mechanism>X-OAUTH2</mechanism></mechanisms><register xmlns='http://jabber.org/features/iq-register'/></stream:features>
2019.06.10 03:06:36 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>AG1hcmlhADEyMzQ1Njc4QA==</auth>
2019.06.10 03:06:38 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
2019.06.10 03:06:38 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <?xml version='1.0' encoding='UTF-8'?><stream:stream to='xmpp.example.com' xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' version='1.0'>
2019.06.10 03:06:40 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 <?xml version='1.0'?><stream:stream id='1118384314067387153' version='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' from='xmpp.example.com' xmlns='jabber:client'><stream:features><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'><optional/></session><c ver='M0fso8w56U7RB1HYmBkwKOuBrgw=' node='http://www.process-one.net/en/ejabberd/' hash='sha-1' xmlns='http://jabber.org/protocol/caps'/><sm xmlns='urn:xmpp:sm:2'/><sm xmlns='urn:xmpp:sm:3'/><ver xmlns='urn:xmpp:features:rosterver'/><csi xmlns='urn:xmpp:csi:0'/></stream:features>
2019.06.10 03:06:40 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <iq type='set' id='5cfdf3e84a9bf'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>norgul_machine_1560146920</resource></bind></iq>
2019.06.10 03:06:42 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 <iq type='result' id='5cfdf3e84a9bf'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>maria@xmpp.example.com/norgul_machine_1560146920</jid></bind></iq>
2019.06.10 03:06:42 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <presence/>
2019.06.10 03:06:44 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 <presence xml:lang='en' to='maria@xmpp.example.com/norgul_machine_1560146920' from='maria@xmpp.example.com/norgul_machine_1560146920'><x xmlns='vcard-temp:x:update'/></presence><presence xml:lang='en' to='maria@xmpp.example.com/norgul_machine_1560146920' from='maria@xmpp.example.com/norgul_machine_1560144963'><x xmlns='vcard-temp:x:update'/><delay from='maria@xmpp.example.com/norgul_machine_1560144963' stamp='2019-06-10T05:36:05.659905Z' xmlns='urn:xmpp:delay'/></presence><presence xml:lang='en' to='maria@xmpp.example.com/norgul_machine_1560146920' from='maria@xmpp.example.com/norgul_machine_1560144532'><x xmlns='vcard-temp:x:update'/><delay from='maria@xmpp.example.com/norgul_machine_1560144532' stamp='2019-06-10T05:28:55.324303Z' xmlns='urn:xmpp:delay'/></presence><presence xml:lang='en' to='maria@xmpp.example.com/norgul_machine_1560146920' from='maria@xmpp.example.com/norgul_machine_1560144631'><x xmlns='vcard-temp:x:update'/><delay from='maria@xmpp.example.com/norgul_machine_1560144631' stamp='2019-06-10T05:30:33.998640Z' xmlns='urn:xmpp:delay'/></presence><presence xml:lang='en' to='maria@xmpp.example.com/norgul_machine_1560146920' from='maria@xmpp.example.com/norgul_machine_1560144960'><x xmlns='vcard-temp:x:update'/><delay from='maria@xmpp.example.com/norgul_machine_1560144960' stamp='2019-06-10T05:36:02.821380Z' xmlns='urn:xmpp:delay'/></presence>
2019.06.10 03:06:44 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <iq type='get' id='5cfdf3ec51787'><query xmlns='jabber:iq:roster'/></iq>
2019.06.10 03:06:46 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 <iq xml:lang='en' to='maria@xmpp.example.com/norgul_machine_1560146920' from='maria@xmpp.example.com' type='result' id='5cfdf3ec51787'><query xmlns='jabber:iq:roster'/></iq>
2019.06.10 03:06:46 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 <message to='diogo@xmpp.example.com' type='chat'><body>Complementando mensagem para envio e tudo certo</body></message>
2019.06.10 03:06:48 5cfdf3de3f7f4 REQUEST::Norgul\Xmpp\Socket::send::57 </stream:stream>
2019.06.10 03:06:48 5cfdf3de3f7f4 RESPONSE::Norgul\Xmpp\Socket::receive::78 </stream:stream>
Norgul commented 5 years ago

Hi @dioobr sending messages isn't the issue. The "problem" here is that the server you're connecting to uses TLS. The process of establishing a TLS tunnel and complete auth process is what takes time because it's a series of request-response cycles.

Once you are authenticated, sending messages will go with XMPP "standard" speed.

You can check this by doing something like this:

$client->message->send('Sample message', 'diogo@xmpp.example.com');

$response = $client->getResponse();
$client->prettyPrint($response);

sleep(2);
echo "Sending another";

$client->message->send('Sample message 2', 'diogo@xmpp.example.com');

Second message should arrive much faster.

It is all normal that 15s will pass each time you start your script since new session is established every time you start the script, thus you don't have a continuous active session. You can look at it as a startup time (like for example when you start Skype app, it takes time to bring it up initially, but once it is up, you are receiving messages in real time).

dioobr commented 5 years ago

Hi @Norgul,

Thanks for the quick response. I'm not used to this kind of routine. Do you think there is any way to preserve the authenticated session without an "infinite" loop?

Norgul commented 5 years ago

Library was intended to provide a low level socket connection to XMPP servers. While the continuous session may be simulated with the infinite loop, the correct way would be to use a piece of software that does this for you.

Specifically, within the production environment I am using Ratchet which is a web socket library. Every continuous and real time communication should be done over WS protocol (old methods were polling and long-polling).

It enables you to do something like

$server->loop->addPeriodicTimer(0.1, [$app, 'checkMessages']);

which is basically adding a timer which is checking messages (or responses, whatever you'd like) periodically (here 0.1s). You can run that script then as a process which will be exposed to the outside world on some port, which should be a WS port (check for ws:// and wss:// protocols).

The solution is unfortunately not so trivial so that I can paste it here, because I've basically brought up a Docker container which is running the script, exposing the port on which I can connect. Ratchet WS is calling my library then. The communication process goes something like this:

Client (Chrome) <--> WS port <--> Docker /w Ratchet process <--> XMPP-PHP
dioobr commented 5 years ago

Thanks for the sugestion. I'll take a look.