PHP socket_read returns empty string - php

I wrote a PHP class for a websocket client that allows you to connect to websocket servers from PHP. It works very well, except that it can only read data in an infinite loop. In a websocket connection, the server or the client can send data whenever they want, as many times as they want. Unfortunately, socket_select, socket_read, and socket_recv won't block if any data has been sent by the other socket - socket_select will return immediately, and socket_read and socket_recv will return an empty string. I tried making the process sleep until it received SIGPOLL, but that caused it to sleep indefinitely. Is there any way to know more data is available on the socket after data has already been received?

PHP is not a good language to go forth with this as it is not an asynchronous language. I would suggest Node.js or something similar.
I may not know much about PHP and websockets, but couldn't you just loop it until you hit SIGPOLL?

Related

How to send a GET request with cookies and do not wait for response using PHP

I want to send some info to a server using cookie for authentication:
http://exampleserver.com/get?parm1=val1&parm2=val2&parm3=val3
with
cookie1=asd123;cookie2=enc%19
I want only to send the request and do not wait for the response. I only need server to register the data, as depending on amount of the data sent, tge wait for the response from client side could become too high, and so I want it to be fast.
I know PHP is blocking, but is is possible to do this in some way?
I think that what you want to obtain is like an asynchronous call to the server, which in PHP can be done using "threading", the quotes are here because is not properly threading what is possible in PHP, but almost.
You can find here the answer to your question
PHP threading call to a php function asynchronously

APNs Server for handling streams from PHP script

I have a web server that sends push notifications to devices when certain actions are performed with a POST or GET. This works, but because of the nature of having to open an SSL connection to APNS, write all the tokens and exit, the actions that involve this operation are latent compared to those who do not. The latency is only a second or so, but a second is still significantly longer than say 100ms, which is how long it takes otherwise (if I comment out the APNS part).
It seems that it's also bad practice to open and close the connection to APNS every time you want to send notifications, not only because of the extra time it takes. I believe a better approach would be to have a different server (not running PHP) handle the stream writing to APNS and receive tokens and messages by let's say some kind of python service, perhaps.
Basically:
Web Server sends fwrite by php (unencrypted, no SSL) to a socket on a local server that has a persistent connection to APNS open, which also is asynchronous in its handling of the response from to the APNS operation: The problem is that PHP will wait until it has written all bytes to the socket before it echoes the desired response to the client. I would imagine it takes much less time to fwrite to a local server unencrypted than it does to SSL to APNS. Correct me if I'm wrong.
I don't have a lot of experience with Python, but as far as I know it's not that hard.
I have the tokens stored in MySQL and retrieving and generating the payload with PHP in place and working - it's just slowing everything down the way it's set up now.
I cannot find any guides on this subject - only how to do what I am already doing with fwrite and OpenSSL in PHP.
I seek suggestions as how to best handle this situation.
You don't need to switch to Python to solve this issue. What you could do is tweak your design a bit to resemble more of "dump and purge" concept.
Basically, the scripts that receive the GET and POST calls dump the data related to the push notification payload locally.
In the background, you have a PHP script running all the time that has already established a connection with APNS and just checks constantly if anything has been dumped locally and needs to be sent.
Script A (The dumper):
// ... something triggers a push ...
if ($_GET['something'] == 'foo') {
$data = // Get all data needed to build push
createPayload($data); // Dump data somewhere; file or database
}
// ... something else maybe ...
return; // Return asap to not keep client waiting
Script B (The purger):
$apns = // Open connection to Apple Push server
while (TRUE) {
// Read file or database where payloads get dumped
$success = (fwrite(payload to $apns));
sleep(5); // Sleep a bit to avoid CPU going crazy
if (!$success) {
// Reopen connection with Apple
}
}
// Close apns here in case you have a break condition in your loop
Using two scripts instead of one, you will return to your client as quickly as possible and still be able to send push notification quickly to Apple's servers.

does the php pg_connection_busy func discriminate source of busy

When sending the status request pg_connection_busy(), does the request discriminate between "connection busy" and "server busy" ?
In other words, a server has 100 allowed connections, with one of them applied to the current script. All 100 connections simultaneously send a query, with 99 of them requiring 2+ seconds of processing time, (theoretically putting the server into a maxed out state thus making it "busy"). One of those 100 requests was a pg_server_busy() request. Would the response be True or False?
pg_connection_busy() basically calls libpq's PQconsumeInput() followed by PQisBusy(), both are documented in
Asynchronous Command Processing.
This has nothing to do with the server being busy overall with other connections. Also it doesn't send anything to it, query or otherwise, it's purely a local condition about the buffering of the incoming data when retrieving results asynchronously.
Unfortunately the example given by php's documentation is misleading. It calls pg_connection_busy() on a new connection without any asynchronous query running, which doesn't make any sense.

How does Long Polling or Comet Work with PHP?

I am making a notification system for my website. I want the logged in users to immediately noticed when a notification has made. As many people say, there're only a few ways of doing so.
One is writing some javascript code to ask the server "Are there any new notifications ?" at a given time interval. It's called "Polling" (I should be right).
Another is "Long Polling" or "Comet". As wikipedia says, long polling is similar to polling. Without asking everytime for new notifications, when new notifications are available, server sends them directly to the client.
So how can i use Long Polling with PHP ? (Don't need full source code, but a way of doing so)
What's its architecture/design really ?
The basic idea of long-polling is that you send a request which is then NOT responded or terminated by the server until some desired condition. I.e. server-side doesn't "finish" serving the request by sending the response. You can achieve this by keeping the execution in a loop on server-side.
Imagine that in each loop you do a database query or whatever is necessary for you to find out if the condition you need is now true. Only when it IS you break the loop and send the response to the client. When the client receives the response, it immediately re-sends the "long-polling" request so it wouldn't miss a next "notification".
A simplified example of the server-side PHP code for this could be:
// Set the loop to run 28 times, sleeping 2 seconds between each loop.
for($i = 1; $i < 29; $i++) {
// find out if the condition is satisfied.
// If YES, break the loop and send response
sleep(2);
}
// If nothing happened (the condition didn't satisfy) during the 28 loops,
// respond with a special response indicating no results. This helps avoiding
// problems of 'max_execution_time' reached. Still, the client should re-send the
// long-polling request even in this case.
You can use (or study) some existing implementations, like Ratchet. There are a few others.
Essentially, you need to avoid having apache or the web server handle the request. Just like you would with a node.js server, you can start PHP from the command line and use the server socket functions to create a server and use socket_select to handle communications.
It could technically work throught the web server by keeping a loop active. However, the memory overhead of keeping a php process active per HTTP connection is typically too high. Creating your own server allows you to share the memory between connections.
I used long polling for a chat application recently. After doing some research and playing it with a while here are some things I would recommend.
1) Don't long poll for more than about 20 seconds. Some browsers will timeout. I normally set my long poll to run about 20 seconds and send back an empty response at that point. Then you can use javascript to restart the long poll.
2) Every once in a while a browser will hang up. To help add a second level of error checking, I have a javascript timer run for 30 seconds and if no response has come in 30 seconds I abandon the ajax call and start it up again.
3) If you are using php make sure you use session_write_close()
4) If you are using ajax with Jquery you may need to use abort()
You can find your answer here. More detail here . And you should remember to use $.ajaxSetup({ cache:false }); when working with jquery.

How to print http response first and do the heavy db operations later?

I'm implementing a mobile api. One of the requests processes json data and returns afterwards a predefined message( is independent from the calculation) back to the device. I'm using kohana 3.
How do I return the http response first and do the calculation afterwards?
What do you think about, using a message queue and a separate program that does the processing and db operations?
One option would be to use gearman. There is a Kohana gearman module made by one of the Kohana devs.
Maybe you can help flush() function, which send buffer (and header also). But flush() don't guarantee header send, because between php and web browser stays a web server (like apache)
Not sure I understand your question, but if you want to buffer output you can use ob_start() and ob_get_clean()
I think you might be looking for something like
ignore_user_abort(true)
http://www.php.net/manual/en/function.ignore-user-abort.php
After making the call you can send your response back to the browser and finish wrapping up your calculations/logging after the connection is closed and the client is off doing something else.
This enables you to do some quick processing without hanging up the client or having to use an external process to handle your tasks

Categories