Home Backend Development PHP Tutorial PHP implements socket push technology

PHP implements socket push technology

Jul 07, 2018 pm 01:44 PM
php implementation

This article mainly introduces the socket push technology implemented in PHP. It has certain reference value. Now I share it with everyone. Friends in need can refer to it.

There were already ajax timing requests before the socket appeared. Long polling and other solutions, but none of them can meet the needs, so socket was born.

Socket basic function socket

Summary of commonly used socket functions

Server side: socket_create creates a socket and sets basic parameters

socket_bind binds ip and port number

socket_listen listens

socket_accept client connection

socket_read reads client data

socket_write sends data to a single client

socket_close Close the connection

Client: socket_create Create socket and set basic parameters

socket_connect Connect socket

socket_write Send data to the server

socket_read Read server data

socket_close closes the connection

H5websocketNo more talk, go to the link

OK, start posting the code~

--------- -------------------------------------------------segmentation Line

Server code:

<?php
class WS {
    var $master;
    var $sockets = array();
    var $debug = false;//true为调试模式,输出log日志
    var $handshake = array();

    function __construct($address, $port){
        $this->master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)     or die("socket_create() failed");
        socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1)  or die("socket_option() failed");
        socket_bind($this->master, $address, $port)                    or die("socket_bind() failed");
        socket_listen($this->master,20)                                or die("socket_listen() failed");
        
        $this->sockets[] = $this->master;
        $this->say("Server Started : ".date(&#39;Y-m-d H:i:s&#39;));
        $this->say("Listening on   : ".$address." port ".$port);
        $this->say("Master socket  : ".$this->master."\n");
        
        while(true){
            $socketArr = $this->sockets;
            $write = NULL;
            $except = NULL;
            socket_select($socketArr, $write, $except, NULL);  //自动选择来消息的socket 如果是握手 自动选择主机
            foreach ($socketArr as $socket){
                if ($socket == $this->master){  //主机
                    $client = socket_accept($this->master);
                    if ($client < 0){
                        $this->log("socket_accept() failed");
                        continue;
                    } else{
                        $this->connect($client);
                    }
                } else {
                    $bytes = @socket_recv($socket,$buffer,2048,0);
                    if ($bytes == 0){
                        $this->disConnect($socket);
                    }
                    else{
                        $key = array_search($socket, $this->sockets);
                        if (empty($this->handshake) || !isset($this->handshake[$key]) || !$this->handshake[$key]){
                            $this->doHandShake($socket, $buffer, $key);
                        }
                        else{
                            $buffer = $this->decode($buffer);
                            echo $buffer.PHP_EOL;
                            $key = array_search($socket, $this->sockets);
                            $arr = $this->sockets;
                            array_shift($arr);
                            foreach ($arr as $s){
                                $this->send($s, $buffer);
                            }
                        }
                    }
                }
            }
        }
    }
    
    function send($client, $msg){
        $msg = $this->frame($msg);
        socket_write($client, $msg, strlen($msg));
    }
    function connect($socket){
        array_push($this->sockets, $socket);
        $this->say("\n" . $socket . " CONNECTED!");
        $this->say(date("Y-n-d H:i:s"));
    }
    function disConnect($socket){
        $index = array_search($socket, $this->sockets);
        socket_close($socket);
        $this->say($socket . " DISCONNECTED!");
        if ($index >= 0){
            echo &#39;unset index is:&#39;.PHP_EOL;
            unset($this->sockets[$index]);
        }
    }
    function doHandShake($socket, $buffer, $handKey){
        $this->log("\nRequesting handshake...");
        $this->log($buffer);
        list($resource, $host, $origin, $key) = $this->getHeaders($buffer);
        $this->log("Handshaking...");
        $upgrade  = "HTTP/1.1 101 Switching Protocol\r\n" .
                    "Upgrade: websocket\r\n" .
                    "Connection: Upgrade\r\n" .
                    "Sec-WebSocket-Accept: " . $this->calcKey($key) . "\r\n\r\n";  //必须以两个回车结尾
        $this->log($upgrade);
        $sent = socket_write($socket, $upgrade, strlen($upgrade));
        $this->handshake[$handKey]=true;
        $this->log("Done handshaking...");
        return true;
    }

    function getHeaders($req){
        $r = $h = $o = $key = null;
        if (preg_match("/GET (.*) HTTP/"              ,$req,$match)) { $r = $match[1]; }
        if (preg_match("/Host: (.*)\r\n/"             ,$req,$match)) { $h = $match[1]; }
        if (preg_match("/Origin: (.*)\r\n/"           ,$req,$match)) { $o = $match[1]; }
        if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$req,$match)) { $key = $match[1]; }
        return array($r, $h, $o, $key);
    }

    function calcKey($key){
        //基于websocket version 13
        $accept = base64_encode(sha1($key . &#39;258EAFA5-E914-47DA-95CA-C5AB0DC85B11&#39;, true));
        return $accept;
    }

    function decode($buffer) {
        $len = $masks = $data = $decoded = null;
        $len = ord($buffer[1]) & 127;

        if ($len === 126) {
            $masks = substr($buffer, 4, 4);
            $data = substr($buffer, 8);
        } 
        else if ($len === 127) {
            $masks = substr($buffer, 10, 4);
            $data = substr($buffer, 14);
        } 
        else {
            $masks = substr($buffer, 2, 4);
            $data = substr($buffer, 6);
        }
        for ($index = 0; $index < strlen($data); $index++) {
            $decoded .= $data[$index] ^ $masks[$index % 4];
        }
        return $decoded;
    }

    function frame($s){
        $a = str_split($s, 125);
        if (count($a) == 1){
            return "\x81" . chr(strlen($a[0])) . $a[0];
        }
        $ns = "";
        foreach ($a as $o){
            $ns .= "\x81" . chr(strlen($o)) . $o;
        }
        return $ns;
    }

    
    function say($msg = ""){
        echo $msg . "\n";
    }
    function log($msg = ""){
        if ($this->debug){
            echo $msg . "\n";
        } 
    }
}
    

new WS(&#39;localhost&#39;, 4000);
Copy after login

Client code (H5):

<html>
    <head>
        <title>demo</title>
        <script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
    </head>
    <body>
    <input type="text" id="content">
    <input type="button" value="send" id="send">
        <script type="text/javascript">                    var ws = new WebSocket("ws://localhost:4000");
            ws.onopen = function(){
                console.log("握手成功");
            }
            ws.onmessage = function(e){
                console.log("message:" + e.data);
            }
            ws.onerror = function(){
                console.log("error");
            }
            $("#send").click(function(){
                content = $("#content").val();
                console.log(content);
                ws.send(content);
            })        </script>
    </body>
</html>
Copy after login

Then execute php demo.php to open the socket (steal a trick from the operation and maintenance, execute nohup php demo.php under Linux & can be executed in the background) , the browser can open multiple index.html, and communication can be established.

Code analysis:

1. The attribute $sockets array saves each accept connection (I don’t know if this description is correct);

2. Attribute The $handshake array saves whether the connection is in the connected state;

The above is the entire content of this article. I hope it will be helpful to everyone's learning. For more related content, please pay attention to the PHP Chinese website!

Related recommendations:

How to use Elasticsearch in PHP

##Batch update of PHP

The above is the detailed content of PHP implements socket push technology. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
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

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to control cache expiration time in PHP? How to control cache expiration time in PHP? Jun 19, 2023 pm 11:23 PM

With the popularity of Internet applications, website response speed has become more and more of a focus for users. In order to quickly respond to user requests, websites often use caching technology to cache data, thereby reducing the number of database queries. However, cache expiration time has an important impact on response speed. This article will discuss methods of controlling cache expiration time to help PHP developers better apply caching technology. 1. What is cache expiration time? Cache expiration time refers to the time when the data in the cache is considered expired. It determines when the data in the cache is needed

How to use PHP to implement file conversion and format conversion functions How to use PHP to implement file conversion and format conversion functions Sep 05, 2023 pm 03:40 PM

How to use PHP to implement file conversion and format conversion functions 1. Introduction In the process of developing web applications, we often need to implement file conversion and format conversion functions. Whether you are converting image files to other formats or converting text files from one encoding to another, these operations are common needs. This article will describe how to implement these functions using PHP, with code examples. 2. File conversion 2.1 Convert image files to other formats In PHP, we can use

User privacy protection of online voting system implemented in PHP User privacy protection of online voting system implemented in PHP Aug 09, 2023 am 10:29 AM

User privacy protection of online voting system implemented in PHP With the development and popularization of the Internet, more and more voting activities have begun to be moved to online platforms. The convenience of online voting systems brings many benefits to users, but it also raises concerns about user privacy leaks. Privacy protection has become an important aspect in the design of online voting systems. This article will introduce how to use PHP to write an online voting system, and focus on the issue of user privacy protection. When designing and developing an online voting system, the following principles need to be followed to ensure

How to use PHP to implement user registration function How to use PHP to implement user registration function Sep 25, 2023 pm 06:13 PM

How to use PHP to implement user registration function In modern network applications, user registration function is a very common requirement. Through the registration function, users can create their own accounts and use corresponding functions. This article will implement the user registration function through the PHP programming language and provide detailed code examples. First, we need to create an HTML form to receive the user's registration information. In the form, we need to include some input fields, such as username, password, email, etc. Form fields can be customized according to actual needs.

Implementation principle of consistent hash algorithm for PHP data cache Implementation principle of consistent hash algorithm for PHP data cache Aug 10, 2023 am 11:10 AM

Implementation Principle of Consistent Hash Algorithm for PHP Data Cache Consistent Hashing algorithm (ConsistentHashing) is an algorithm commonly used for data caching in distributed systems, which can minimize the number of data migrations when the system expands and shrinks. In PHP, implementing consistent hashing algorithms can improve the efficiency and reliability of data caching. This article will introduce the principles of consistent hashing algorithms and provide code examples. The basic principle of consistent hashing algorithm. Traditional hashing algorithm disperses data to different nodes, but when the node

How to use PHP to implement mobile adaptation and responsive design How to use PHP to implement mobile adaptation and responsive design Sep 05, 2023 pm 01:04 PM

How to use PHP to implement mobile adaptation and responsive design Mobile adaptation and responsive design are important practices in modern website development. They can ensure good display effects of the website on different devices. In this article, we will introduce how to use PHP to implement mobile adaptation and responsive design, with code examples. 1. Understand the concepts of mobile adaptation and responsive design Mobile adaptation refers to providing different styles and layouts for different devices based on the different characteristics and sizes of the device. Responsive design refers to the use of

How to implement fingerprint login for WeChat mini program in PHP How to implement fingerprint login for WeChat mini program in PHP May 31, 2023 pm 10:40 PM

With the continuous development of WeChat mini programs, more and more users are beginning to choose WeChat mini programs to log in. In order to improve users’ login experience, WeChat mini programs began to support fingerprint login. In this article, we will introduce how to use PHP to implement fingerprint login for WeChat mini programs. 1. Understand the fingerprint login of WeChat mini programs On the basis of WeChat mini programs, developers can use WeChat's fingerprint recognition function to allow users to log in to WeChat mini programs through fingerprints, thereby improving the security and convenience of the login experience. 2. Preparation work is implemented using PHP

PHP implementation of WeChat applet operation flow chart techniques PHP implementation of WeChat applet operation flow chart techniques May 31, 2023 pm 07:51 PM

With the rapid development of the mobile Internet, WeChat mini programs are becoming more and more popular among users, and PHP, as a powerful programming language, also plays an important role in the development process of mini programs. This article will introduce the techniques of implementing WeChat applet operation flow chart in PHP. Obtain access_token During the development process of using WeChat applet, you first need to obtain access_token, which is an important credential for realizing the operation of WeChat applet. The code to obtain access_token in PHP is as follows: f

See all articles