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里面进行了链接,进行通信,废话不多说,直接上代码吧, 首先, ...
随机推荐
- grep 查询包含内容的文件
加入到 ~/.bashrc 或者 ~/.bash_profile bash export GREPF_FILES=/mnt/d/Developer:/mnt/e/Developer function ...
- Mac环境下Android Studio配置Git以及最基本使用
Git是分布式版本管理工具,现在使用十分广泛,相对于SVN,GIT的使用更加方便,在离线环境下,仍然可以进行版本控制工作.且速度十分快.在Windows下,先需要自行安装Git程序,网址git-scm ...
- iOS-证书真机调试
开发者账号分类 个人的 99$ 申请简单,付钱就行,688人民币 企业的 99$ 申请复杂,需要“邓白氏”认证,可以确认企业是合法有效的 可以管理团队开发 商业的 299$ 也需要邓白氏 ...
- python迭代器与生成器(二)
一.什么是迭代? 迭代通俗的讲就是一个遍历重复的过程. 维基百科中 迭代(Iteration) 的一个通用概念是:重复某个过程的行为,这个过程中的每次重复称为一次迭代.具体对应到Python编程中 ...
- GAN作用——在我做安全的看来,就是做数据拟合、数据增强
from:https://www.zhihu.com/question/56171002/answer/155777359 GAN的作用,也就是为什么GAN会火了(有部分原因可能是因为Lecun的赞赏 ...
- 【scala】占位符
Scala语言为了让函数字面量更加精简,还可以使用下划线作为占位符,用来表示一个或多个参数. 我们用来表示的参数必须满足只在函数字面量中出现一次. 我们用例子来看占位符的用法 scala> va ...
- 【Hive】数据类型
1.基本类型 整型:tinyint / samllint / int / bigint 浮点型:float / double / Decimals 布尔型:boolean 字符串:string / v ...
- 【ccf2017-12-2】游戏(模拟)
问题描述 有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向. 游戏开始,从1号小朋 ...
- EL标签
1.EL的作用 jsp的核心语法: jsp表达式 <%=%>和 jsp脚本<% %>. 开发jsp的原则: 尽量在jsp页面中少写甚至不写java代码. 使用EL表达式替换掉 ...
- [置顶]
Android Shape一些新玩法?
敏少咨讯: 1.生活琐事篇 最近由于公司赶项目所以偷懒了,博客没有及时更新,还请小伙伴们手下留情啊!最近发生了很多趣事,就在今天我们学校退书籍费,这可把我开心的哈哈!无缘无故又有钱了,嘿嘿,刚好五一出 ...