PHP based on WebSocket to build a simple chat room practice _php Example

Source: Internet
Author: User
Tags configuration php php server set socket unpack
The example in this paper describes PHP based on WebSocket to build a simple chat room practice. Share to everyone for your reference. Specific as follows:
1. Preface

Company game inside there is a simple chat room, understand the later only know is Node+websocket do, think of PHP also to do a simple chat room. So gather all kinds of information to look at the document, find the instance oneself also wrote a simple chat room.

HTTP connections are divided into short connections and long connections. Short connections can generally be implemented with Ajax, and long connections are websocket. Short connections are relatively simple to implement, but they are too resource-intensive. WebSocket efficient but compatible there are points of issue. WebSocket is a HTML5 resource.

2. Front-end

Front-end implementation WebSocket is simple and straightforward

Connect Websocketvar ws = new WebSocket ("ws://127.0.0.1:8000");//When the WEBSOC is successfully connected Ws.onopen = function () {}// Successfully get the server output message Ws.onmessage = function (e) {}//connection error ws.onerror = function () {}//send data to the server Ws.send ();

3. Backstage

The difficulty of websocket mainly in the backstage

3.1websocket Connection Process
WebSocket Communication Diagram This is a simple communication diagram between the client and the server, and the main thing PHP does is to accept the encryption key and return the creation and handshake operation of the socket.

is a detailed flowchart of the service-side processing WebSocket

3.2 Code Practices

The process that the service side does is basically:

    1. Suspends a socket socket process waiting for a connection
    2. Traverse the socket array after having a socket connection
    3. Handshake operation without handshake, receive data parsing and write buffer to output if handshake is already in progress

Here's the sample code (I'm writing a class so the code is segmented according to the function), and the base gives the GitHub address and some of the pits that you encounter
1, the first is to create sockets

Establish socket public    function Createsocket ($address, $port)    {      //Create a socket      $socket = socket_create (Af_inet, Sock_stream, sol_tcp);      Set socket options      socket_set_option ($socket, Sol_socket, SO_REUSEADDR, 1);      Bind IP address and port      socket_bind ($socket, $address, $port);      Listener Socket      Socket_listen ($socket);      return $socket;    }

2. Putting sockets into arrays

Public function __construct ($address, $port)    {      //build socket      $this->soc= $this->createsocket ($ Address, $port);      $this->socs=array ($this->soc);    }

3, suspended process traversal socket Word group, the main operation is done in this area

Public Function Run () {//Suspend process while (true) {$arr = $this->socs;        $write = $except =null;        Receive socket numbers to listen to their status Socket_select ($arr, $write, $except, NULL);            Traverse Socket string foreach ($arr as $k + $v) {//If it is a newly established socket, return a valid socket resource if ($this->soc = = $v) {            $client =socket_accept ($this-&GT;SOC);            if ($client <0) {echo "socket_accept () failed";              }else{//Array_push ($this->socs, $client);              Unset ($this []);            Put a valid socket resource into the socket string $this->socs[]= $client;            }else{//The number of bytes received from the socket is returned from the connected socket $byte =socket_recv ($v, $buff, 20480, 0);            If the received byte is 0 if ($byte <7) continue; The handshake is determined if there is no handshake, if the handshake is handled if (! $this->hand[(int) $client]) {//handshake operation $this            Hands ($client, $buff, $v);    }else{//Handling Data operations          $mess = $this->decodedata ($buff);            Send data $this->send ($mess, $v); }          }        }      }    }

4, the handshake process is to receive WebSocket content from the Sec-websocket-key: to get Key and write to the buffer through the encryption algorithm client will be authenticated (automatic validation does not require us to process)

Public function Hands ($client, $buff, $v)    {      //extract WebSocket key and encrypt it (this is a fixed handshake mechanism to get sec-websocket-key: Key inside)      $buf = substr ($buff, Strpos ($buff, ' Sec-websocket-key: ') +18);      Remove newline space character      $key = Trim (substr ($buf, 0,strpos ($buf, "\ r \ n")));       Fixed cryptographic algorithms      $new _key = Base64_encode (SHA1 ($key. " 258eafa5-e914-47da-95ca-c5ab0dc85b11 ", true));      $new _message = "http/1.1 101 switching protocols\r\n";      $new _message. = "upgrade:websocket\r\n";      $new _message. = "sec-websocket-version:13\r\n";      $new _message. = "connection:upgrade\r\n";      $new _message. = "Sec-websocket-accept:". $new _key. "\r\n\r\n";      Writes the socket to the buffer      socket_write ($v, $new _message,strlen ($new _message));      Socket_write (socket, $upgrade. chr (0), strlen ($upgrade. chr (0)));      Mark this socket handshake successfully      $this->hand[(int) $client]=true;    }

5. Parse the client's data (I'm not encrypting it, and I can encrypt it myself if necessary)

//parse data public function Decodedata ($buff) {//$buff parse data frame $mask = Arra       Y ();       $data = "; $msg = Unpack (' h* ', $buff);       Decodes the data from the binary using the unpack function $head = substr ($msg [1],0,2);       if (Hexdec ($head {1}) = = = 8) {$data = false;         }else if (Hexdec ($head {1}) = = = 1) {$mask [] = Hexdec (substr ($msg [1],4,2));         $mask [] = Hexdec (substr ($msg [1],6,2));         $mask [] = Hexdec (substr ($msg [1],8,2));           $mask [] = Hexdec (substr ($msg [1],10,2));         The problem encountered when just connected to send data display state connecting $s = 12;         $e = strlen ($msg [1])-2;         $n = 0;           for ($i = $s; $i <= $e; $i + = 2) {$data. = Chr ($mask [$n%4]^hexdec (substr ($msg [1], $i, 2)));         $n + +;          }//Send data to client//If the length is greater than 125 block the data $block =str_split ($data, 125);        $mess =array (' mess ' = $block [0],);                return $mess; }

6. Write socket to buffer

Send data public    function Send ($mess, $v)    {      //Traverse Socket Word Group successful handshake for bulk data      foreach ($this->socs as $keys = $ Values) {        //using the system-assigned socket resource ID as the user nickname          $mess [' name ']= ' tourist ' socket:{$v} ";          $str =json_encode ($mess);          $writes = "\x81". Chr (strlen ($STR)). $str;          Ob_flush ();          Flush ();          Sleep (3);          if ($this->hand[(int) $values])            socket_write ($values, $writes, strlen ($writes));        }    }

7. Operation Method

GitHub Address Git@github.com:rsalive/websocket.git

① better run server.php in the console

Go to the server.php script directory (you can php-v see if there is no configuration PHP if there is no Linux configuration under the bash Windows configuration under Path)

Php-f server.php

If there are errors, you will be prompted

② Accessing HTML files from the server

8, step over the pit, open debugging work convenient to view errors

①server.php can print output in a suspended process, and if there is a problem, you can add print to the code to debug

Can be labeled in each judgment. Check the console to see which interval the code is running on.

However, you will need to rerun the script after each modification of the code PHP server.php

② If this error occurs, it may be

1, when the initial socket with the server to send data (the first time with the server to verify the handshake can not send content)

2, if it has been verified, but the client did not send or send a message is empty will also appear this situation

So to verify the data of a connected socket

③ may not be supported by the browser or the server does not open the socket before starting the best authentication

if (window. WebSocket) {  console.log ("This browser supports websocket!"),} else {  console.log ("This browser does WebSocket. ");

The above is the whole content of this article, I hope that everyone's learning has helped, but also hope that we support the script home.

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.