Forcing chat bot made with JAXL/XMPPHP to reconnect upon disconnection - php

I'm using the JAXL library to implement a jabber chat bot written in php, which is then ran as a background process using the PHP CLI.
Things work quite well, but I've been having a hard time figuring out how to make the chat bot reconnect upon disconnection!
I notice when I leave it running over night sometimes it drops off and doesn't come back. I've experimented with $jaxl->connect() and $jaxl->startStream(), and $jaxl->startCore() after jaxl_post_disconnect hook, but I think I'm missing something.

One solution would be to test your connection:
1) making a "ping" request to your page/controller or whatever
2) setTimeout(functionAjaxPing(), 10000);
3) then read the Ajax response and if == "anyStringKey" then your connection works find
4) else: reconnect() / errorMessage() / whatEver()
This is what IRC chat use i think.
But this will generate more traffic since the ping/ping request will be needed.
Hop this will help you a bit. :)

If you are using Jaxl v3.x all you need is to add a callback for on_disconnect event.
Also you must be using XEP-0199 XMPP Ping. What this XEP will do is, periodically send out XMPP pings to connected jabber server. It will also receive server pings and send back required pong packet (for instance if your client is not replying to server pings, jabber.org will drop your connection after some time).
Finally you MUST also use whitespace pings. A whitespace ping is a single space character sent to the server. This is often enough to make NAT devices consider the connection “alive”, and likewise for certain Jabber servers, e.g. Openfire. It may also make the OS detect a lost connection faster—a TCP connection on which no data is sent or received is indistinguishable from a lost connection.

What I ended up doing was creating a crontab that simply executed the PHP script again.
In the PHP script I read a specific file for the pid of the last fork. If it exists, the script attempts to kill it. Then the script uses pcntl_fork() to fork the process (which is useful for daemonifying a PHP script anyway) and capture the new PID to a file. The fork then logs in with to Jabber with JAXL per usual.
After talking with the author of JAXL it became apparent this would be the easiest way to go about this, despite being hacky. The author may have worked on this particular flaw in more recent iterations, however.
One flaw to this particular method is it requires pcntl_fork() which is not compiled with PHP by default.

Related

Multiple connection to php script on behalf of the same user

I have long running operations in my php app. It uses mod_rewrite so all traffic is heading to index.php. When it is doing those long running tasks it doesn't response in other cards in browser until task ends.
Is there any configuration allowing to multiple connection to one php script on behalf of the same user?
You can use Ajax or WebSocket. But there is no way to solve it with a pure server side solution because of blocking (operations are executed in order). You can try multi-threading, there is a pthread extension for PHP, but you have to compile PHP with it.
Other solution is to use some sort of work queue if you don't have to wait for the tasks to end and return some response from them.
#mlask reply about session_write_close() did exactly what i wanted. After calling session_write_close() next connection where accepted immediately.
more about session_write_close()

Send data with opened connection in PHP

I'm trying to find a solution to my problem with sending data to client with PHP. The biggest issue is - what I'm trying to do is to keep sending data inside a single connection with PHP script. I'm sure there are other ways but currently I don't know how to solve this.
What I'm trying to do is: A client connects to a web server and keeps the connection opened, so the TCP connection is "established". He will keep making for example GET requests every X seconds to keep this connection alive.
Inside of this connection on certain event I want to send the client some data without him making the request! So it means the event is triggered on the server side, not on the client side.
There is no possibility of using any JavaScript or any client-side technique as my client is Arduino module. I can keep the connection opened but I need to pass data to the client by using HTTP.
I have a database set up on the server and PHP will send data to the client when something changes inside the database.
I was trying to play with php flush() running in loop in the PHP script; but that doesn't do it the way I want.
So any advices appreciated.
Thank you.
edit: would be perfect it the solution would also work on Windows machine!
edit2: There will be multiple clients, not just one (eg hundreds)
As long as you don’t have lots of clients, Server-side Events sounds like it could work for you.
http://dsheiko.com/weblog/html5-and-server-sent-events
Just read that you will have hundreds of clients, in that case you probably won't want to use PHP but use node.js instead.
How about CRON jobs?
http://en.wikipedia.org/wiki/Cron
http://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/
I think that might be the solution for your project. If i undrestand CRON's correctly, what thy do is execute a given script at given intervals. So that is basicly what u want, scripts to execute for every X seconds. And inside your script u have your function working with the database.
I think what you are looking for is IPC - Inter Process Communication. In your case I would suggest a message queue (or multiple of those)
(On the client)
Open connection to foo.php
When receiving a new line, process it.
If connection times out, re-open it
(On the server - foo.php)
Open a Message Queue (You will have to register a message queue for each user!)
Register it so that your bar.php knows about it.
Start a blocking receive.
When a message is received, send whatever you want to send, FLUSH OUTPUT BUFFERS, go back to 2.
If anything times out, back to 2.
(On the server - bar.php)
When the database changes, send message to all active queues
There are a few problems with this approach:
The server side only really works on Linux / Unix (that includes Macs)
There is a limited number of message queues
You may have to do some housekeeping, removing old queues, etc.
The benefits:
This is application independent. Message queues are an operating system feature, thus your bar.php could really be say a java application.
Ok, so I think I found the way I want it to work. The problem why flush() wasn't working is that I didn't reach the flush buffer limit before flushing. Also I'm using Nginx server and I disabled gzip (just in case).
My test code which absolutely works looks like this:
<?
ob_implicit_flush(1);
for($i=0; $i<10; $i++){
echo $i;
//this is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
sleep(1);
}
?>
Found my answer here: PHP Flush that works... even in Nginx
I will test it with my Arduinos if it can accept such output. Thanks all for your help.

Ajax Long Polling Restrictions

So a friend and I are building a web based, AJAX chat software with a jQuery and PHP core. Up to now, we've been using the standard procedure of calling the sever every two seconds or so looking for updates. However I've come to dislike this method as it's not fast, nor is it "cost effective" in that there are tons of requests going back and forth from the server, even if no data is returned.
One of our project supporters recommended we look into a technique known as COMET, or more specifically, Long Polling. However after reading about it in different articles and blog posts, I've found that it isn't all that practical when used with Apache servers. It seems that most people just say "It isn't a good idea", but don't give much in the way of specifics in the way of how many requests can Apache handle at one time.
The whole purpose of PureChat is to provide people with a chat that looks great, goes fast, and works on most servers. As such, I'm assuming that about 96% of our users will being using Apache, and not Lighttpd or Nginx, which are supposedly more suited for long polling.
Getting to the Point:
In your opinion, is it better to continue using setInterval and repeatedly request new data? Or is it better to go with Long Polling, despite the fact that most users will be using Apache? Also, it possible to get a more specific rundown on approximately how many people can be using the chat before an Apache server rolls over and dies?
As Andrew stated, a socket connection is the ultimate solution for asynchronous communication with a server, although only the most cutting edge browsers support WebSockets at this point. socket.io is an open source API you can use which will initiate a WebSocket connection if the browser supports it, but will fall back to a Flash alternative if the browser does not support it. This would be transparent to the coder using the API however.
Socket connections basically keep open communication between the browser and the server so that each can send messages to each other at any time. The socket server daemon would keep a list of connected subscribers, and when it receives a message from one of the subscribers, it can immediately send this message back out to all of the subscribers.
For socket connections however, you need a socket server daemon running full time on your server. While this can be done with command line PHP (no Apache needed), it is better suited for something like node.js, a non-blocking server-side JavaScript api.
node.js would also be better for what you are talking about, long polling. Basically node.js is event driven and single threaded. This means you can keep many connections open without having to open as many threads, which would eat up tons of memory (Apaches problem). This allows for high availability. What you have to keep in mind however is that even if you were using a non-blocking file server like Nginx, PHP has many blocking network calls. Since It is running on a single thread, each (for instance) MySQL call would basically halt the server until a response for that MySQL call is returned. Nothing else would get done while this is happening, making your non-blocking server useless. If however you used a non-blocking language like JavaScript (node.js) for your network calls, this would not be an issue. Instead of waiting for a response from MySQL, it would set a handler function to handle the response whenever it becomes available, allowing the server to handle other requests while it is waiting.
For long polling, you would basically send a request, the server would wait 50 seconds before responding. It will respond sooner than 50 seconds if it has anything to report, otherwise it waits. If there is nothing to report after 50 seconds, it sends a response anyways so that the browser does not time out. The response would trigger the browser to send another request, and the process starts over again. This allows for fewer requests and snappier responses, but again, not as good as a socket connection.

How can a background service running in a webserver inform client browser the progress of the service?

First of all, I am completely new on many stuff, so I will welcome any inputs, including suggestions, existing projects, existing models, etc.
My current problems are:
The background service maintains a queue of tasks. The background service is written in C++ or python.
When a client clicks "Create Task" button in browser, the information will be sent to web server and the web server script (written in PHP) will initiate an RPC call to the background service to append the task to the internal queue.
The client browser will initiate an AJAX request to wait for the completion of the task. The AJAX request will hold until the task is completed (or failed) or the client cancels the request.
Thus, I need an low cost way to get the task progress which is run on a background service process.
I can think of two ways:
The background service can inform the server AJAX script about the progress pro-actively. This is low cost but I actually do not know how to do it. Does any RPC framework provides such asynchronous call back? Currently the RPC framework I decided to use is Thrift because of its multi-languages support.
The AJAX script on server side will make an RPC call to get current progress every a few seconds, and sleep in between. Upon completion, the AJAX script will return, otherwise it will just let the client browser wait by not returning. This is actually simpler but I am not sure about its cost. Note that delay isn't an issue to me here because I suppose that the clients are okay to wait for a few more seconds.
Is there any common way/model to deal with this problem?
Thanks for the help.
Depends on how you code it. The common way to do it is to make a javascripted ajax request every 1-3 seconds or so and poll the progress from the server.
This will intermediately close the connection and be more gentle to the server. If you use a persistent connection (WebSockets also fall into this category), you will keep the server busy. Besides, a "sleep" keeps the CPU busy - which is something I would try to avoid if I were you. On the other hand, if you've got the resources for that...
I can only repeat myself: it depends on how you code it and what you expect of it in the end.
If you want the client do some more work and treat the server gentle, choose your 1st option and if you think your server can handle it, choose the 2nd option and go "persistent" and even use WebSockets (which represent persistent connections to your server - remember that they aren't widely supported by web-browsing clients yet either).
Although I think that in the end - the trade-off of a simple progress compared to hogging your server CPU with constant sleeps and some persistent connections on-top of that will make you choose your 1st option: poll the server script for the progress value every x secs from the client side. Btw.: it's what Twitter does and their servers survived until today! ;)
I think, You can use WebSockets for that.
You can use WebSockets.
Establish a WebSockets connection between the client and a web service that has access to the information you need to pass to the client.
With web sockets, you don't need to poll the server asking it for progress, but rather have the server notify the client whenever it's ready.
A backwards compatible implementation would be long polling.
Cheers

How can I write a real time chat using XAJAX and PHP?

How can I write a real time chat using XAJAX and PHP?
In other words, is there a way to send xajax responses from the server to multiple clients?
Or is the only possibility to check for new messages every few seconds on client side?
No. Clients must "poll" the server repeatadly.
I think the key here is to think interaction design. The trick is to fool the user into thinking that the chat is instant, but when in reality it updates once every 1 or 2 or 3 or 10 seconds.
Ideas:
1) When the user sends a message, show it directly in the chat and trigger a poll.
2) If a poll comes back with multiple messages from other users, don't add them all at once, actually add them over a period of 1-2 sec or so, with random spacing, making it look like they're coming in "instantly" and independently. (If a bunch of messages come in at once the user is very quick to realize that the chat updated there and then, and not continiously.)
3) If the user is idle for x amount of time. Drop the poll rate to once every 10sec or so.
4) If the user is active, ie sending a lot of messages, poll more often.
5) Have a static file for every channel that your write the time the chat last updated to. For instance file chat-teenfun-lastupdate.txt has the contents 1224934239 or whatever time format you prefer. Serve this file statically and let clients poll this file in order to check if the channel has updated, rather that calling chat-poll.php?ch=teenfun that does a dynamic check. Static files are served around 10-100 times faster, depending on the work involved for the dynamic script, and you're gonna need it when you get 250+ users polling.
Good luck and have fun!
/0
PS. Alternatively you could actually let clients do an ajax call to the server and keep them 'hanging'. That is you accept their request and pretend to start sending data back, but then you just pause. When something happends you finish the response with the approriate data. For this to work I believe you'd need to write your own HTTP-server though, that does this specifically, as you can't have 250 php processes hanging around in memory. Maybe Lighttpd could be used in this way somehow with that LUA cache mod. I don't know. Would be interesting though. Hell I gotta try it sometime :)
Sure there is, but I don't think it'll be very efficient with many users. You can either do polling where each client polls the server to see if there are any new messages, or you could use the comet technique in which the server can push new messages to the clients - Check out the Comet plugin for XAJAX. How this would be implemented using XAJAX and PHP is beyond me, but here's how I would try to implement it.
Let each client connect to the server (login etc), then:
For each message sent by a client (sender) update the message queue for client (receiver)
Let client poll server for new messages in the queue / Push the new messages via comet.
Update GUI if there are new messages.
Rinse, lather, repeat
Using a true IM server like ejabberd could go a long way, be more efficient and allow your users to connect via desktop clients (if that's what you want). I'd probably use that as a backend, IOW ejabberd would be the server and PHP would be the client using XMPP in PHP, and act as a proxy for the webgui.
See also:
Google Techtalk on Gmail's chat feature (and scalability issues)
That's my $0.02
As long as there there is not HTTP push technology you will never get a realtime chat only using JavaScript.
Possible workarrounds:
use a Flash Movie or a Java Applet to perform some socket communication
hold polling requests back on the server side for a few seconds
You could use websockets, but being a new HTML5 feature it's kinda limited. Lucky for you there is socksjs, which implements websockets on browsers that do not handle it.
On the hosting side you should be able to use any websockets server, there's a few for PHP.
If you are looking to implement a chat server written with a scripting language such as PHP/JSP, technique of hanging HTTP connection will have to be ticked off from your your options list. The reason is most of the web severs (specially shared hosts) don't like too many connections hanging.
You can find everything you need to implement a web client and PHP chat server in this "Optimized Chat Server Protocol for Server Side Scripting Languages" publication.
The best strategy I've seen is to do an AJAX request for messages and then restart that exact same request as soon as it finishes.
On the server side, make the script "stall" for 60 seconds or until a new message is received. This keeps the same connection open for a max of 60 seconds, but when a new message is received, it outputs it and stops immediately, prompting the client-side AJAX to open another connection.
This provides almost instant notification of new messages and is also much easier on the server than making a new connection every x seconds.

Categories