ホームページ  >  記事  >  バックエンド開発  >  PHPを使用してWebSocketサービスを作成する

PHPを使用してWebSocketサービスを作成する

WBOY
WBOYオリジナル
2016-07-25 08:50:471763ブラウズ
実行方法:
まずserver.phpとindex.htmlのipを変更します
コマンドラインで[phpパス]php.exe "[ファイルパス]server.php"を実行します
次にブラウザでindex.htmlを開きます
  1. include 'websocket.class.php';
  2. $config=array(
  3. 'address'=>'192.168.0.200',
  4. 'port'=>'8000',
  5. ' event'=>'WSevent',//コールバック関数の関数名
  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('顧客エントリ ID:'.$event['k' ]) ;
  14. }elseif('out'==$type){
  15. $websocket->log('顧客終了 ID:'.$event['k']);
  16. }elseif('msg'==$ type) {
  17. $websocket->log($event['k'].'Message:'.$event['msg']);
  18. robot($event['sign'],$event['msg' ]) ;
  19. }
  20. }
  21. function robot($sign,$t){
  22. global $websocket;
  23. switch ($t)
  24. {
  25. case 'hello':
  26. $show='hello,GIt @ OSC';
  27. ブレーク ;
  28. ケース '名前':
  29. $show='ロボット';
  30. ブレーク;
  31. ケース '時間':
  32. $show='現在時刻:'.date('Y-m-d H:i:s');
  33. ブレーク;
  34. case 'Goodbye':
  35. $show='( ^_^ )/~~Bye';
  36. $websocket->write($sign,'Robot:'.$show);
  37. $websocket->close ($ 記号);
  38. return;
  39. Break;
  40. case '天の王が虎を覆う':
  41. $array = array('鶏肉のキノコ煮', 'パゴダは川の悪魔を揺るがす', 'すべてが大変です' );
  42. $show = $array[rand(0,2)];
  43. Break;
  44. default:
  45. $show='( ⊙o⊙?) 理解できない場合は、「こんにちは、名前、」と言ってみてください。時間よ、さようなら、天の王が大地と虎を覆う。コード
websocket_TEST
  1. <入力タイプ="text" id="text">
  2. <script></li> <li>function link(){</li> <li> var url='ws: / /192.168.0.200:8000';</li> <li>ソケット=新しいWebSocket(url);</li> <li>socket.onopen=function(){log('接続成功')}</li> <li>socket.onmessage=function(msg){log('メッセージを取得: '+msg.data);console.log(msg);}</li> <li>socket.onclose=function(){log('disconnect')}</li> <li>}</li> <li>function dis(){</li> <li>socket.close();</li> <li>socket=null ;</li> <li>}</li> <li>function log(var1){</li> <li> $('.log').append(var1+"rn");</li> <li>}</li> <li>function send(){</li> <li>ソケット.send($('#text') .attr( 'value'));</li> <li>}</li> <li>function send2(){</li> <li> var json = JSON.stringify({'type':'php','msg':$('#text2').attr('value ')} )</li> <li>socket.send(json);</li> <li>}</li> <li></script>
  3. コードをコピー
    1. /*
    2. Create class websocket($config);
    3. $config Structure:
    4. $config=array(
    5. 'address'=>'192.168.0.200',//バインドアドレス
    6. ' port'=>'8000',//バインドポート
    7. 'event'=>'WSevent',//コールバック関数の関数名
    8. 'log'=>true,//コマンドラインはレコードを表示します
    9. ) ;
    10. コールバック関数の戻りデータ形式
    11. function WSevent($type,$event)
    12. $type string イベントタイプには次の 3 つのタイプがあります
    13. in クライアントが入る
    14. out クライアントが切断する
    15. msg クライアントメッセージが到着する
    16. すべて小文字です
    17. $event 配列
    18. $event['k'] 組み込みユーザー リストのユーザー ID;
    19. $event['sign'] メッセージ $type='msg' の場合のみ顧客マーク
    20. $event['msg']受信しました この情報があります
    21. メソッド:
    22. run() run
    23. search(label) traverse してラベルの ID を取得
    24. close(label) 切断
    25. write(label, information) 情報のプッシュ
    26. idwrite(id, information) Push情報
    27. 属性:
    28. $users顧客リスト
    29. 構造:
    30. $users=array(
    31. [ユーザーID]=>array('socket'=>[マーク],'hand'=[握手をするかどうか - Boolean value]),
    32. [userid]=>arr....
    33. )
    34. */
    35. class websocket{
    36. public $log;
    37. public $event;
    38. public $signets;
    39. public $users; ;
    40. public function __construct($config){
    41. if (substr(php_sapi_name(), 0, 3) !== 'cli') {
    42. die("コマンドラインモードで実行してください!");
    43. }
    44. error_reporting( E_ALL) ;
    45. set_time_limit(0);
    46. ob_implicit_flush();
    47. $this->event = $config['event'];
    48. $this->log = $config['log'];
    49. $this- > master=$this->WebSocket($config['address'], $config['port']);
    50. $this->sockets=array('s'=>$this->master );
    51. }
    52. 関数 WebSocket($address,$port){
    53. $server =ソケット_create(AF_INET, SOCK_STREAM, SOL_TCP);
    54. ソケットセットオプション($server, SOL_SOCKET, SO_REUSEADDR, 1);
    55. ソケットバインド($server, $address, $port );
    56. socket_listen($server);
    57. $this->log('リッスン開始: '.$address.' : '.$port);
    58. return $server;
    59. }
    60. function run(){
    61. while( true){
    62. $changes=$this->sockets;
    63. @socket_select($changes,$write=NULL,$excel=NULL,NULL);
    64. foreach($changes as $sign){
    65. if($ Sign= =$this->master){
    66. $client=socket_accept($this->master);
    67. $this->sockets[]=$client;
    68. $user = array(
    69. 'socket'=> ;$ client,
    70. 'hand'=>false,
    71. );
    72. $this->users[] = $user;
    73. $k=$this->search($client);
    74. $eventreturn = array( 'k '=>$k,'sign'=>$sign);
    75. $this->eventoutput('in',$eventreturn);
    76. }else{
    77. $len=socket_recv($sign,$buffer) ,2048 ,0);
    78. $k=$this->search($sign);
    79. $user=$this->users[$k];
    80. if($len $this-> ;close ($sign);
    81. $eventreturn = array('k'=>$k,'sign'=>$sign);
    82. $this->eventoutput('out',$eventreturn);
    83. 続ける;
    84. }
    85. if(!$this->users[$k]['hand']){//ハンドシェイクにはハンドシェイクはありません
    86. $this->handshake($k,$buffer);
    87. }else{
    88. $buffer = $this->uncode($buffer);
    89. $eventreturn = array('k'=>$k,'sign'=>$sign,'msg'=>$buffer);
    90. $ this- >eventoutput('msg',$eventreturn);
    91. }
    92. }
    93. }
    94. }
    95. }
    96. function search($sign){//サイントラバーサルで ID を取得
    97. foreach ($this->users as $k= >$v){
    98. if($sign==$v['socket'])
    99. return $k;
    100. }
    101. return false;
    102. }
    103. function close($sign){// サインによる切断
    104. $k=array_search($sign, $this->sockets);
    105. ソケット_close($sign);
    106. unset($this->sockets[$k]);
    107. unset($this->users[$ k ]);
    108. }
    109. function handshake($k,$buffer){
    110. $buf = substr($buffer,strpos($buffer,'Sec-WebSocket-Key:')+18);
    111. $key = trim( substr ($buf,0,strpos($buf,"rn")));
    112. $new_key =base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
    113. $new_message = " HTTP/1.1 101 スイッチング プロトコルrn";
    114. $new_message .= "アップグレード: websocketrn";
    115. $new_message .= "Sec-WebSocket-Version: 13rn";
    116. $new_message .= "接続: Upgradern";
    117. $new_message 。 = "Sec-WebSocket-Accept: " . $new_key . "rnrn";
    118. ソケット_ライト($this->users[$k]['socket'],$new_message,strlen($new_message));
    119. $this- > ;users[$k]['hand']=true;
    120. return true;
    121. }
    122. 関数 uncode($str){
    123. $mask = array();
    124. $data = '';
    125. $msg = unpack('H*',$str);
    126. $head = substr($msg[1],0,2);
    127. if (hexdec($head小贝) === 8) {
    128. $data = false;
    129. }else if (hexdec($head小贝) === 1){
    130. $mask[] = hexdec(substr($msg[1],4,2));
    131. $mask[] = hexdec(substr( $msg[1],6,2));
    132. $mask[] = hexdec(substr($msg[1],8,2));
    133. $mask[] = hexdec(substr($msg[1], 10,2));
    134. $s = 12;
    135. $e = strlen($msg[1])-2;
    136. $n = 0;
    137. for ($i=$s; $i $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i) ,2)));
    138. $n++;
    139. }
    140. }
    141. return $data;
    142. }
    143. 関数コード($msg){
    144. $msg = preg_replace(array('/r$/','/n$/','/rn$/',), '', $msg);
    145. $frame = array();
    146. $frame[0] = '81';
    147. $len = strlen($msg);
    148. $frame[1] = $len $frame[2] = $this->ord_hex($msg);
    149. $data = implode('',$frame);
    150. return Pack("H*", $data);
    151. }
    152. function ord_hex($data) {
    153. $msg = '';
    154. $l = strlen($data);
    155. for ($i= 0; $i $msg .= dechex(ord($data{$i}));
    156. }
    157. $msg を返します。
    158. }
    159. function idwrite($id,$t){//通过id推送信メッセージ
    160. if(!$this->users[$id]['socket']){return false;}//没有这个标示
    161. $t=$this->code($t);
    162. returnソケット_write($this->users[$id]['socket'],$t,strlen($t));
    163. }
    164. 関数書き込み($k,$t){//通标表示推送信メッセージ
    165. $t=$this->code($t);
    166. returnソケット_write($k,$t,strlen($t));
    167. }
    168. function eventoutput($type,$event){// イベント回调
    169. call_user_func($this->event,$type,$event);
    170. }
    171. function log($t){// 制御台输出
    172. if($this ->log){
    173. $t=$t."rn";
    174. fwrite(STDOUT, iconv('utf-8','gbk//IGNORE',$t));
    175. }
    176. }
    177. }
    复制代


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。