English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

php+Ejemplo de código de ejemplo de sala de chat implementada con webSoket (con código fuente)

Recientemente, al construir una sala de transmisión de imágenes y texto en la empresa, necesité usar chatsever y estudié un poco de html5El websocket implementado en el client.html permitió la comunicación bidireccional, después de varios días de experimentación basada en la experiencia de los demás, logré crear un chatroom que permite enviar imágenes, emoticonos de QQ, chats grupales y privados, y especialmente lo comparto con los principiantes para que lo utilicen como referencia y aprendizaje, los expertos pueden ignorarlo.

前端:client.html

!doctype html
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
<title>HTML5 websocket 网页聊天室 javascript php</title>
<style type="text/css">
body,p{margin:0px; padding:0px; font-tamaño:14px; color:#333; font-family:Arial, Helvetica, sans-serif;}
#ltian,.rin{width:98%; margin:5px auto;}
#ltian{border:1px #ccc solid;overflow-y:auto; overflow-x:hidden; position:relative;}
#ct{margin-derecha:111px; height:100%;overflow-y:auto;overflow-x: hidden;}
#us{width:110px; overflow-y:auto; overflow-x:hidden; float:right; border-izquierda:1px #ccc solid; height:100%; background-color:#F1F1F1;}
#us p{padding:3px 5px; color:#08C; línea-altura:20px; altura:20px; cursor:pointer; desbordar:oculto; blanco-espacio:no_repetir; texto-desbordar:ellipsis;}
#us p:hover,#us p:active,#us p.ck{fondo-color:#069; color:#FFF;}
#us p.my:hover,#us p.my:active,#us p.my{color:#333; fondo-color:transparent;}
botón{flotar:right; ancho:80px; altura:35px; fuente-tamaño:18px;}
input{ancho:100%; altura:30px; relleno:2px; línea-altura:20px; contorno:none; borde:sólido 1px #CCC;}
.rin p{margen-derecha:160px;}
.rin span{flotar:right; relleno:6px 5px 0px 5px; posición:relative;}
.rin span img{margen:0px 3px; cursor:pointer;}
.rin span form{posición:absoluta; ancho:25px; height:25px; ocultar:oculto; opacidad:0; arriba:5px; derecha:5px;}
.rin span input{ancho:180px; altura:25px; margen-izquierda:-160px; cursor:pointer}
#ct p{relleno:5px; línea-altura:20px;}
#ct a{color:#069; cursor:pointer;}
#ct span{color:#999; margen-derecha:10px;}
.c2{color:#999;}
.c3{fondo-color:#DBE9EC; relleno:5px;}
.qp{posición:absoluta; fuente-tamaño:12px; color:#666; arriba:5px; derecha:130px; texto-decoración:none; color:#069;}
#ems{posición:absoluta; z-índice:5; ocultar; arriba:0px; izquierda:0px; max-width:230px; background-color:#F1F1F1; border:solid 1px #CCC; padding:5px;}
#ems img{width:44px; height:44px; border:solid 1px #FFF; cursor:pointer;}
#ems img:hover,#ems img:active{border-color:#A4",true));7DA3;}
#ems a{color:#069; border-radius:2px; display:inline-block; margin:2px 5px; padding:1px 8px; text-decoration:none; background-color:#D5DFFD;}
#ems a:hover,#ems a:active,#ems a.ck{color:#FFF; background-color:#069;}
.tc{text-align:center; margin-top:5px;}
</style>
</head>
<body>
<div id="ltian">
 <div id="us" class="jb"></div>
 <div id="ct"></div>
 <a href="javascript:;" rel="external nofollow" rel="external nofollow" class="qp" onClick="this.parentNode.children[1].innerHTML=''">Borrar Pantalla</a>
</div>
<div class="rin">
 <button id="sd">Enviar</button>
 <span><img src="http://www.yxsss.com/ui/sk/t.png" title="[#1#]" id="imgbq"><img src="http://www.yxsss.com/ui/sk/e.png" title="[#2#]"><form><input type="file" title="[#2#]" id="upimg"></form></span>
 <p><input id="nrong"></p>
</div>
<div id="ems"><p></p><p class="tc"></p></div>
<script>
if(typeof(WebSocket)=='undefined'){
 alert('Su navegador no admite WebSocket, se recomienda usar Google Chrome o Mozilla Firefox'); 
}
</script>
<script src="http://www.yxsss.com/ui/p/a.js" type="text/javascript"></script>
<script>
(function(){
 var key='all',mkey;
 var users={};
 var url='ws://127.0.0.1:8000';
 var so=false,n=false;
 var lus=A.$('us'),lct=A.$('ct');
 function st(){
  var Arr1 = ["Inteligente","Cruel","Amable","Bella","Cruel","Bondadoso","Guapo","Divertido"]; 
  var Arr2 = ["Lobo gris","Conejo blanco","Tigre hembra","Extraterrestre","Pikachu","HelloKitty","Crickett Wu","Xue Ziqing"]; 
  1 = Math.floor(Math.random() * Arr1.length + 1>-1; 
  2 = Math.floor(Math.random() * Arr2.length + 1>-1; 
  var n=Arr1[ran1]+Arr2[ran2]; 
  //Estas cinco líneas se utilizan para generar nombres de usuario aleatorios, consulte más a continuación. Si desea personalizar el nombre de usuario, puede anotar las cinco líneas anteriores y descomentar las dos líneas a continuación
  //
  //n=n.substr(0,16]);
  //console.log(n);
  if(!n){
   return ; 
  }
  so=new WebSocket(url);
  so.onopen=function(){
   if(so.readyState==1{
    so.send('type=add&ming='+n);
   }
  }
  so.onclose=function(){
   so=false;
   lct.appendChild(A.$$('<p class="c',2">salir de la sala de chat</p>'));
  }
  so.onmessage=function(msg){
   eval('var da='+msg.data);
   var obj=false,c=false;
   if(da.type=='add'){
    var obj=A.$$('<p>'+da.name+</p)>;
    lus.appendChild(obj);
    cuser(obj,da.code);
    obj=A.$$('<p><span>['+da.time+']</span>欢迎<a>'+da.name+</a>加入</p)>;
    c=da.code;
   }else if(da.type=='madd'){
    mkey=da.code;
    da.users.unshift({'code':'all','name':'大家'});
    for(var i=0;i<da.users.length;i++{
     var obj=A.$$('<p>'+da.users[i].name+</p)>;
     lus.appendChild(obj);
     if(mkey!=da.users[i].code){
      cuser(obj,da.users[i].code);
     }else{
      obj.className='my';
      document.title=da.users[i].name;
     }
    }
    obj=A.$$('<p><span>['+da.time+']</span>欢迎'+da.name+'加入</p)>;
    users.all.className='ck';
   }
   if(obj==false){
    if(da.type=='rmove'){
     var obj=A.$$('<p class="c2><span>['+da.time+']</span>'+users[da.nrong].innerHTML+'退出聊天室</p)>;
     lct.appendChild(obj);
     users[da.nrong].del();
     delete users[da.nrong];
    }else{
     da.nrong=da.nrong.replace(/{\\(\d+})/g,function(a,b){
      return '<img src="sk/'+b+'.jpg">';
     }).replace(/^data\:image\/png;base64\,.{50,}$/i,function(a){
      return '<img src="'+a+'">';
     });
     //da.code 发信息人的code
     if(da.code1==mkey){
      obj=A.$$('<p class="c3><span>['+da.time+']</span><a>'+users[da.code].innerHTML+</a>对我说:'+da.nrong+</p)>;
      c=da.code;
     }else if(da.code==mkey){
      if(da.code1!='all')
      obj=A.$$('<p class="c3><span>['+da.time+']</span>我对<a>'+users[da.code1].innerHTML+</a>说:'+da.nrong+</p)>;
      else
      obj=A.$$('<p><span>['+da.time+']</span>我对<a>'+users[da.code1].innerHTML+</a>说:'+da.nrong+</p)>;
      c=da.code1;
     }else if(da.code==false){
      obj=A.$$('<p><span>['+da.time+']</span>'+da.nrong+</p)>;
     }else if(da.code1{
      obj=A.$$('<p><span>['+da.time+']</span><a>'+users[da.code].innerHTML+</a>对'+users[da.code1].innerHTML+':'+da.nrong+</p)>;
      c=da.code;
     }
    }
   }
   if(c){
     obj.children[1].onclick=function(){
      users[c].onclick();
     }
    }
   lct.appendChild(obj);
   lct.scrollTop=Math.max(0,lct.scrollHeight-lct.offsetHeight);
  }
 }
 A.$('sd').onclick=function(){
  
    return st();
  }
  var da=A.$('nrong').value.trim();
  if(da==''){
   alert('内容不能为空');
   return false; 
  }
  A.$('nrong').value='';
  so.send('nr='+esc(da)+'&key='+key);
 }
 A.$('nrong').onkeydown=function(e){
  
  if(e.keyCode==13{
   A.$('sd').onclick();
  }
 }
 function esc(da){
  da=da.replace(/</g,'<').replace(/>/g,'>').replace(/\"/g,'"');
  return encodeURIComponent(da);
 }
 function cuser(t,code){
  users[code]=t;
  t.onclick=function(){
   t.parentNode.children.rcss('ck','');
   t.rcss('','ck');
   key=code;
  }
 }
  - 7+
 
 var bq=A.$('imgbq'),ems=A.$('ems');
 var l=80,r=4,c=5,s=0,p=Math.ceil(l/(r*c));
 var pt='sk/';
 bq.onclick=function(e){
  
  
    return st();
  }
  ems.style.display='block';
  document.onclick=function(){
    
  }
  
  
 }
 for(var i=0;i<p;i++{
  var a=A.$$('<a href="javascript:;" rel="external nofollow" rel="external nofollow" >');+(i+1>+</a)>;
  1.appendChild(a);
  
 }
 1
 
  
  
   -242+
   +-235+
  }
 }
 
  
   
   **
   
   
   
   
   
  }
 }
 
  +*
  ++{
   +++
   1
   
  }
  
 }
 1
  
   
   +++
   
    
   }
   
  }
 }
 
  
  
  
 }
 
 
   - 7+
  
  
 
 
 43
 
  
   
   return false;
  }
  
   
   return false; 
  }
  
  if(f.type.match('image.', '第2段':*')){}}
   var r = new FileReader();
   r.onload = function(e){
    img.setAttribute('src',e.target.result);
   };
   r.readAsDataURL(f);
  }
 });
 img.onload=function(){
  ih=img.height,iw=img.width;
  if(iw/ih > dw/dh && iw > dw){
   ih=ih/iw*dw;
   iw=dw;
  }else if(ih > dh){
   iw=iw/ih*dh;
   ih=dh;
  }
  var rc = A.$$('canvas');
  var ct = rc.getContext('2d');
  rc.width=iw;
  rc.height=ih;
  ct.drawImage(img,0,0,iw,ih);
  var da=rc.toDataURL();
  so.send('nr='+esc(da)+'&key='+key);
 }
})();
</script>
</body>
</html>

Código de backend: webserver.php

<?php
error_reporting(E_ALL ^ E_NOTICE);
ob_implicit_flush();
$sk=new Sock('127.0.0.1',8000);
$sk->run();
class Sock{
 public $sockets;
 public $users;
 public $master;
 private $sda=array();//Datos recibidos
 private $slen=array();//Longitud total de datos
 private $sjen=array();//Longitud de datos recibidos
 private $ar=array();//Clave de cifrado
 private $n=array();
 public function __construct($address, $port){
 $this->master=$this->WebSocket($address, $port);
 $this->sockets=array($this->master);
 }
 function run(){
 while(true){
 $changes=$this->sockets;
 $write=NULL;
 $except=NULL;
 socket_select($changes,$write,$except,NULL);
 foreach($changes as $sock){
 if($sock==$this->master){
  $client=socket_accept($this->master);
  $key=uniqid();
  $this->sockets[]=$client;
  $this->users[$key]=array(
  'socket'=>$client,
  'shou'=>false
  ]);
 }else{
  $len=0;
  $buffer='';
  do{
  $l=socket_recv($sock,$buf,1000,0);
  $len+=$l;
  while($l==
  }1000);
  $k=$this->search($sock);
  if($len<7{
  $this->send2($k);
  continue;
  }
  if(!$this->users[$k]['shou']){
  $this->woshou($k,$buffer);
  }else{
  $buffer = $this->uncode($buffer,$k);
  if($buffer==false){
  continue;
  }
  $this->send($k,$buffer);
  }
 }
 }
 }
 }
 function close($k){
 socket_close($this->users[$k]['socket']);
 unset($this->users[$k]);
 $this->sockets=array($this->master);
 foreach($this->users as $v){
 $this->sockets[]=$v['socket'];
 }
 $this->e("key:$k close");
 }
 function search($sock){
 foreach ($this->users as $k=>$v){
 if($sock==$v['socket'])
 return $k;
 }
 return false;
 }
 function WebSocket($address,$port){
 $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
 socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1]);
 socket_bind($server, $address, $port);
 >e('Server Started : '.date('Y
 $this-m-d H:i:s'));->e('Listening on : '.$address.' port '.$port);
 $this-return $server;
 function woshou($k,$buffer){
 }
 $buf = substr($buffer,strpos($buffer,'Sec"
 Key:')-Accept: " . $new_key . "\r\n\r\n";-$key = trim(substr($buf,0,strpos($buf,"\r\n")));+18]);
 $new_key = base
 _encode(sha64($key."1EAFA258E5-DA914-47CA-95AB0DC-C5B85",true));11$new_message = "HTTP"
 Switching Protocols\r\n"/1.1 101 $new_message .= "Upgrade: websocket\r\n"
 Version:
 WebSocket-Accept: " . $new_key . "\r\n\r\n";-\r\n" 13$new_message .= "Connection: Upgrade\r\n"
 $new_message .= "Sec"
 WebSocket-Accept: " . $new_key . "\r\n\r\n";->users[$k]['socket'],$new_message,strlen($new_message));
 socket_write($this->users[$k]['shou']=true;
 $this-return true;
 function uncode($str,$key){
 }
 $mask = array();
 $data = ''; 
 $msg = unpack('H', 
 ',$str);*$head = substr($msg[
 ],0,1if ($head == '2]); 
 ' && !isset($this81>slen[$key])) {-if(substr($msg[ 
 $len=substr($msg[1,2$s =2]);
 $len=hexdec($len);
 ])=='fe'){1,2$s =2else if(substr($msg[
 $len=substr($msg[1,4$s =4]);
 $len=hexdec($len);
 $msg[1]=substr($msg[1,4]);
 }1,2$s =2])=='ff'){
 $len=substr($msg[1,4$s =16]);
 $len=hexdec($len);
 $msg[1]=substr($msg[1,16]);
 }
 $mask[] = hexdec(substr($msg[1,4$s =2)); 
 $mask[] = hexdec(substr($msg[1,6$s =2)); 
 $mask[] = hexdec(substr($msg[1,8$s =2)); 
 $mask[] = hexdec(substr($msg[1,10$s =2));
 $n=0; 12;
 else if($this
 }->slen[$key] > 0){
 $len=$this->slen[$key];
 $mask=$this->ar[$key];
 $n=$this->n[$key];
 $s = 0;
 }
 $e = strlen($msg[1)]-2;
 for ($i=$s; $i<= $e; $i+= 2) { 
 $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i,2); 
 $n++; 
 } 
 $dlen=strlen($data);
 if($len > 255 && $len > $dlen+intval($this->sjen[$key])){
 $this->ar[$key]=$mask;
 $this->slen[$key]=$len;
 $this->sjen[$key]=$dlen+intval($this->sjen[$key]);
 $this->sda[$key]=$this->sda[$key].$data;
 $this->n[$key]=$n;
 return false;
 }else{
 unset($this->ar[$key],$this->slen[$key],$this->sjen[$key],$this->n[$key]);
 $data=$this->sda[$key].$data;
 unset($this->sda[$key]);
 return $data;
 }
 }
 function code($msg){
 $frame = array(); 
 $frame[0] = '81'; 
 $len = strlen($msg);
 if($len < 126{
 $frame[1] = $len<16?'0'.dechex($len):dechex($len);
 }else if($len < 65025{
 $s=dechex($len);
 $frame[1]='7e'.str_repeat('0',4-strlen($s)).$s;
 }else{
 $s=dechex($len);
 $frame[1]='7f'.str_repeat('0',16-strlen($s)).$s;
 }
 $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<$l; $i++) { 
 $msg .= dechex(ord($data{$i})); 
 } 
 return $msg; 
 }
 //用户加入
 function send($k,$msg){
 parse_str($msg,$g);
 $ar=array();
 if($g['type']=='add'){
 $this->users[$k]['name']=$g['ming'];
 $ar['type']='add';
 $ar['name']=$g['ming'];
 $key='all';
 }else{
 $ar['nrong']=$g['nr'];
 $key=$g['key'];
 }
 $this->send1($k,$ar,$key);
 }
 function getusers(){
 $ar=array();
 foreach($this->users as $k=>$v){
 $ar[]=array('code'=>$k,'name'=>$v['name']);
 }
 return $ar;
 }
 //$k 发信息人的code $key接受人的 code
 function send1($k,$ar,$key='all'){
 $ar['code1']=$key;
 $ar['code']=$k;
 $ar['time']=date('m-d H:i:s');
 $str = $this->code(json_encode($ar));
 if($key=='all'){
 $users=$this->users;
 if($ar['type']=='add'){
 $ar['type']='madd';
 $ar['users']=$this->getusers();
 $str1 = $this->code(json_encode($ar));
 socket_write($users[$k]['socket'],$str1,strlen($str1));
 unset($users[$k]);
 }
 foreach($users as $v){
 socket_write($v['socket'],$str,strlen($str));
 }
 }else{
 socket_write($this->users[$k]['socket'],$str,strlen($str));
 socket_write($this->users[$key]['socket'],$str,strlen($str));
 }
 }
 //El usuario ha salido
 function send2($k){
 $this->close($k);
 $ar['type']='rmove';
 $ar['nrong']=$k;
 $this->send1(false,$ar,'all');
 }
 function e($str){
 //$path=dirname(__FILE__).'/log.txt';
 
 //3
 echo iconv('utf-8','gbk//IGNORE,$str);
 }
}
?>

Muchos estudiantes han dicho que mi proyecto de código fuente sigue generando errores y no puede ejecutarse. Explico los pasos detallados de instalación y despliegue.

Primero, descomprima el código fuente descargado y colóquelo en el directorio web, por ejemplo, el mío es applications/Xampp/xamppfiles/htdocs/phpb/websocket

Ruta

Luego, use la herramienta de línea de comandos para cambiar al directorio correspondiente y ejecutar el comando:

php websocket.php

Imágenes de efecto de ejecución:

Operaciones de línea de comandos

A continuación, abra el servidor Apache, acceda al navegador a través de http://localhost/phpb/websocket/client.html

Imágenes de efecto de ejecución:

Enlace de código fuente:webSoket-php-chatsever_jb51.rar

Esto es todo el contenido de este artículo, espero que sea útil para su aprendizaje y que todos los amigos apoyen el tutorial de gritos.

Declaración: el contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga espontáneamente por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha realizado una edición humana y no asume ninguna responsabilidad legal relacionada. Si encuentra contenido sospechoso de copyright, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @) para denunciar, y proporcione evidencia relevante. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción.

Te gustará