When it comes to long links, you must be familiar with the continuous data interaction with a link, unlike those one-night stand-by services that require frequent opening and closing links, low efficiency and increased complexity of the business. In the crotch a lot of internet business scenes need long connection support, such as: games, chat, information push and so on, and so on, today we will step by step to uncover the PHP long connection play. I believe that the implementation of any technology is due to the needs of the business scene, so this time we have chat room to say things.
0x00 a sledgehammer.
Remember used to write in PHP chat room or with polling way, no doubt, a mention of polling, will certainly be someone said long polling, yes! Long polling is also very good, but play on nginx+fpm above a little bit laborious, after all, a request needs to occupy a PHP process (even with apache+php_mod, also need a request a thread), so if a few people casually play it OK, Once you put it on the line, it's basically obsolete. So it's still in the polling way, so it doesn't block the process, and a request is immediately responsive, but the new problem is the need to keep sending requests to the server, and the greater the time it takes to delay the message.
0x01 Gorgeous change body
In the experience of the above kind of a small card, three seconds a kcal scene! No longer see, so decided to become a real man, oh no, should be a real long connection. Fuck polling, go fuck long polling, fuck webserver, all stand aside and let Flash sockets (or websocket) rule the world! Started the long connection journey in the real sense. To play a long connection will always have to deal with the socket, as the best language in the world (no one), the encapsulation of the socket is naturally the drop. Copy up the socket_*** to open dry, so there is the following this support code, long connection is it? The delay, huh? Socket, right? Soup, huh? So easy ....
- $SFD = Socket_create (af_inet, sock_stream, 0);
- Socket_bind ($SFD, "0.0.0.0", 1234);
- Socket_listen ($SFD, 511);
- Socket_set_option ($SFD, Sol_socket, SO_REUSEADDR, 1);
- Socket_set_nonblock ($SFD);
- $rfds = Array ($SFD);
- $wfds = Array ();
- do{
- $rs = $rfds;
- $ws = $wfds;
- $es = Array ();
- $ret = Socket_select ($rs, $ws, $es, 3);
- Read Event
- foreach ($rs as $FD) {
- if ($fd = = $SFD) {
- $CFD = Socket_accept ($SFD);
- Socket_set_nonblock ($CFD);
- $rfds [] = $CFD;
- echo "New client coming, fd= $CFD \ n";
- }else{
- $msg = Socket_read ($FD, 1024);
- if ($msg <= 0) {
- Close
- }else{
- Recv msg
- echo "On", fd= $fd data= $msg \ n ";
- }
- }
- }
- Write Event
- foreach ($ws as $FD) {
- Socket_write ($FD, ...);
- }
- }while (TRUE);
0x02 the Pinnacle
From the day of playing socket, Google Whisper with me, high concurrent select Do not use Ah, the efficiency of Ah, win to use IOCP Ah, Linux to use Epoll Ah, blablablabla ... Oh! Well, since Google has said so, I can not be honest with his old man, another decision (why to say again?) To listen to Google, the Epoll get up, but can not write their own ah? Like me so lazy people or the whole expansion of the good, libevent walk you! After the Crazy series (CO) code (PY), God has finally come out, concrete can be more efficient, can support how many concurrent, not made, anyway, no use SELECT, I played is cock!
- $SFD = Stream_socket_server (' tcp://0.0.0.0:1234 ', $errno, $ERRSTR);
- Stream_set_blocking ($SFD, 0);
- $base = Event_base_new ();
- $event = Event_new ();
- Event_set ($event, $SFD, Ev_read ev_persist, ' ev_accept ', $base);
- Event_base_set ($event, $base);
- Event_add ($event);
- Event_base_loop ($base);
- function ev_accept ($socket, $flag, $base)
- {
- $connection = Stream_socket_accept ($socket);
- Stream_set_blocking ($connection, 0);
- $buffer = Event_buffer_new ($connection, ' Ev_read ', NULL, ' Ev_error ', $connection);
- Event_buffer_base_set ($buffer, $base);
- Event_buffer_timeout_set ($buffer, 30, 30);
- Event_buffer_watermark_set ($buffer, Ev_read, 0, 0XFFFFFF);
- Event_buffer_priority_set ($buffer, 10);
- Event_buffer_enable ($buffer, Ev_read ev_persist);
- }
- function Ev_error ($buffer, $error, $connection)
- {
- Event_buffer_disable ($buffer, Ev_read ev_write);
- Event_buffer_free ($buffer);
- Fclose ($connection);
- }
- function Ev_read ($buffer, $connection)
- {
- $read = Event_buffer_read ($buffer, 256);
- Do something ....
- }
0X03 Ledge
As the number of growth, concurrent ascension, a single process has not met the demand, Timberg's story tells us, singled out is not the group P, how the whole? As the saying goes, small, trivial, stop!! No more, no more of it. Demolition, the single process into a number of processes, but after the demolition and face a new problem, interprocess communication, load balancing, session only, and so on. Since the question has been raised, there must be a solution, there are extensions and libraries to solve this problem, such as: Swoole,workerman and so on? By contrast, swoole a bit more, sex, function, uh! As if this shorthand is not very elegant, well, performance and function more cock Some (barrel elder brother, please forgive my boring ~) .... Wait a minute!!! However, when we are using PHP to develop the web, we do not use Webserver related libraries for development, right? I'm just a simple echo. These miscellaneous things are to the Nginx or Apache, is their duty-bound to the top in front, so that we can concentrate on writing logic. Write the web we simply need to configure Nginx and fpm just fine, that write socket service? Why can't we just configure as simple as nginx+fpm?? Of course, we must be able to ... Look at this story is afraid of advertising to come ...
0x04 Surprise
Write socket service is not more than writing web advanced, are playing code, is the completion of the requirements, communication that layer is fixed, but one by the Nginx, and the other by themselves to complete. But now do not need to complete their own, similar to the NGINX+FPM scheme, fooking+fpm=php long connection, Gateway used to host the connection, router for forwarding messages, interprocess communication? Load Balancing? Session only? So easy.
- $sid = $_server[' SESSIONID '];//this is SESSIONID
- $data = file_get_contents ("Php://input");//So you can get the request content.
- It only takes two steps to return the message
- Header (' content-length:11 ');//Return to client bytes
- echo "Hello World";
- Want to send a message to another user
- Include ' api.php ';
- $router = new Routerclient (' Router host ', ' Router port ');
- $router->sendmsg (user SessionID, "fuck You");
- Want to give everyone a message
- $router->sendallmsg ("Fuck all");
- Want to send a message to a specified group (similar to Redis pub/sub)
- $router->publish ("channel name", "Fuck All");
Project Address: http://git.oschina.net/scgywx/fooking
Document address (not regularly updated): http://my.oschina.net/scgywx/blog/465186