1.socket Server Building Ideas
1) Purpose: Understanding the socket server working mechanism
2) Train of thought: Create socket--connect the socket join pool--processing receive information, handshake action, send information
2.socket Server Code
Note: Copy to php file, direct command line can run, no additional support required
Special note: In order to be able to transfer the Chinese _sendmsg did Json_encode ()
<?php/** * Socket Server * @author Wuchangliang 2018/1/17 */class socketserver{private $sockets;//Connection Pool private $mast Er Private $handshake; /** * @param $address * @param $port */Public Function run ($address, $port) {//config error level, run time, refresh Buffer echo iconv (' UTF-8 ', ' GBK ', "Welcome to PHP Socket Test service. \ n "); error_reporting (0); Set_time_limit (0); Ob_implicit_flush (); Create socket $this->master = $this->_connect ($address, $port); $this->sockets[] = $this->master; Run socket while (true) {$sockets = $this->sockets; $write = NULL; $except = NULL; Socket_select ($sockets, $write, $except, NULL); $write, $except reference foreach ($sockets as $socket) {if ($socket = = $this->master) {$client = socket_accept ($socket); $thishandshake = false; if ($client) {$this->sockets[] = $client;//join Connection Pool} } else {//receive information $bytes = @socket_recv ($socket, $buffer, 2048, 0); if ($bytes <= 6) {$this->_disconnect ($socket); Continue }; Processing information if (! $this->handshake) { $this->_handshake ($socket, $buffer); } else {$buffer = $this->_decode ($buffer); $this->_sendmsg ($buffer, $socket); } } }}}/** * Create socket connection * @param $address * @param $port * @return Resource */ Private Function _connect ($address, $port) {//create socket $master = Socket_create (Af_inet, Sock_stream, sol_tcp) or Die ("Socket_create () Failed:reason:". Socket_strerror (Socket_last_error ()). "\ n"); Socket_bind ($master, $address, $port) or Die ("Socket_bind () Failed:reason:". Socket_strerror (Socket_last_error ($master)). "\ n"); Socket_listen ($master, 5) or Die ("Socket_listen () Failed:reason:". Socket_strerror (Socket_last_error ($master)). "\ n"); return $master; /** * Handshake Action * @param $socket * @param $buffer */Private Function _handshake ($socket, $buffer) {//handshake action Information $buf = substr ($buffer, Strpos ($buffer, ' Sec-websocket-key: ') + 18); $key = Trim (substr ($buf, 0, Strpos ($buf, "\ r \ n"))); $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"; Record handshake Action Socket_write ($socket, $new _message, strlen ($new _message)); $this->handshake = true; /** * Disconnect the socket * @param $socket */Private Function _disconnect ($socket) {$index = Array_ Search ($socket, $this->sockets); Socket_close ($socket); if ($index >= 0) {array_splice ($this->sockets, $index, 1); }}/** * Send message * @param $buffer * @param $client */Private Function _sendmsg ($buffer, $client) {$send _buffer = $this->_frame (Json_encode ($buffer)); foreach ($this->sockets as $socket) { if ($socket! = $this->master && $socket! = $client) {//broadcast send (except yourself) socket_write ($socket, $send _ Buffer, strlen ($send _buffer)); }}}/** * Parse data frame * @param $buffer * @return null|string */Private 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; }/** * handles the return frame * @param $buffer * @return String */Private Function _frame($buffer) {$len = strlen ($buffer); if ($len <=) {return "\x81". Chr ($len). $buffer; } else if ($len <= 65535) {return "\x81". Chr (126). Pack ("n", $len). $buffer; } else {return "\x81". Char (127). Pack ("Xxxxn", $len). $buffer; }}} $SC = new Socketserver (); $sc->run (' 127.0.0.1 ', 2046);
3. Client code
Note: Copy directly to HTML, and the above PHP file in the same folder, pay special attention to onmessage parsing of the two layers of parse
<! DOCTYPE html>
4. Test examples