PHP 简单实现webSocket
费话少说,用源代码说话
1)客户端实现

1 <html>
2 <head>
3 <meta charset="UTF-8">
4 <title>Web sockets test</title>
5 <script src="jquery-min.js" type="text/javascript"></script>
6 <script type="text/javascript">
7 var ws;
8 function ToggleConnectionClicked() {
9 try {
10 ws = new WebSocket("ws://127.0.0.1:2000");//连接服务器
11 ws.onopen = function(event){alert("已经与服务器建立了连接\r\n当前连接状态:"+this.readyState);};
12 ws.onmessage = function(event){alert("接收到服务器发送的数据:\r\n"+event.data);};
13 ws.onclose = function(event){alert("已经与服务器断开连接\r\n当前连接状态:"+this.readyState);};
14 ws.onerror = function(event){alert("WebSocket异常!");};
15 } catch (ex) {
16 alert(ex.message);
17 }
18 };
19
20 function SendData() {
21 try{
22 var content = document.getElementById("content").value;
23 if(content){
24 ws.send(content);
25 }
26
27 }catch(ex){
28 alert(ex.message);
29 }
30 };
31
32 function seestate(){
33 alert(ws.readyState);
34 }
35
36 </script>
37 </head>
38 <body>
39 <button id='ToggleConnection' type="button" onclick='ToggleConnectionClicked();'>连接服务器</button><br /><br />
40 <textarea id="content" ></textarea>
41 <button id='ToggleConnection' type="button" onclick='SendData();'>发送我的名字:beston</button><br /><br />
42 <button id='ToggleConnection' type="button" onclick='seestate();'>查看状态</button><br /><br />
43
44 </body>
45 </html>

2)服务器端实现

1 class WS {
2 var $master; // 连接 server 的 client
3 var $sockets = array(); // 不同状态的 socket 管理
4 var $handshake = false; // 判断是否握手
5
6 function __construct($address, $port){
7 // 建立一个 socket 套接字
8 $this->master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)
9 or die("socket_create() failed");
10 socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1)
11 or die("socket_option() failed");
12 socket_bind($this->master, $address, $port)
13 or die("socket_bind() failed");
14 socket_listen($this->master, 2)
15 or die("socket_listen() failed");
16
17 $this->sockets[] = $this->master;
18
19 // debug
20 echo("Master socket : ".$this->master."\n");
21
22 while(true) {
23 //自动选择来消息的 socket 如果是握手 自动选择主机
24 $write = NULL;
25 $except = NULL;
26 socket_select($this->sockets, $write, $except, NULL);
27
28 foreach ($this->sockets as $socket) {
29 //连接主机的 client
30 if ($socket == $this->master){
31 $client = socket_accept($this->master);
32 if ($client < 0) {
33 // debug
34 echo "socket_accept() failed";
35 continue;
36 } else {
37 //connect($client);
38 array_push($this->sockets, $client);
39 echo "connect client\n";
40 }
41 } else {
42 $bytes = @socket_recv($socket,$buffer,2048,0);
43 print_r($buffer);
44 if($bytes == 0) return;
45 if (!$this->handshake) {
46 // 如果没有握手,先握手回应
47 $this->doHandShake($socket, $buffer);
48 echo "shakeHands\n";
49 } else {
50
51 // 如果已经握手,直接接受数据,并处理
52 $buffer = $this->decode($buffer);
53 //process($socket, $buffer);
54 echo "send file\n";
55 }
56 }
57 }
58 }
59 }
60
61 function dohandshake($socket, $req)
62 {
63 // 获取加密key
64 $acceptKey = $this->encry($req);
65 $upgrade = "HTTP/1.1 101 Switching Protocols\r\n" .
66 "Upgrade: websocket\r\n" .
67 "Connection: Upgrade\r\n" .
68 "Sec-WebSocket-Accept: " . $acceptKey . "\r\n" .
69 "\r\n";
70
71 echo "dohandshake ".$upgrade.chr(0);
72 // 写入socket
73 socket_write($socket,$upgrade.chr(0), strlen($upgrade.chr(0)));
74 // 标记握手已经成功,下次接受数据采用数据帧格式
75 $this->handshake = true;
76 }
77
78
79 function encry($req)
80 {
81 $key = $this->getKey($req);
82 $mask = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
83
84 return base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
85 }
86
87 function getKey($req)
88 {
89 $key = null;
90 if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $req, $match)) {
91 $key = $match[1];
92 }
93 return $key;
94 }
95
96 // 解析数据帧
97 function decode($buffer)
98 {
99 $len = $masks = $data = $decoded = null;
100 $len = ord($buffer[1]) & 127;
101
102 if ($len === 126) {
103 $masks = substr($buffer, 4, 4);
104 $data = substr($buffer, 8);
105 } else if ($len === 127) {
106 $masks = substr($buffer, 10, 4);
107 $data = substr($buffer, 14);
108 } else {
109 $masks = substr($buffer, 2, 4);
110 $data = substr($buffer, 6);
111 }
112 for ($index = 0; $index < strlen($data); $index++) {
113 $decoded .= $data[$index] ^ $masks[$index % 4];
114 }
115 return $decoded;
116 }
117
118 // 返回帧信息处理
119 function frame($s)
120 {
121 $a = str_split($s, 125);
122 if (count($a) == 1) {
123 return "\x81" . chr(strlen($a[0])) . $a[0];
124 }
125 $ns = "";
126 foreach ($a as $o) {
127 $ns .= "\x81" . chr(strlen($o)) . $o;
128 }
129 return $ns;
130 }
131
132 // 返回数据
133 function send($client, $msg)
134 {
135 $msg = $this->frame($msg);
136 socket_write($client, $msg, strlen($msg));
137 }
138 } 测试 $ws = new WS("127.0.0.1",2000);

PHP 简单实现webSocket的更多相关文章
- 用 Go 编写一个简单的 WebSocket 推送服务
用 Go 编写一个简单的 WebSocket 推送服务 本文中代码可以在 github.com/alfred-zhong/wserver 获取. 背景 最近拿到需求要在网页上展示报警信息.以往报警信息 ...
- 【node+小程序+web端】简单的websocket通讯
[node+小程序+web端]简单的websocket通讯 websoket是用来做什么的? 聊天室 消息列表 拼多多 即时通讯,推送, 实时交互 websoket是什么 websocket是一个全新 ...
- springboot搭建一个简单的websocket的实时推送应用
说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...
- python简单实现websocket
协议选择的是新的Hybi-10,参考文章如下: http://www.cnblogs.com/zhuweisky/p/3930780.html http://blog.mycolorway.com/2 ...
- 实现一个简单的WebSocket聊天室
WebSocket 简介 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主 ...
- 简单聊聊WebSocket
一.概述 上一篇文章<浅析一次HTTP请求>我们分析了简单的一次 HTTP 请求具体是怎么样完成的,分析了 HTTP 协议的数据结构,如何连接,如何断开,又是如何多路复用的,那么今天我们来 ...
- 用Java构建一个简单的WebSocket聊天项目之新增HTTP接口调度
采用框架 我们整个Demo基本不需要大家花费太多时间,就可以实现以下的功能. 用户token登录校验 自我聊天 点对点聊天 群聊 获取在线用户数与用户标签列表 发送系统通知 首先,我们需要介绍一下我们 ...
- WebSocket简单介绍(WebSocket 实战)(3)
这一节里我们用一个案例来演示怎么使用 WebSocket 构建一个实时的 Web 应用.这是一个简单的实时多人聊天系统,包括客户端和服务端的实现.客户端通过浏览器向聊天服务器发起请求,服务器端解析客户 ...
- WebSocket简单介绍(WebSocket JavaScript 接口)(2)
上一节介绍了 WebSocket 规范,其中主要介绍了 WebSocket 的握手协议.握手协议通常是我们在构建 WebSocket 服务器端的实现和提供浏览器的WebSocket 支持时需要考虑的问 ...
- 使用node+vue实现简单的WebSocket聊天功能
最近学习了一下websocket的即时通信,感觉非常的强大,这里我用node启动了一个服务进行websocket链接,然后再vue的view里面进行了链接,进行通信,废话不多说,直接上代码吧, 首先, ...
随机推荐
- C#和Java接口对比
C#和java的接口有很多类似之处,对于编程约束和设计模式的实现有重要作用.这里记录几个知识点. 1. C#的接口中不能有字段,但Java的接口中允许有static final修饰的字段/域(fiel ...
- iOS自动化探索(一)WebDriverAgent安装
WebDriverAgent FaceBook推出的一款iOS移动测试框架, 支持真机和模拟器, 同时支持USB, 官方是这样介绍的: https://github.com/facebook/WebD ...
- dubbo-monitor安装、 监控中心 配置过程
简单介绍下monitor: Simple Monitor挂掉不会影响到Consumer和Provider之间的调用,所以用于生产环境不会有风险. 配置好了之后可以结合admin管理后台使用,可以清晰的 ...
- 理解字符串 Boyer-Moore 算法
作者: 阮一峰 上一篇介绍了 kmp算法 但是,它并不是效率最高的算法,实际采用并不多. 各种文本编辑器的"查找"功能(Ctrl+F),大多采用Boyer-Moore算法. Boy ...
- AS3里面的错误代码
ActionScript 3 出现2048安全策略服务,一种原因是因为843端口下发策略文件有问题,另一种原因是Socket端口有问题,可以用telnet来测试. 其它AS3错误代码的意义可以在官网文 ...
- R 之 rJava 包安装错误的解决方案
前几天在Ubuntu上安装R中的xlsx包时一直卡在了rJava包的安装上,最终各种google都没能解决问题.直到最后,我回到了安装rJava时的错误记录....我用血的教训证明,错误日志是很重要很 ...
- ORM版,学生管理系统02
学生管理系统 urls.py url(r'^student_list/$',views.student_list,name="student_list"), url(r'^dele ...
- MpVue开发之框架的搭建
npm install --global vue-cli vue脚手架 vue init mpvue/mpvue-quickstart my-project 创建一个基于mpvue-quickst ...
- 【转载】取得系统中网卡MAC地址的三种方法
From:http://blog.csdn.net/zhangting1987/article/details/2732135 网卡地址这个概念有点混淆不清.因为实际上有两个地址,mac地址和物理地址 ...
- Laraver 框架资料
重定向: return redirect()->to('http://www.baidu.com'); 重定向到内部路由 return redirect()->route(‘name’); ...