<?php
error_reporting(E_ALL ^ E_NOTICE);/* Allow the script to hang around waiting for connections. */
set_time_limit(0);/* Turn on implicit output flushing so we see what we're getting* as it comes in. */
ob_implicit_flush();// 直接输出到浏览器$address = '192.168.0.171';
const MAX_LISTEN_NUM = 200;
$port = 1212;
$socketPool = [];
if (($hostSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}// 设置TIME_WAIT状态socket可以复用
socket_set_option($hostSocket, SOL_SOCKET, SO_REUSEADDR,1);// 强制关闭socket开关:l_linger=0开启,1平滑关闭
$linger = array ('l_linger' => 0, 'l_onoff' => 1);
socket_set_option($hostSocket, SOL_SOCKET, SO_LINGER, $linger);if (socket_bind($hostSocket, $address, $port) === false) {echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($hostSocket)) . "\n";
}if (socket_listen($hostSocket, 200) === false) {echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($hostSocket)) . "\n";
}// 把所有socket存储在$sockets$socketPool[] = ['source'=>$hostSocket];try {while(true){$sockets = array_column($socketPool,'source'); // 拷贝clients$write = null; // 可读socket$except = null; // 异常socket$readNum = socket_select($sockets,$write,$except,null);foreach ($sockets as $socket) {if ($socket == $hostSocket) {// 处理连接情况$client = socket_accept($hostSocket);echo 'client:'.$client;echo 'client:'.(int)$client;if ($client < 0) {echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($hostSocket)) . "\n";} else {$socketPool[(int)$client] = ['source'=>$client,'handshake'=>false];}} else {$len = socket_recv($socket, $buff, 2048,0);echo 'len:'.$len;echo 'buff:'.$buff;$recvMsg = decode($buff);echo 'recvMsg:'.$recvMsg;// buff=null 证明socket已经关闭if ($buff == null) {socket_close($socket);unset($socketPool[(int)$socket]);break;}else if ($socketPool[(int)$socket]['handshake']) {// 发送消息$answMsg = frame(json_encode(['code'=>0,'msg'=>$recvMsg,'data'=>[]]));$host = '';$port = '';// socket_getpeername($socket,$host,$port);// echo 'host:'.$host;// echo 'port:'.$port;@socket_write($socket,$answMsg,strlen($answMsg));} else {// 握手$socketPool[(int)$socket]['handshake'] =  true;handshake($socket,$buff,$address,$port);}}}}
} catch (Exception $e) {echo $e->getMessage();socket_shutdown($hostSocket);socket_close($hostSocket);
}function handshake($socket,$buffer,$host, $port)
{$headers = array();$lines = preg_split("/\r\n/", $buffer);foreach($lines as $line){$line = rtrim($line);if(preg_match('/\A(\S+): (.*)\z/', $line, $matches)){$headers[$matches[1]] = $matches[2];}}$secKey = $headers['Sec-WebSocket-Key'];$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));//hand shaking header$upgrade  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" ."Upgrade: websocket\r\n" ."Connection: Upgrade\r\n" ."WebSocket-Origin: $host\r\n" ."WebSocket-Location: ws://$host:$port\r\n"."Sec-WebSocket-Version: 13\r\n" ."Sec-WebSocket-Accept:$secAccept\r\n\r\n";socket_write($socket, $upgrade);
}// 解析数据帧
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;
}// 返回帧信息处理
function frame($s) {$a = str_split($s, 125);if (count($a) == 1) {return "\x81" . chr(strlen($a[0])) . $a[0];}$ns = "";foreach ($a as $o) {$ns .= "\x81" . chr(strlen($o)) . $o;}return $ns;
}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<input type="text" name="msg" value="这是发送消息" id="msg"/><br>
<button onclick="send()">发送</button><br>
<button onclick="closeWs()">关闭连接</button>
<script>var ws = new WebSocket('ws://192.168.0.171:1212/');ws.onopen = function(e){console.log("Connection open ...");ws.send("发送消息");}ws.onmessage = function(e){console.log("onmessage",e.data);}ws.onclose = function(e){ws = null;}function closeWs(){console.log('close ws');ws.close();}function send(){console.log('send');var msg = document.getElementById('msg').value;console.log('msg',msg);ws.send(msg);}</script></body>
</html>

socket+websocket相关推荐

  1. socket/WebSocket/WebService/http/https概念

    学习了这么久的java技术, 但是这5个 socket/WebSocket/WebService/http/https  概念还不是很清楚, 总是很模糊,或者是弄混. 惭愧! ! 学习之前, 要对这个 ...

  2. 自定义Udp/Tcp协议,通信协议Socket/WebSocket,IM粘包、分包解决等(2),ProtocolBuffer

    > 自定义Udp/Tcp协议/通信协议(Java/C):自定义构建和解析IM协议消息:IM自定义UDP通信协议   类似于网络通信中的TCPIP协议一般,比较可靠的通信协议往往包含有以下几个组成 ...

  3. socket websocket

    1.websocket客户端 websocket允许通过JavaScript建立与远程服务器的连接,从而实现客户端与服务器间双向的通信.在websocket中有两个方法: 1.send() 向远程服务 ...

  4. Vue里怎么使用socket?(websocket)

    第一步:封装socket.js import { Message } from 'iview';class Socket {constructor (wsurl, binaryType){this.w ...

  5. WebSocket和Socket

    原文:WebSocket和Socket WebSocket和Socket tags:WebSocket和Socket 引言:好多朋友想知道WebSocket和Socket的联系和区别,下面就是你们想要 ...

  6. Socket和Websocket

    Socket和Websocket Socket Socket当初设计的目的就是为了统一同一台计算机中进程之间的通信以及不同计算机进程之间的通信所设计的一个统一的接口.套接字最早是UC Berkeley ...

  7. websocket+php socket实现聊天室

    原文地址:http://www.cnblogs.com/nickbai/articles/6169745.html 这两天用了点时间,研究了一下,用php socket+ websocket实现了一个 ...

  8. websocket 与 socket

    websocket 建连过程: 浏览器.服务器建立TCP连接,三次握手.这是通信的基础,传输控制层,若失败后续都不执行. TCP连接成功后,浏览器通过HTTP协议向服务器传送WebSocket支持的版 ...

  9. Thinkphp5使用workerman、socket、websocket、layui、layim建立即时通讯

    在开始之前,有句话想说,曾经我以为socket会很难入门,所以为了节省时间,使用了ajax轮询的方式,最近项目不是很多,想起来优化一下曾经的项目,就准备引入socket代替ajax轮询,从开始到发出第 ...

最新文章

  1. ocp 工资_【中秋节加班费】2016中秋节加班工资怎么算,中秋节放假加班费的计算方法...
  2. 开发板_Hi3516DV300核心板/开发板;Hi3516EV100+4G+AUDIO RTMP开发板;海思系列开发板/核心板定制开发...
  3. 服务器搬迁方案_数据中心机房改造搬迁IDC机房工程建设
  4. 成年人的样子是什么样子_不只是看样子
  5. 一个WordPress站点绑定多个域名
  6. 阿里云新设浙江猫精人工智能科技有限公司
  7. java url压缩_URL短地址压缩算法 微博短地址原理解析 (Java实现)
  8. Ubuntu 20.04 安装 ModSecurity3.0+Nginx
  9. 10亿级流数据交互查询,为什么抛弃MySQL选择VoltDB?
  10. 字符函数-(学习笔记)
  11. 华中科技大学计算机考纲,华中科技大学硕士研究生入学考试824信号与线性系统考研大纲...
  12. 信息安全工程师 学习笔记 完结
  13. I2C 总线详解-转
  14. eas表单分录带出自定义核算项目
  15. 三菱q系列plc连接电脑步骤_三菱Q系列PLC以太网通信设置方法
  16. 1102: 韩信点兵
  17. [HNOI2007]紧急疏散evacuate
  18. mysql学习记录之创建数据库指定编码
  19. 火遍全网的 ChatGPT,给你的求职新方向
  20. 微软宣布IE进入死亡倒计时 回顾IE传奇的一生

热门文章

  1. IE浏览器之可信任站点
  2. 2023计算机毕业设计SSM最新选题之java企业部门报销管理g9d62
  3. 【机器学习】聚类学习笔记+西瓜书数据集K-means实现
  4. 基于gardner环的定时同步matlab仿真
  5. 如何关闭qq空间以及微信朋友圈广告
  6. matlab音乐键盘模拟,Matlab课程设计报告--MATLAB GUI的音乐键盘仿真
  7. 【计算机毕业设计】541心灵治愈交流平台
  8. ARCore平面与空间点云实现
  9. 项目 1: 预测波士顿房价
  10. 站在31岁,理解程序员年过三十这道坎