実行方法: まずserver.phpとindex.htmlのipを変更します コマンドラインで[phpパス]php.exe "[ファイルパス]server.php"を実行します 次にブラウザでindex.htmlを開きます
- include 'websocket.class.php';
- $config=array(
- 'address'=>'192.168.0.200',
- 'port'=>'8000',
- ' event'=>'WSevent',//コールバック関数の関数名
- 'log'=>true,
- );
- $websocket = new websocket($config);
- $websocket->run() ;
- function WSevent($type,$event){
- global $websocket;
- if('in'==$type){
- $websocket->log('顧客エントリ ID:'.$event['k' ]) ;
- }elseif('out'==$type){
- $websocket->log('顧客終了 ID:'.$event['k']);
- }elseif('msg'==$ type) {
- $websocket->log($event['k'].'Message:'.$event['msg']);
- robot($event['sign'],$event['msg' ]) ;
- }
- }
-
- function robot($sign,$t){
- global $websocket;
- switch ($t)
- {
- case 'hello':
- $show='hello,GIt @ OSC';
- ブレーク ;
- ケース '名前':
- $show='ロボット';
- ブレーク;
- ケース '時間':
- $show='現在時刻:'.date('Y-m-d H:i:s');
- ブレーク;
- case 'Goodbye':
- $show='( ^_^ )/~~Bye';
- $websocket->write($sign,'Robot:'.$show);
- $websocket->close ($ 記号);
- return;
- Break;
- case '天の王が虎を覆う':
- $array = array('鶏肉のキノコ煮', 'パゴダは川の悪魔を揺るがす', 'すべてが大変です' );
- $show = $array[rand(0,2)];
- Break;
- default:
- $show='( ⊙o⊙?) 理解できない場合は、「こんにちは、名前、」と言ってみてください。時間よ、さようなら、天の王が大地と虎を覆う。コード
-
-
-
-
-
websocket_TEST
-
- <入力タイプ="text" id="text">
- <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>
-
-
- コードをコピー
-
- /*
- Create class websocket($config);
- $config Structure:
- $config=array(
- 'address'=>'192.168.0.200',//バインドアドレス
- ' port'=>'8000',//バインドポート
- 'event'=>'WSevent',//コールバック関数の関数名
- 'log'=>true,//コマンドラインはレコードを表示します
- ) ;
-
- コールバック関数の戻りデータ形式
- function WSevent($type,$event)
-
- $type string イベントタイプには次の 3 つのタイプがあります
- in クライアントが入る
- out クライアントが切断する
- msg クライアントメッセージが到着する
- すべて小文字です
-
- $event 配列
- $event['k'] 組み込みユーザー リストのユーザー ID;
- $event['sign'] メッセージ $type='msg' の場合のみ顧客マーク
- $event['msg']受信しました この情報があります
-
- メソッド:
- run() run
- search(label) traverse してラベルの ID を取得
- close(label) 切断
- write(label, information) 情報のプッシュ
- idwrite(id, information) Push情報
-
- 属性:
- $users顧客リスト
- 構造:
- $users=array(
- [ユーザーID]=>array('socket'=>[マーク],'hand'=[握手をするかどうか - Boolean value]),
- [userid]=>arr....
- )
- */
-
- class websocket{
- public $log;
- public $event;
- public $signets;
- public $users; ;
- public function __construct($config){
- if (substr(php_sapi_name(), 0, 3) !== 'cli') {
- die("コマンドラインモードで実行してください!");
- }
- error_reporting( E_ALL) ;
- set_time_limit(0);
- ob_implicit_flush();
- $this->event = $config['event'];
- $this->log = $config['log'];
- $this- > master=$this->WebSocket($config['address'], $config['port']);
- $this->sockets=array('s'=>$this->master );
- }
- 関数 WebSocket($address,$port){
- $server =ソケット_create(AF_INET, SOCK_STREAM, SOL_TCP);
- ソケットセットオプション($server, SOL_SOCKET, SO_REUSEADDR, 1);
- ソケットバインド($server, $address, $port );
- socket_listen($server);
- $this->log('リッスン開始: '.$address.' : '.$port);
- return $server;
- }
- function run(){
- while( true){
- $changes=$this->sockets;
- @socket_select($changes,$write=NULL,$excel=NULL,NULL);
- foreach($changes as $sign){
- if($ Sign= =$this->master){
- $client=socket_accept($this->master);
- $this->sockets[]=$client;
- $user = array(
- 'socket'=> ;$ client,
- 'hand'=>false,
- );
- $this->users[] = $user;
- $k=$this->search($client);
- $eventreturn = array( 'k '=>$k,'sign'=>$sign);
- $this->eventoutput('in',$eventreturn);
- }else{
- $len=socket_recv($sign,$buffer) ,2048 ,0);
- $k=$this->search($sign);
- $user=$this->users[$k];
- if($len $this-> ;close ($sign);
- $eventreturn = array('k'=>$k,'sign'=>$sign);
- $this->eventoutput('out',$eventreturn);
- 続ける;
- }
- if(!$this->users[$k]['hand']){//ハンドシェイクにはハンドシェイクはありません
- $this->handshake($k,$buffer);
- }else{
- $buffer = $this->uncode($buffer);
- $eventreturn = array('k'=>$k,'sign'=>$sign,'msg'=>$buffer);
- $ this- >eventoutput('msg',$eventreturn);
- }
- }
- }
- }
- }
- function search($sign){//サイントラバーサルで ID を取得
- foreach ($this->users as $k= >$v){
- if($sign==$v['socket'])
- return $k;
- }
- return false;
- }
- function close($sign){// サインによる切断
- $k=array_search($sign, $this->sockets);
- ソケット_close($sign);
- unset($this->sockets[$k]);
- unset($this->users[$ k ]);
- }
- function handshake($k,$buffer){
- $buf = substr($buffer,strpos($buffer,'Sec-WebSocket-Key:')+18);
- $key = trim( substr ($buf,0,strpos($buf,"rn")));
- $new_key =base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
- $new_message = " HTTP/1.1 101 スイッチング プロトコルrn";
- $new_message .= "アップグレード: websocketrn";
- $new_message .= "Sec-WebSocket-Version: 13rn";
- $new_message .= "接続: Upgradern";
- $new_message 。 = "Sec-WebSocket-Accept: " . $new_key . "rnrn";
- ソケット_ライト($this->users[$k]['socket'],$new_message,strlen($new_message));
- $this- > ;users[$k]['hand']=true;
- return true;
- }
- 関数 uncode($str){
- $mask = array();
- $data = '';
- $msg = unpack('H*',$str);
- $head = substr($msg[1],0,2);
- if (hexdec($head小贝) === 8) {
- $data = false;
- }else if (hexdec($head小贝) === 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));
- $s = 12;
- $e = strlen($msg[1])-2;
- $n = 0;
- for ($i=$s; $i $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i) ,2)));
- $n++;
- }
- }
- return $data;
- }
- 関数コード($msg){
- $msg = preg_replace(array('/r$/','/n$/','/rn$/',), '', $msg);
- $frame = array();
- $frame[0] = '81';
- $len = strlen($msg);
- $frame[1] = $len $frame[2] = $this->ord_hex($msg);
- $data = implode('',$frame);
- return Pack("H*", $data);
- }
- function ord_hex($data) {
- $msg = '';
- $l = strlen($data);
- for ($i= 0; $i $msg .= dechex(ord($data{$i}));
- }
- $msg を返します。
- }
-
- function idwrite($id,$t){//通过id推送信メッセージ
- if(!$this->users[$id]['socket']){return false;}//没有这个标示
- $t=$this->code($t);
- returnソケット_write($this->users[$id]['socket'],$t,strlen($t));
- }
- 関数書き込み($k,$t){//通标表示推送信メッセージ
- $t=$this->code($t);
- returnソケット_write($k,$t,strlen($t));
- }
- function eventoutput($type,$event){// イベント回调
- call_user_func($this->event,$type,$event);
- }
- function log($t){// 制御台输出
- if($this ->log){
- $t=$t."rn";
- fwrite(STDOUT, iconv('utf-8','gbk//IGNORE',$t));
- }
- }
- }
复制代
|