服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|编程技术|正则表达式|C/C++|

服务器之家 - 编程语言 - PHP教程 - php+html5基于websocket实现聊天室的方法

php+html5基于websocket实现聊天室的方法

2020-11-06 21:21洞悉 PHP教程

这篇文章主要介绍了php+html5基于websocket实现聊天室的方法,实例分析了php结合html5的websocket通讯的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下

本文实例讲述了php+html5基于websocket实现聊天室的方法。分享给大家供大家参考。具体如下:

html5的websocket 实现了双向通信,折腾了几天弄了个聊天室,分享给大家

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<?php
error_reporting(E_ALL);
ob_implicit_flush();
$sk=new Sock('127.0.0.1',8000);
$sk->run();
class Sock{
 public $sockets;
 public $users;
 public $master;
 public function __construct($address, $port){
  $this->master=$this->WebSocket($address, $port);
  $this->sockets=array('s'=>$this->master);
 }
 function run(){
  while(true){
   $changes=$this->sockets;
   socket_select($changes,$write=NULL,$except=NULL,NULL);
   foreach($changes as $sock){
    if($sock==$this->master){
     $client=socket_accept($this->master);
     //$key=uniqid();
     $this->sockets[]=$client;
     $this->users[]=array(
      'socket'=>$client,
      'shou'=>false
     );
    }else{
     $len=socket_recv($sock,$buffer,2048,0);
     $k=$this->search($sock);
     if($len<7){
      $name=$this->users[$k]['ming'];
      $this->close($sock);
      $this->send2($name,$k);
      continue;
     }
     if(!$this->users[$k]['shou']){
      $this->woshou($k,$buffer);
     }else{
      $buffer = $this->uncode($buffer);
      $this->send($k,$buffer);
     }
    }
   }
  }
 }
 function close($sock){
  $k=array_search($sock, $this->sockets);
  socket_close($sock);
  unset($this->sockets[$k]);
  unset($this->users[$k]);
  $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);
  socket_listen($server);
  $this->e('Server Started : '.date('Y-m-d H:i:s'));
  $this->e('Listening on : '.$address.' port '.$port);
  return $server;
 }
 function woshou($k,$buffer){
  $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";
  socket_write($this->users[$k]['socket'],$new_message,strlen($new_message));
  $this->users[$k]['shou']=true;
  return true;
 }
 function uncode($str){
  $mask = array();
  $data = '';
  $msg = unpack('H*',$str);
  $head = substr($msg[1],0,2);
  if (hexdec($head{1}) === 8) {
   $data = false;
  }else if (hexdec($head{1}) === 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<= $e; $i+= 2) {
    $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i,2)));
    $n++;
   }
  }
  return $data;
 }
 function code($msg){
  $msg = preg_replace(array('/\r$/','/\n$/','/\r\n$/',), '', $msg);
  $frame = array();
  $frame[0] = '81';
  $len = strlen($msg);
  $frame[1] = $len<16?'0'.dechex($len):dechex($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<$l; $i++) {
   $msg .= dechex(ord($data{$i}));
  }
  return $msg;
 }
 function send($k,$msg){
  /*$this->send1($k,$this->code($msg),'all');*/
  parse_str($msg,$g);
  $this->e($msg);
  $ar=array();
  if($g['type']=='add'){
   $this->users[$k]['ming']=$g['ming'];
   $ar['add']=true;
   $ar['nrong']='欢迎'.$g['ming'].'加入!';
   $ar['users']=$this->getusers();
   $key='all';
  }else if($g['type']=='ltiao'){
   $ar['nrong']=$g['nr'];
   $key=$g['key'];
  }
  $msg=json_encode($ar);
  $this->e($msg);
  $msg = $this->code($msg);
  $this->send1($k,$msg,$key);
  //socket_write($this->users[$k]['socket'],$msg,strlen($msg));
 }
 function getusers(){
  $ar=array();
  foreach($this->users as $k=>$v){
   $ar[$k]=$v['ming'];
  }
  return $ar;
 }
 function send1($k,$str,$key='all'){
  if($key=='all'){
   foreach($this->users as $v){
    socket_write($v['socket'],$str,strlen($str));
   }
  }else{
   if($k!=$key)
   socket_write($this->users[$k]['socket'],$str,strlen($str));
   socket_write($this->users[$key]['socket'],$str,strlen($str));
  }
 }
 function send2($ming,$k){
  $ar['remove']=true;
  $ar['removekey']=$k;
  $ar['nrong']=$ming.'退出聊天室';
  $str = $this->code(json_encode($ar));
  $this->send1(false,$str,'all');
 }
 function e($str){
  $path=dirname(__FILE__).'/log.txt';
  $str=$str."\n";
  error_log($str,3,$path);
  echo iconv('utf-8','gbk//IGNORE',$str);
 }
}
?>

希望本文所述对大家的php程序设计有所帮助。

延伸 · 阅读

精彩推荐
  • PHP教程PHP设计模式之状态模式定义与用法详解

    PHP设计模式之状态模式定义与用法详解

    这篇文章主要介绍了PHP设计模式之状态模式定义与用法,结合实例形式分析了php状态模式的概念、原理、定义、使用方法及相关注意事项,需要的朋友可以参...

    雪山飞猪3692019-10-14
  • PHP教程php中大括号作用介绍

    php中大括号作用介绍

    {}大括号在php中的作用(PHP变量放在大括号里面的含义) ...

    PHP教程网2692019-12-28
  • PHP教程php+mysql实现无限分类实例详解

    php+mysql实现无限分类实例详解

    这篇文章主要介绍了php+mysql实现无限分类的方法,实例分析了mysql数据库设计、数据库操作及无限极分类的具体实现步骤,非常具有实用价值,需要的朋友可以...

    PHP教程网5162020-08-29
  • PHP教程PHP调试函数和日志记录函数分享

    PHP调试函数和日志记录函数分享

    这篇文章主要介绍了PHP调试函数和日志记录函数分享,本文分享的函数都是自己项目中使用的,需要的朋友可以参考下...

    PHP教程网1872020-09-01
  • PHP教程php中获取关键词及所属来源搜索引擎名称的代码

    php中获取关键词及所属来源搜索引擎名称的代码

    有时候我们需要知道用户通过哪个搜索引擎,通过拿个关键词访问我们页面,当然js也可以实现,但这里介绍下php的实现代码。 ...

    php教程网1942019-11-18
  • PHP教程PDO::lastInsertId讲解

    PDO::lastInsertId讲解

    今天小编就为大家分享一篇关于PDO::lastInsertId讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...

    php参考手册2712019-06-26
  • PHP教程PHP命令行脚本接收传入参数的三种方式

    PHP命令行脚本接收传入参数的三种方式

    这篇文章主要介绍了PHP命令行脚本接收传入参数的三种方式,即把PHP脚本像Python脚本、Ruby脚本、Shell脚本一样,用来处理命令行程序,如何获取命令行中的参数...

    琼台3842020-07-23
  • PHP教程php数组排序usort、uksort与sort函数用法

    php数组排序usort、uksort与sort函数用法

    这篇文章主要介绍了php数组排序usort、uksort与sort函数用法,详细介绍了usort、uksort与sort函数在数组排序中的应用,具有不错的参考借鉴价值,需要的朋友可以参...

    php中文网3692020-08-12