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

Source: Internet
Author: User
Tags chr configuration php php server php script set socket socket strlen unpack

This article describes the PHP based on WebSocket to build a simple chat room practice. Share to everyone for your reference. Specifically as follows:
1. Preface

There is a simple chat room in the company game, understand after know is node+websocket do, think of PHP also to do a simple chat room. So collect all kinds of information to look at the documents, find examples of their own also wrote a simple chat room.

HTTP connections are divided into short connections and long connections. Short connection can generally be implemented with Ajax, long connection is websocket. Short connections are simple to implement, but they consume resources too much. WebSocket high Efficiency But there is a point of compatibility. WebSocket is a HTML5 resource.

2. Front End

Front-End implementation websocket is simple and straightforward

Connection WebSocket

var ws = new WebSocket ("ws://127.0.0.1:8000");

When the WEBSOC was successfully connected

Ws.onopen = function () {}

//////////////////= function (

e) {}

//Connection Error
ws.onerror = function () {}

//Send data to Server

ws.send ();

3, Backstage

The difficulty of websocket is mainly in the backstage

3.1websocket Connection Process
WebSocket Communication Diagram This is a simple client and server communication diagram, PHP is mainly to accept the encryption key and return to complete the socket in the creation and handshake operation

The following figure is a detailed flowchart of the service-side processing WebSocket

3.2 Code Practice

The service-side process is roughly:

    1. Suspend a socket socket process waiting for connection
    2. Traversing the socket word group after having a socket connection
    3. Handshake without handshake, receive data parsing and write to buffer for output if already shook

Here's the sample code (I'm writing a class so the code is segmented by function), the GitHub address, and some of the pits you've encountered.
1, first is the creation of 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);
      Binding IP address and port
      socket_bind ($socket, $address, $port);
      Listening socket
      Socket_listen ($socket);
      return $socket;
    }

2, put the socket into the array

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

    

3, suspend the process to traverse the socket Word group, the main operation is completed in this area

Public Function Run () {//Suspend process while (true) {$arr = $this->socs;
        $write = $except =null;
        Receive socket numbers to monitor their state socket_select ($arr, $write, $except, NULL);
            Traversal sockets group foreach ($arr as $k => $v) {//If the newly established socket returns a valid socket resource if ($this->soc = = $v) {
            $client =socket_accept ($this->SOC);
            if ($client <0) {echo "socket_accept () failed";
              }else{//Array_push ($this->socs, $client);
              Unset ($this []);
            Put the valid socket resource into the socket Word group $this->socs[]= $client;
            }else{//Receive data from a connected socket returns the number of bytes received from the socket $byte =socket_recv ($v, $buff, 20480, 0);
            If the bytes received are 0 if ($byte <7) continue; To decide whether to shake hands or not to shake hands, if the handshake is handled if (! $this->hand[(int) $client]) {//Handshake $this-&
            Gt;hands ($client, $buff, $v); }else{//Processing data operation $mess = $this->decodedata ($buff);
            Send data $this->send ($mess, $v);
 }
          }
        }
      }
    }

4, the handshake process is to receive WebSocket content from the Sec-websocket-key: Get Key and write through the encryption algorithm to the buffer client will verify (automatic verification does not require us to deal with)

Public function Hands ($client, $buff, $v)
    {
      //extract WebSocket key and encrypt it (this is a fixed handshake mechanism to get sec-websocket-key: Inside Key)
      $buf = substr ($buff, Strpos ($buff, ' Sec-websocket-key: ') +18);
      Remove the newline space character
      $key = Trim (substr ($buf, 0,strpos ($buf, "\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \"));
       Fixed encryption algorithm
      $new _key = Base64_encode (SHA1 ($key.) 258eafa5-e914-47da-95ca-c5ab0dc85b11 ", true));
      $new _message = "http/1.1 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 success
      $this->hand[(int) $client]=true;
    }

5, the resolution of the client data (I do not have encryption here, if necessary, you can encrypt yourself)

//Parse data public function Decodedata ($buff) {//$buff parse data frame $mask = Arra 
      Y (); 
      $data = '; $msg = Unpack (' h* ', $buff); 
      Decoding the data using the unpack function from the binary $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)); 
        When the problem is just connected, send the data to show the 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 Group successful handshake for data mass
      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 on the console server.php

Go to server.php Script directory (you can first php-v see if there is no configuration PHP if no Linux configuration under bash Windows configuration down path)

Php-f server.php

If there are errors you will be prompted

② access to HTML files through the server

8, stepped on the pit, open debugging work to facilitate viewing errors

①server.php can print output in a pending process, and if a problem occurs, you can add printing to the code to debug

It can be labeled in every judgment, in the console to see where the code is running.

However, you 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 (in the first time with the server to verify the handshake can not send content)

2. This can happen if the message that the client has not sent or sent is empty if it has been validated

So to verify the data for a connected socket

③ may not support the browser or the server does not open the socket before the start of the best verification

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

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.