Home >PHP Framework >Workerman >Workerman-based real-time push (abandoning ajax polling)

Workerman-based real-time push (abandoning ajax polling)

藏色散人
藏色散人forward
2020-01-20 13:43:593339browse

The following column workerman tutorial will introduce to you how to implement real-time push based on workerman and abandon ajax polling. I hope it will be helpful to friends in need!

Workerman-based real-time push (abandoning ajax polling)

Let’s talk about these things first:

TCP/IP

TCP/IP is a protocol group. It is divided into three layers: network layer, transport layer and application layer.

In the network layer, there are IP protocol, ICMP protocol, ARP protocol, RARP protocol and BOOTP protocol.

There are TCP protocol and UDP protocol in the transport layer.

In the application layer there are:

TCP includes FTP, HTTP, TELNET, SMTP and other protocols

UDP includes DNS, TFTP and other protocols

Short connection

Connect->Transfer data->Close connection

HTTP is stateless. Every time the browser and server perform an HTTP operation, The connection is established once, but the connection is terminated when the task is completed.

It can also be said: short connection means that the SOCKET connection is sent and the data is received and then disconnected immediately.

Long connection

Connect->Transfer data->Keep connected->Transfer data->. . . ->Close the connection.

Long connection refers to maintaining the connection regardless of whether it is used or not after establishing a SOCKET connection, but the security is poor.

Http long connection

HTTP can also establish a long connection, use Connection:keep-alive, HTTP 1.1 defaults to a persistent connection. Comparing HTTP1.1 with HTTP1.0, the biggest difference is the addition of persistent connection support (it seems that the latest http1.0 can explicitly specify keep-alive), but it is still stateless, or cannot be trusted. .

When to use long connection and short connection?

Long connections are mostly used for frequent operations, point-to-point communication, and the number of connections cannot be too many. Each TCP connection requires a three-step handshake, which takes time. If each operation is connected first and then operated, the processing speed will be reduced a lot. Therefore, it is not disconnected after each operation and the data packet is sent directly during the first processing. It's OK, no need to establish a TCP connection. For example: long connections are used for database connections. Frequent communication with short connections will cause socket errors, and frequent socket creation is also a waste of resources.

HTTP services like WEB websites generally use short links, because long connections will consume certain resources for the server, and thousands of them are frequently used on WEB websites. Even for hundreds of millions of client connections, using short connections will save some resources. If long connections are used and there are thousands of users at the same time, it is conceivable that if each user occupies one connection. Therefore, the amount of concurrency is large, but each user needs to use a short connection if they do not need frequent operations.

workermanWhat is it? Workerman is an open source, high-performance PHP socket server framework developed purely in PHP. It is widely used in the development of mobile apps, mobile communications, WeChat applets, mobile game servers, online games, PHP chat rooms, hardware communications, smart homes, Internet of Vehicles, Internet of Things and other fields. Supports TCP long connections, supports Websocket, HTTP and other protocols, and supports custom protocols. It has many high-performance components such as asynchronous Mysql, asynchronous Redis, asynchronous Http, asynchronous message queue, etc.

Let’s get to the point: In order to achieve real-time communication, we often use the ajax polling mechanism, as shown in the figure:

Workerman-based real-time push (abandoning ajax polling)

The workerman method can be used later. Implementation, the project is also written by TP. The official manual says that

is recommended to be combined with other mvc frameworks as shown in the picture above (ThinkPHP as an example):

1. ThinkPHP and Workerman are two independent The system is deployed independently (can be deployed on different servers) without interfering with each other.

2. ThinkPHP uses the HTTP protocol to provide web pages for rendering and display in the browser.

3. The js of the page provided by ThinkPHP initiates a websocket connection and connects to the workerman

4. After the connection, a data packet (including username, password or some kind of token string) is sent to the workerman for verification. Which user the websocket connection belongs to.

5. Only when ThinkPHP needs to push data to the browser, it calls the workerman's socket interface to push data.

6. The remaining requests are still processed according to the original HTTP method of ThinkPHP.

Summary:

Use Workerman as a channel that can be pushed to the browser, and only call the Workerman interface to complete the push when data needs to be pushed to the browser. Business logic is all completed in ThinkPHP.

ok, here, run the workerman container. Note that it is running in CLI mode.

Workerman-based real-time push (abandoning ajax polling)

Then we will play like this in the receiving information of our project. Attached Code

<script>
    // 连接服务端
    var socket = io(&#39;http://127.0.0.1:2120&#39;);
    // uid可以是自己网站的用户id,以便针对uid推送
    uid = 123;
    // socket连接后以uid登录
    socket.on(&#39;connect&#39;, function(){
    socket.emit(&#39;login&#39;, uid);
    });
    // 后端推送来消息时
    socket.on(&#39;new_msg&#39;, function(msg){
        console.log("收到消息:"+msg);  //自己业务逻辑处理
    });
    
</script>

Next, we add

// 指明给谁推送,为空表示向所有在线用户推送
        $to_uid = "123";
        // 推送的url地址
        $push_api_url = "http://127.0.0.1:2121/";
        $post_data = array(
           "type" => "publish",
           "content" => "数据",
           "to" => $to_uid, 
        );
        $ch = curl_init ();
        curl_setopt ( $ch, CURLOPT_URL, $push_api_url );
        curl_setopt ( $ch, CURLOPT_POST, 1 );
        curl_setopt ( $ch, CURLOPT_HEADER, 0 );
        curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_data );
        curl_setopt ($ch, CURLOPT_HTTPHEADER, array("Expect:"));
        $return = curl_exec ( $ch );
        curl_close ( $ch );
        var_export($return);

when the user sends information to the user. Among them, the push core code in workererman implements

// 全局数组保存uid在线数据
$uidConnectionMap = array();
// 记录最后一次广播的在线用户数
$last_online_count = 0;
 
 
// PHPSocketIO服务
$sender_io = new SocketIO(2120);
// 客户端发起连接事件时,设置连接socket的各种事件回调
 
// 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据
$sender_io->on(&#39;workerStart&#39;, function(){
    // 监听一个http端口
    $inner_http_worker = new Worker(&#39;http://0.0.0.0:2121&#39;);
    // 当http客户端发来数据时触发
    $inner_http_worker->onMessage = function($http_connection, $data){
        global $uidConnectionMap;
        $_POST = $_POST ? $_POST : $_GET;
        // 推送数据的url格式 type=publish&to=uid&content=xxxx
        switch(@$_POST[&#39;type&#39;]){
            case &#39;publish&#39;:
                global $sender_io;
                $to = @$_POST[&#39;to&#39;];
                $_POST[&#39;content&#39;] = htmlspecialchars(@$_POST[&#39;content&#39;]);
                // 有指定uid则向uid所在socket组发送数据
                if($to){
                    $sender_io->to($to)->emit(&#39;new_msg&#39;, $_POST[&#39;content&#39;]);
                // 否则向所有uid推送数据
                }else{
                    $sender_io->emit(&#39;new_msg&#39;, @$_POST[&#39;content&#39;]);
                }
                // http接口返回,如果用户离线socket返回fail
                if($to && !isset($uidConnectionMap[$to])){
                    return $http_connection->send(&#39;offline&#39;);
                }else{
                    return $http_connection->send(&#39;ok&#39;);
                }
        }
        return $http_connection->send(&#39;fail&#39;);
    };
    
});
 
if(!defined(&#39;GLOBAL_START&#39;))
{
    Worker::runAll();
}

ok, and you’re done!

The above is the detailed content of Workerman-based real-time push (abandoning ajax polling). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete