-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use getSocket return value in PHP? #22
Comments
I'm not entirely sure if this is useful, as I've not played with React and Mosquitto together yet, but I do have an example of using the result of getSocket with ext/event: https://github.com/mgdm/Mosquitto-PHP/blob/master/examples/event.php Does that help at all? |
@mgdm Thank you very much. But I learned about the pecl event extension, and found that React-PHP actually supports it already, I just had to uninstall the libevent extension first. |
@kernelguy Did you try to specifically make a PHP socket resource and register it? Looking at PHP's socket_create() a PHP socket resource is created from the integer reference returned from the POSIX socket() call. This is thrown into a struct with its type and is registered as a PHP resource and returned using; RETURN_RES(zend_register_resource(php_sock, le_socket)); Surely something very similar must be doable on an already existing socket? An alternative socket_create() could probably do it, but it would be annoying to have to deal with a homebuilt PHP compared to an extension. Mikkel |
It doesn't return a resource right now, but when I get a spare minute I'll try it and see if it actually works. |
Got it to compile using this patch. Haven't tested it runtime yet ;). On master branch they use zend_register_resource() instead of ZEND_REGISTER_RESOURCE() in socket_create(). (valid link to non-master; https://github.com/php/php-src/blob/PHP-5.5.12/ext/sockets/sockets.c#L1370).
|
Cool, thanks! If you get a chance to test it Is quite happily merge a PR :-)
|
@mikini Nice digging ;-) I tried it and got a runtime error on a missing IS_INVALID_SOCKET. #ifdef PHP_WIN32
# include <win32/sockets.h> /* Not tested */
#else
# define IS_INVALID_SOCKET(a) (a->bsd_socket < 0)
# define set_errno(a) (errno = a)
#endif I looped the following test code: $read = array($client->getSocket());
$write = null;
$except = null;
debug_log("print_r(\$read): ".print_r($read, true));
$num_changed_sockets = socket_select($read, $write, $except, 30);
if ($num_changed_sockets === false) {
} else if ($num_changed_sockets > 0) {
$client->loop(0);
} And the first call to getSocket returns a valid resource, but the second caused socket_select to bark an exception:
|
Hi folks, If that's any use to you, then I'll merge it. I've got tests for it in another branch too that will land shortly. |
Thanks for following up on this, Michael. The PR looks fine, but one major issue came up after digging into @kernelguy 's loop problem; Output from PHP with "php_error_docref(NULL, E_NOTICE, "socket fd: %i", sockfd);" in getSocket() and var_dump($socket) in a loop doing assignment of getSocket() to $socket then socket_select():
Of course this also sever the mosquitto client library's connection with the MQTT broker. Can't elaborate on the correct way for the library to react to being back-stabbed like this. But at least I think mosquitto_socket() ought to check whether it has a valid socket before returning it. I'm cooking up a mosquitto bug report raising this question. Regarding Mosquitto-PHP, could getSocket() somehow mark the socket resource to be non-collectable by the GC to prevent it from closing the mosquitto file descriptor? Mikkel |
Ah ha. I have an idea, I'll attempt to implement it. Basically, we can up the ref count on the zval that |
Sounds exactly like "the right thing" to do ;). |
The ref count solution works for me. I still have one issue though: When I close the mosquitto server, I get an onDisconnected event which is correct. But now, using this socket, I get a lot of spurious "socket ready for read" events, even though no data is available. Could it be that getSocket still returns the old socket? |
I would like to use Mosquitto-PHP together with React-PHP.
React-PHP uses stream_select to detect if a socket is ready for something.
The socket parameter used in stream_select and socket_select are resources, but the Mosquitto-PHP getSocket function returns a long integer.
I have never written any extension code my self, but tried to look at the code for stream and sockets, to see if I could change the unix socket to a PHP resource before returning from getSocket. But they seem to use two different resources.
Does anybody know how to convert a unix socket (integer) to a PHP resource?
The text was updated successfully, but these errors were encountered: