Php uses websocket to build a simple chat room and phpwebsocket

Source: Internet
Author: User
Tags script php what php

Php uses websocket to build a simple chat room and phpwebsocket

This example describes how to set up a simple chat room in php Based on websocket. Share it with you for your reference. The details are as follows:
1. Preface

There is a simple chat room in the company's game. After learning about it, I learned that it was implemented by node + websocket. I think php will also be used as a simple chat room. As a result, I collected various materials to read documents and find instances. I also wrote a simple chat room.

Http connections are divided into short connections and long connections. Short connections can be implemented using ajax. Long connections are websocket. Short connections are easy to implement, but consume too much resources. There are some problems with the efficiency but compatibility of websocket. Websocket is an html5 Resource

2. Front-end

Front-end websocket implementation is simple and straightforward

// Connect websocketvar ws = new WebSocket ("ws: // 127.0.0.1: 8000"); // ws when the websoc is successfully connected. onopen = function () {}// the message ws output by the server is obtained successfully. onmessage = function (e) {}// ws when a connection error occurs. onerror = function () {}// send data ws to the server. send ();

3. Background

The difficulties of websocket are mainly in the background

3.1websocket connection process
Websocket communication diagram this is a simple communication diagram between the client and the server. What php does is to accept the Encrypted key and return it to complete socket creation and handshake operations.

Is a detailed flowchart of websocket processing by the server.

3.2 code practices

The process of the server is roughly as follows:

  1. Suspends a socket process waiting for connection
  2. Traverse socket array after socket connection
  3. Handshakes are performed without handshakes. If handshakes are performed, the data is parsed and written to the buffer for output.

The following is the sample code (I wrote a class, so the code is segmented based on the function). The github address and some pitfalls I encountered are provided at the bottom of this article.
1. First, create a socket
 

// Create a socket public function createSocket ($ address, $ port) {// create a socket $ socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP ); // set the socket option socket_set_option ($ socket, SOL_SOCKET, SO_REUSEADDR, 1); // bind the IP address and port socket_bind ($ socket, $ address, $ port ); // listener socket socket_listen ($ socket); return $ socket ;}

2. Put the socket into an array

Public function _ construct ($ address, $ port) {// create a socket $ this-> soc = $ this-> createSocket ($ address, $ port ); $ this-> socs = array ($ this-> soc );}

3. Process suspension traverses the socket array. The main operations are completed here.

Public function run () {// pending process while (true) {$ arr = $ this-> socs; $ write = $ response T = NULL; // receive socket numbers to listen to their status socket_select ($ arr, $ write, $ response T, NULL); // traverse the socket array foreach ($ arr as $ k => $ v) {// if a new socket is created, a valid socket resource is returned. 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 valid socket Resources in the socket array $ this-> socs [] = $ Client ;}} else {// number of bytes received from the socket from the connected socket $ byte = socket_recv ($ v, $ buff, 20480, 0); // if the received byte is 0 if ($ byte <7) continue; // if there is no handshake, the handshake is performed. if the handshake is performed, the request is processed if (! $ This-> hand [(int) $ client]) {// perform the handshake operation $ this-> hands ($ client, $ buff, $ v );} else {// data processing 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 obtain the key and write it to the buffer client through the encryption algorithm for verification (automatic verification does not need to be processed)

Public function hands ($ client, $ buff, $ v) {// extract the key passed by websocket and encrypt it (this is a fixed handshake mechanism to obtain Sec-WebSocket-Key: key) $ buf = substr ($ buff, strpos ($ buff, 'sec-WebSocket-Key: ') + 18 ); // remove the line break space character $ key = trim (substr ($ buf, 0, strpos ($ buf, "\ r \ n "))); // fixed encryption algorithm $ new_key = base64_encode (sha1 ($ key. "258eafa5-e914-4710995ca-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"; // write the socket into the buffer socket_write ($ v, $ new_message, strlen ($ new_message); // socket_write (socket, $ upgrade. chr (0), strlen ($ upgrade. chr (0); // mark the socket handshake success $ this-> hand [(int) $ client] = true ;}

5. parse the client data (I have not encrypted it here. You can also encrypt it as needed)

// Parse data public function decodeData ($ buff) {// $ buff parse data frames $ mask = array (); $ data = ''; $ msg = unpack ('H * ', $ buff); // use the unpack function to decode the data from binary. $ head = substr ($ msg [1 ); 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 status connecting $ s = 12; $ e = strlen ($ msg [1])-2; $ n = 0 is displayed when the connection is established; for ($ I = $ s; $ I <= $ e; $ I + = 2) {$ data. = chr ($ mask [$ n % 4] ^ hexdec (substr ($ msg [1], $ I, 2); $ n ++ ;} // send data to the client // If the length is greater than 125, block the data into blocks $ block = str_split ($ data, 125 ); $ mess = array ('mess '=> $ block [0],); return $ mess ;}

6. Write the socket into the buffer.

// Send data public function send ($ mess, $ v) {// send a group foreach ($ this-> socs as $ keys => $ values) when the socket array is successfully traversed) {// use the socket resource id allocated by the system as your nickname $ mess ['name'] = "Tourist's 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. Running Method

Github address git@github.com: rsaLive/websocket. git

① It is best to run server. php on the console

Go to the server. php script directory (you can first check php-v to see If php is configured. If there is no Linux configuration, go to bash windows to configure path)

Php-f server. php

If there is an error or misunderstanding

② Access html files through the server

8. Open debugging to check errors.

① Output can be printed in the suspended process of server. php. If any problem occurs, you can add printing to the Code for debugging.

You can mark in each judgment to view the code running range on the console

However, you need to re-run the script php server. php after each modification.

② If this error occurs, it may be

1. Send data with the initial socket of the server (content cannot be sent when shaking hands with the server for the first time)

2. If the verification has been completed but the client has not sent or the message sent is empty, this will also happen.

Therefore, we need to check the data of connected sockets.

 

③ It may not be supported by the browser or the server does not enable socket before it starts to verify

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

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

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.