websocket服务端PHP代码
来源:互联网 发布:淘宝怎么提高买家信誉 编辑:程序博客网 时间:2024/06/01 10:38
在网上看到一个高手写的PHP代码就直接拉下来修改了一下,原贴地址暂时没找到,找到了贴回来
2016年6月18日
这位大佬写的很详细,看他的博客会好一点
http://blog.jnecw.com/p/1523
//socket.phpset_time_limit(0);//永不超时class socket{ private $host = '127.0.0.1'; private $port = 8080; private $maxuser = 10; public $accept = array(); //连接的客户端 private $cycle = array(); //循环连接池 private $isHand = array();//握手信息 //加载socket配置 function __construct($host, $port, $max) { $this->host = $host; $this->port = $port; $this->maxuser = $max; } //挂起socket public function start_server() { //创建一个socket $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //配置socket socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, TRUE); //绑定接口,最多10个人连接,超过的客户端连接会返回WSAECONNREFUSED错误 socket_bind($this->socket, $this->host, $this->port); //监听接口 socket_listen($this->socket, $this->maxuser); while(TRUE) { //获取所有socket连接 $this->cycle = $this->accept; $this->cycle[] = $this->socket; //阻塞用,有新连接时才会结束 socket_select($this->cycle, $write, $except, null); foreach ($this->cycle as $k => $v) { //当socket运行到连接池最后一位时,开始添加连接 if($v === $this->socket) { //如果socket连接失败,跳出本次循环 if (($accept = socket_accept($v)) < 0) { continue; } //连接成功加入连接池 $this->add_accept($accept); continue; } //在连接池中搜索socket连接ID $acceptId = array_search($v, $this->accept); //如果连接没有保存至连接池,跳出本次循环 if ($acceptId === NULL) { continue; } //没消息的socket就断开 if (!@socket_recv($v, $data, 1024, 0) || !$data) { $this->close($v); continue; } //检查是否握手 if (!$this->isHand[$acceptId]) { //进行握手 $this->upgrade($v, $data, $acceptId); continue; } //将数据进行解码 $data = $this->decode($data); //将信息返回给客户端 $this->send_to_user($v,$data); } sleep(1); } } /** * 新建一个连接 * @param $accept 套接号 */ private function add_accept($accept) { $this->accept[] = $accept; $accept = array_keys($this->accept); //获取新连接的key值,用于跟握手信息绑定 $acceptId = end($accept); //添加初次连接用户握手信息 $this->isHand[$acceptId] = FALSE; } /** * 关闭一个连接 * @param $accept 套接号 */ private function close($accept) { //在连接池中搜索套接号 $acceptId = array_search($accept, $this->accept); //断开socket连接 socket_close($accept); //销毁变量 unset($this->cycle[$acceptId]); unset($this->accept[$acceptId]); unset($this->isHand[$acceptId]); } /** * 响应升级协议,与websocket进行握手 * @param $accept 套接号 * @param $data websocket发送的数据 * @param $acceptId 与套接号绑定的Id */ private function upgrade($accept, $data, $acceptId) { //用正则表达式获取websocket传输过来的key值 if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$data,$match)) { //服务端生成对应key值返回 $key = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); $upgrade = "HTTP/1.1 101 Switching Protocol\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Accept: " . $key . "\r\n\r\n"; //必须以两个回车结尾 //向套接口写入数据 socket_write($accept, $upgrade, strlen($upgrade)); $this->isHand[$acceptId] = TRUE; } } /** * 编码信息 * @param $data 需要编码的数据 */ private function frame($data){ //将数据转为数组,一个元素长度最高为125 $array = str_split($data, 125); //添加头文件信息,不然前台无法接受 if (count($array) == 1){ return "\x81" . chr(strlen($array[0])) . $array[0]; } $ns = ""; foreach ($data as $v){ $ns .= "\x81" . chr(strlen($v)) . $v; } return $ns; } /** * 按照websocket协议进行解码 * @param $buffer 需要解码的数据 */ private function decode($buffer) { $len = $masks = $data = $decoded = null; //获取传递过来数据长度 $len = ord($buffer[1]) & 127; if ($len === 126) { $masks = substr($buffer, 4, 4); $data = substr($buffer, 8); } else if ($len === 127) { $masks = substr($buffer, 10, 4); $data = substr($buffer, 14); } else { $masks = substr($buffer, 2, 4); $data = substr($buffer, 6); } // for ($index = 0; $index < strlen($data); $index++) { $decoded .= $data[$index] ^ $masks[$index % 4]; } return $decoded; } /** * 向所有连接至socket的用户发送消息 * @param $accept 套接号 * @param $data 发送的数据 */ private function send_to_user($accept, $data){ //添加头文件信息 $data = $this->frame($data); socket_write($accept, $data, strlen($data)); }}
如何调用
//index.phprequire('socket.php');//设置连接信息$ws = new socket('192.168.0.114', '8080', 10);//开启socket服务端$ws->start_server();
用命令行打开index.php就可以挂起socket服务器了
0 0
- websocket服务端PHP代码
- 服务端接收文件PHP代码
- php socket 服务端实现代码
- WebSocket 服务端实现
- websocket服务端请求标准
- java编写WebSocket服务端
- C# 实现WebSocket服务端
- Java WebSocket服务端实现
- google支付服务端订单验证PHP代码
- Php websocket
- websocket-php
- websocket php
- php websocket
- 用Python写了个websocket即时聊天网页(含客户端、服务端代码)
- netty的websocket服务端开发
- IdHTTPServer完成websocket服务端编写
- java编写的Websocket服务端
- Websocket服务端实现的方法
- Leetcode 111. Minimum Depth of Binary Tree
- IEEE 802.15.4协议完整中文版 - 3.2 缩略语和简写
- C++ map 中的reverse_iterator
- Unix & Linux笔记(16)
- 二叉树前序,中序,后序求法
- websocket服务端PHP代码
- 修改代码
- MAC OS下JDK版本切换指南
- 内外网同时上网的方法
- Android开发:利用AlarmManager不间断向服务器发送请求以及notification通知
- MTSimpleAdapter框架扩展——添加empty页面、error页面和loading等特性
- 同步代码块什么时候释放锁
- xargs的用法
- 修改内核临时端口范围