Have you ever used workerman to push real-time messages?

Posted by shya on Thu, 30 Dec 2021 05:33:54 +0100

The article comes from WeChat official account: PHP self study center


Before learning real-time message push, understand the following concepts, which you must understand.

TCP/IP
TCP/IP is a protocol group, which can be 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:
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. The browser and server establish a connection every time they perform an HTTP operation, but the connection is interrupted at the end of the task.
It can also be said that a short connection means that the SOCKET is disconnected immediately after sending and receiving data.

Long connection
Connect - > transmit data - > keep connected - > transmit 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. Connection: keep alive is used. HTTP 1.1 makes a persistent connection by default. HTTP1.1 and http1 0, the biggest difference is that it adds persistent connection support (it seems that the latest HTTP 1.0 can display the specified keep alive), but it is still stateless or untrustworthy.

When to use long connection and short connection?
Long connections are mostly used for frequent operation and 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 greatly reduced. Therefore, it will continue to open after each operation. It is OK to send data packets directly during the next processing. There is no need to establish a TCP connection. For example, the database connection uses a long connection. If a short connection is used, frequent communication will cause socket errors, and frequent socket creation is also a waste of resources.

For example, http services on WEB sites generally use short links, because long connections will consume certain resources for the server, while short connections for thousands or even hundreds of millions of clients as frequently as WEB sites will save some resources. If long connections are used, and there are thousands of users at the same time, if each user occupies a connection, You can imagine. Therefore, there is a large amount of concurrency, but each user needs short connection without frequent operation.

What is workman?
Workerman is an open source high-performance PHP socket server framework developed in pure PHP. It is widely used in the development of mobile app, mobile communication, wechat applet, mobile game server, online game, PHP chat room, hardware communication, smart home, Internet of vehicles, Internet of things and other fields. Support TCP long connection, Websocket, HTTP and other protocols, and user-defined protocols. It has many high-performance components such as asynchronous Mysql, asynchronous Redis, asynchronous HTTP and asynchronous message queue.


Start to get to the point: in order to achieve real-time communication, we often use ajax polling mechanism, which can be implemented by worker man later Take ThinkPHP and workerman as examples):
1. ThinkPHP and Workerman are two independent systems, which are deployed independently (can be deployed on different servers) and do not interfere with each other.
2. ThinkPHP provides Web page rendering and display in the browser with HTTP protocol.
3. The js of the page provided by ThinkPHP initiates a websocket connection to connect to the worker man
4. After connecting, send a data packet (including user name, password or some token string) to workman to verify which user the websocket connection belongs to.
5. Only when ThinkPHP needs to push data to the browser, it calls the socket interface of workerman to push data.
6. The rest of the requests are called and processed according to the original HTTP mode of ThinkPHP.

Summary:
Take Workerman as a channel that can push to the browser, and call the Workerman interface to complete the push only when you need to push data to the browser. The business logic is all done in ThinkPHP.
ok, here, run the worker man container. Note that this is the CLI mode


Then we write this in the project receiving information and attach the code

<script>

    // Connect server
    var socket = io('http://127.0.0.1:2120');

    // Uid can be the user id of your own website to push for uid
    uid = 123;

    // Log in with uid after socket connection
    socket.on('connect', function(){
        socket.emit('login', uid);
    });

    // When the backend pushes a message
    socket.on('new_msg', function(msg){
        console.log("Message received:"+msg);  //Own business logic processing
    });

</script>

Then, when the user sends information to the user, we add

// Indicates to whom to push. If it is blank, it means to push to all online users
$to_uid = "123";

// Push url address
$push_api_url = "http://127.0.0.1:2121/";

$post_data = array(
   "type" => "publish",
   "content" => "data",
   "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);

Among them, the push core code in workerman is implemented

// Global array to save uid online data
$uidConnectionMap = array();

// Record the number of online users of the last broadcast
$last_online_count = 0;

// PHPSocketIO service
$sender_io = new SocketIO(2120);

// When the client initiates a connection event, it sets various event callbacks to connect to the socket
// When $sender_ After IO starts, it listens to an http port through which it can push data to any uid or all UIDs
$sender_io->on('workerStart', function(){

    // Listen to an http port
    $inner_http_worker = new Worker('http://0.0.0.0:2121');

    // Triggered when the http client sends data
    $inner_http_worker->onMessage = function($http_connection, $data){
        global $uidConnectionMap;
        $_POST = $_POST ? $_POST : $_GET;

        // url format of push data type = publish & to = uid & content = XXXX
        switch(@$_POST['type']){

            case 'publish':

                global $sender_io;
                $to = @$_POST['to'];
                $_POST['content'] = htmlspecialchars(@$_POST['content']);

                // If there is a specified uid, send data to the socket group where the uid is located
                if($to){
                    $sender_io->to($to)->emit('new_msg', $_POST['content']);

                // Otherwise, push data to all UIDs
                }else{
                    $sender_io->emit('new_msg', @$_POST['content']);

                }

                // The http interface returns. If the user is offline, the socket returns fail
                if($to && !isset($uidConnectionMap[$to])){
                    return $http_connection->send('offline');

                }else{
                    return $http_connection->send('ok');

                }
        }
        return $http_connection->send('fail');

    };

});


if(!defined('GLOBAL_START'))
{
    Worker::runAll();
}

The above core code has been provided. You can try to practice it. If you want to learn about workerman comprehensively, I suggest you check the documentation of workerman and combine it with this course[ TP5 and workerman actual combat online customer service video ], you can practice!

Topics: PHP Workerman