Php + websocket Simple Chat Room practice, websocket Construction

Source: Internet
Author: User
Tags script php unpack what php

Php + websocket Simple Chat Room practice, websocket Construction

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

For more information about websocket persistent connections, see https://www.zhihu.com/question/20215561.

This article mainly introduces the implementation steps of websocket simple chat rooms. The in-depth introduction of some knowledge points will provide links or help readers collect their own information.

2. Front-end

Front-end websocket implementation is simple and straightforward

// Connect to websocket

Var ws = new WebSocket ("ws: // FIG: 8000 ");

// When the websoc is successfully connected

Ws. onopen = function (){}

// The message output by the server is obtained successfully.

Ws. onmessage = function (e ){}

// When a connection error occurs
Ws. onerror = function (){}

//Send data to the server

Ws. 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. Suspend A socket process to wait for connection

② Traverse socket array after socket connection

③ Perform a handshake without handshaking. If the handshake has been made, the system will receive data parsing and write the data into 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.

Server. phpOutput can be printed in a suspended process. 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.");}

 

If any, please point out

 

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.