Home  >  Article  >  Backend Development  >  PHP implements long connection method

PHP implements long connection method

小云云
小云云Original
2018-03-21 11:50:004555browse

Hold a connection on the server side and do not return immediately. It will not return until there is data. This is the principle of long connection technology. This article mainly shares with you the method of implementing long connection in PHP. I hope it can help everyone.

The key to long connection technology is to hold an HTTP request and not respond to the request until there is new data. Then the client automatically initiates a long connection request again.

How to hold a request? Woolen cloth? The server-side code may look like this

set_time_limit(0);  //这句很重要, 不至于运行超时while (true) 
、{    if (hasNewMessage()) 
{        echo json_encode(getNewMessage());        break;
    }
    usleep(100000);      //避免太过频繁的查询}


Yes, it is to hold a request through a loop so as not to return immediately. Only after new data is queried Respond to the request. Then after the client processes the data, it initiates a long connection request again.

The client code is like this

<script type="text/javascript">
    (function longPolling() {
        $.ajax({            &#39;url&#39;: &#39;server.php&#39;,            &#39;data&#39;: data,            &#39;dataType&#39;: &#39;json&#39;,            &#39;success&#39;: function(data) {
                processData(data);
                longPolling();
            },            &#39;error&#39;: function(data) {
                longPolling();
            }
        });
    })();</script>

A simple chat room

Through long connections, we can develop a simple web chat room

Next, we develop a simple web chat room through redis

  1. Each client When initiating a long connection, a message queue is generated on the server side, corresponding to the user. Then it monitors whether there is new data, returns the data to the client for processing, and initiates a long connection request again.

  2. When each client initiates a message, it broadcasts the message queue.

The following is the code snippet:

<?php namespace church\LongPolling;use Closure;use church\LongPolling\Queue\RedisQueue;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\JsonResponse;class Server{
    public $event = [];    public $redisQueue = null;    public $request = null;    public $response = null;    public function __construct()
    {
        $this->redisQueue = new RedisQueue();        $this->request = Request::createFromGlobals();        $this->response = new JsonResponse();
    }    public function on($event, Closure $closure)
    {
        if (is_callable($closure)) {            $this->event[$event][] = $closure;
        }
    }    public function fire($event)
    {
        if (isset($this->event[$event])) {            foreach ($this->event[$event] as $callback) {
                call_user_func($callback, $this);
            }
        }
    }    public function sendMessage($data)
    {
        switch ($data[&#39;type&#39;]) {            case &#39;unicast&#39;:     //单播
                $this->unicast($data[&#39;target&#39;], $data[&#39;data&#39;], $data[&#39;resource&#39;]);                break;            case &#39;multicast&#39;:       //组播
                foreach ($data[&#39;target&#39;] as $target) {                    $this->unicast($target, $data[&#39;data&#39;], $data[&#39;resource&#39;]);
                }                break;            case &#39;broadcast&#39;:       //广播
                foreach ($this->redisQueue->setQueueName(&#39;connections&#39;) as $target) {                    $this->unicast($target, $data[&#39;data&#39;], $data[&#39;resource&#39;]);
                }                break;
        }        $this->fire(&#39;message&#39;);
    }    public function unicast($target, $message, $resource = &#39;system&#39;)
    {
        $redis_queue = new RedisQueue();        $redis_queue->setQueueName($target)->push($resource . &#39;:&#39; . $message);
    }    public function getMessage($target)
    {
        return $this->redisQueue->setQueueName($target)->pop();
    }    public function hasMessage($target)
    {
        return count($this->redisQueue->setQueueName($target));
    }    public function run()
    {
        $data = $this->request->request;        while (true) {            if ($data->get(&#39;action&#39;) == &#39;getMessage&#39;) {                if ($this->hasMessage($data->get(&#39;target&#39;))) {                    $this->response->setData([                        &#39;state&#39; => &#39;ok&#39;,                        &#39;message&#39; => &#39;获取成功&#39;,                        &#39;data&#39; => $this->getMessage($data->get(&#39;target&#39;))
                    ]);                    $this->response->send();                    break;
                }
            } elseif ($data->get(&#39;action&#39;) == &#39;connect&#39;) {                $exist = false;                foreach ($this->redisQueue->setQueueName(&#39;connections&#39;) as $connection) {                    if ($connection == $data->get(&#39;data&#39;)) {                        $exist = true;
                    }
                }                if (! $exist) {                    $this->redisQueue->setQueueName(&#39;connections&#39;)->push($data->get(&#39;data&#39;));   
                }               
                $this->fire(&#39;connect&#39;);                break;
            }
            usleep(100000);
        }
    }
}

The source code has been open sourced to github

A web version of a simple chat room developed based on long connections. Long connections avoid too frequent polling. However, maintaining a long connection on the server also consumes additional resources. The performance is not ideal when there is large concurrency. It can be considered in small applications. use. It is more recommended that the client uses the html5 websocket protocol and the server uses swoole.

Related recommendations:

How does php socket implement long connections

A brief analysis of the principles of http long connections and short connections

The implementation of long connections in PHP

The above is the detailed content of PHP implements long connection method. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn