Create a websocket service using PHP

Source: Internet
Author: User
Execution method:
First modify the IP of server.php and index.html
Execute [PHP path]\php.exe] [file path]\server.php] from the command line
Then open index.html through the browser
  1. Include ' websocket.class.php ';
  2. $config =array (
  3. ' Address ' = ' 192.168.0.200 ',
  4. ' Port ' = ' 8000 ',
  5. ' Event ' = ' wsevent ',//function name of the callback function
  6. ' Log ' =>true,
  7. );
  8. $websocket = new WebSocket ($config);
  9. $websocket->run ();
  10. function Wsevent ($type, $event) {
  11. Global $websocket;
  12. if (' in ' = = $type) {
  13. $websocket->log (' Customer Entry ID: ' $event [' K ']);
  14. }elseif (' out ' = = $type) {
  15. $websocket->log (' Customer exit ID: ' $event [' K ']);
  16. }elseif (' msg ' = = $type) {
  17. $websocket->log ($event [' K ']. ' Message: '. $event [' msg ']);
  18. Roboot ($event [' sign '], $event [' msg '];
  19. }
  20. }
  21. function Roboot ($sign, $t) {
  22. Global $websocket;
  23. Switch ($t)
  24. {
  25. Case ' Hello ':
  26. $show = ' hello,git @ OSC ';
  27. Break
  28. Case ' name ':
  29. $show = ' Robot ';
  30. Break
  31. Case ' time ':
  32. $show = ' Current time: '. Date (' y-m-d h:i:s ');
  33. Break
  34. Case ' goodbye ':
  35. $show = ' (^_^)/~~ goodbye ';
  36. $websocket->write ($sign, ' Robot: '. $show);
  37. $websocket->close ($sign);
  38. Return
  39. Break
  40. Case ' King of the Land Tiger ':
  41. $array = Array (' Chicken stew mushroom ', ' Pagoda Quake River Demon ', ' grain is hard ');
  42. $show = $array [rand (0,2)];
  43. Break
  44. Default
  45. $show = ' (⊙o⊙?) Do not understand, you can try to say: Hello,name,time, Goodbye, the king of the Land Tiger.
  46. }
  47. $websocket->write ($sign, ' Robot: '. $show);
  48. }
  49. ?>
Copy Code
    1. Websocket_test
    2. <li>=======websocket======<li>
Copy Code
  1. /*
  2. Create Class WebSocket ($config);
  3. $config structure:
  4. $config =array (
  5. ' Address ' = ' 192.168.0.200 ',//Bind addresses
  6. ' Port ' = ' 8000 ',//Bind port
  7. ' Event ' = ' wsevent ',//function name of the callback function
  8. ' Log ' =>true,//command line display record
  9. );
  10. callback function returns data format
  11. function Wsevent ($type, $event)
  12. There are three types of string events $type:
  13. In Client Access
  14. Out Client Disconnects
  15. MSG Client message arrives
  16. are lowercase
  17. $event Array
  18. $event [' K '] userid with built-in user list;
  19. $event [' sign '] customer logo
  20. $event the message received by [' msg '] $type = ' msg '
  21. Method:
  22. Run ()
  23. Search (Mark) traversal to get the ID of the indicator
  24. Close (Mark) Disconnect
  25. Write (flag, message) push information
  26. Idwrite (ID, info) push information
  27. Property:
  28. $users Customer List
  29. Structure:
  30. $users =array (
  31. [User Id]=>array (' socket ' =>[indicator], ' hand ' =[if handshake-boolean value]),
  32. [User Id]=>arr .....
  33. )
  34. */
  35. Class websocket{
  36. Public $log;
  37. Public $event;
  38. Public $signets;
  39. Public $users;
  40. Public $master;
  41. Public function __construct ($config) {
  42. if (substr (Php_sapi_name (), 0, 3)!== ' CLI ') {
  43. Die ("Run through command-line mode!");
  44. }
  45. Error_reporting (E_all);
  46. Set_time_limit (0);
  47. Ob_implicit_flush ();
  48. $this->event = $config [' event '];
  49. $this->log = $config [' Log '];
  50. $this->master= $this->websocket ($config [' address '], $config [' Port '];
  51. $this->sockets=array (' s ' = = $this->master);
  52. }
  53. function WebSocket ($address, $port) {
  54. $server = Socket_create (Af_inet, Sock_stream, sol_tcp);
  55. Socket_set_option ($server, Sol_socket, SO_REUSEADDR, 1);
  56. Socket_bind ($server, $address, $port);
  57. Socket_listen ($server);
  58. $this->log (' Start listening: ' $address. ': '. $port);
  59. return $server;
  60. }
  61. function Run () {
  62. while (true) {
  63. $changes = $this->sockets;
  64. @socket_select ($changes, $write =null, $except =null,null);
  65. foreach ($changes as $sign) {
  66. if ($sign = = $this->master) {
  67. $client =socket_accept ($this->master);
  68. $this->sockets[]= $client;
  69. $user = Array (
  70. ' Socket ' = $client,
  71. ' Hand ' =>false,
  72. );
  73. $this->users[] = $user;
  74. $k = $this->search ($client);
  75. $eventreturn = Array (' k ' = = $k, ' sign ' = = $sign);
  76. $this->eventoutput (' in ', $eventreturn);
  77. }else{
  78. $len =socket_recv ($sign, $buffer, 2048,0);
  79. $k = $this->search ($sign);
  80. $user = $this->users[$k];
  81. if ($len <7) {
  82. $this->close ($sign);
  83. $eventreturn = Array (' k ' = = $k, ' sign ' = = $sign);
  84. $this->eventoutput (' Out ', $eventreturn);
  85. Continue
  86. }
  87. if (! $this->users[$k [' hand ']) {//No Handshake for handshake
  88. $this->handshake ($k, $buffer);
  89. }else{
  90. $buffer = $this->uncode ($buffer);
  91. $eventreturn = Array (' k ' = = $k, ' sign ' = = $sign, ' msg ' = $buffer);
  92. $this->eventoutput (' msg ', $eventreturn);
  93. }
  94. }
  95. }
  96. }
  97. }
  98. function Search ($sign) {//Pass ID traversal
  99. foreach ($this->users as $k = + $v) {
  100. if ($sign = = $v [' socket ']
  101. return $k;
  102. }
  103. return false;
  104. }
  105. function Close ($sign) {//Disconnect by marking
  106. $k =array_search ($sign, $this->sockets);
  107. Socket_close ($sign);
  108. unset ($this->sockets[$k]);
  109. unset ($this->users[$k]);
  110. }
  111. function handshake ($k, $buffer) {
  112. $buf = substr ($buffer, Strpos ($buffer, ' Sec-websocket-key: ') +18);
  113. $key = Trim (substr ($buf, 0,strpos ($buf, "\ r \ n")));
  114. $new _key = Base64_encode (SHA1 ($key. ") 258eafa5-e914-47da-95ca-c5ab0dc85b11 ", true));
  115. $new _message = "http/1.1 101 switching protocols\r\n";
  116. $new _message. = "upgrade:websocket\r\n";
  117. $new _message. = "sec-websocket-version:13\r\n";
  118. $new _message. = "connection:upgrade\r\n";
  119. $new _message. = "Sec-websocket-accept:". $new _key. "\r\n\r\n";
  120. Socket_write ($this->users[$k [' socket '], $new _message,strlen ($new _message));
  121. $this->users[$k] [' Hand ']=true;
  122. return true;
  123. }
  124. function Uncode ($STR) {
  125. $mask = Array ();
  126. $data = ";
  127. $msg = Unpack (' h* ', $str);
  128. $head = substr ($msg [1],0,2);
  129. if (Hexdec ($head beckham) = = = 8) {
  130. $data = false;
  131. }else if (Hexdec ($head beckham) = = = 1) {
  132. $mask [] = Hexdec (substr ($msg [1],4,2));
  133. $mask [] = Hexdec (substr ($msg [1],6,2));
  134. $mask [] = Hexdec (substr ($msg [1],8,2));
  135. $mask [] = Hexdec (substr ($msg [1],10,2));
  136. $s = 12;
  137. $e = strlen ($msg [1])-2;
  138. $n = 0;
  139. for ($i = $s; $i <= $e; $i + = 2) {
  140. $data. = Chr ($mask [$n%4]^hexdec (substr ($msg [1], $i, 2)));
  141. $n + +;
  142. }
  143. }
  144. return $data;
  145. }
  146. function code ($MSG) {
  147. $msg = preg_replace (Array ('/\r$/', '/\n$/', '/\r\n$/',), ', $msg);
  148. $frame = Array ();
  149. $frame [0] = ' 81 ';
  150. $len = strlen ($msg);
  151. $frame [1] = $len <16? ' 0 '. Dechex ($len):d Echex ($len);
  152. $frame [2] = $this->ord_hex ($msg);
  153. $data = Implode (' ', $frame);
  154. Return Pack ("h*", $data);
  155. }
  156. function Ord_hex ($data) {
  157. $msg = ";
  158. $l = strlen ($data);
  159. for ($i = 0; $i < $l; $i + +) {
  160. $msg. = Dechex (Ord ($data {$i}));
  161. }
  162. return $msg;
  163. }
  164. function Idwrite ($id, $t) {//push information by ID
  165. if (! $this->users[$id [' socket ']) {return false;} No sign of that.
  166. $t = $this->code ($t);
  167. Return Socket_write ($this->users[$id [' socket '], $t, strlen ($t));
  168. }
  169. function Write ($k, $t) {//By marking push information
  170. $t = $this->code ($t);
  171. Return Socket_write ($k, $t, strlen ($t));
  172. }
  173. function Eventoutput ($type, $event) {//Event callback
  174. Call_user_func ($this->event, $type, $event);
  175. }
  176. function log ($t) {//console output
  177. if ($this->log) {
  178. $t = $t. " \ r \ n ";
  179. Fwrite (STDOUT, Iconv (' Utf-8 ', ' Gbk//ignore ', $t));
  180. }
  181. }
  182. }
Copy Code
  • Related Article

    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.