当前位置: 首页 > 后端技术 > PHP

在PHP服务中使用Websocket

时间:2023-03-29 21:14:44 PHP

WebSocketWebSocket协议诞生于2008年,2011年成为国际标准,所有浏览器都已经支持。它最大的特点是服务端可以主动向客户端推送信息,客户端也可以主动向服务端发送信息。是真正的双向平等对话,属于服务器推送技术的一种。为什么需要WebSocket?需求是:如果用户在页面停留15分钟没有任何操作,会弹出登录窗口让用户重新登录。一般此类需求的实现多为长连接轮询,会造成浏览器卡顿、服务器消耗、维护困难等问题。后来发现websocket这种通信方式主要有以下优点:它是基于TCP协议的,在server端实现起来比较容易。上手不易拦截,可通过各种HTTP代理服务器。数据格式相对轻量级,性能开销小,通信高效。可以发送文本或二进制数据。没有同源限制,客户端可以与任何服务器通信。协议标识符是ws(如果加密则为wss),服务器地址是URL。目标选定了,那么如何实现呢?PHP已经有了一个非常好用的异步网络通信框架swoole,节省了实现websocket服务的时间。我用的是laravel框架,最后选择了laravel-swoole扩展。安装配置引入laravel-swoole扩展包wiki。启用websocket.enabled等相应配置。通过如下命名管理服务非常方便:phpartisanswoole:http{start|stop|restart|reload|infos}修改配置文件中默认的handler配置为自定义类:主要是自定义一些生活中的回调websocket的循环。/*|----------------------------------------------------------------------|onOpen和onClose回调的Websocket处理程序|如果您想自定义您的websocket处理程序,请替换此处理程序|------------------------------------------------------------------------*/'handler'=>\App\Listeners\Swoole\WebsocketHandler::class,/*|--------------------------------------------------------------------------|默认帧解析器|如果您想自定义您的websocket负载,请替换它|------------------------------------------------------------------------*/'parser'=>SwooleTW\Http\Websocket\SocketIO\SocketIOParser::class,配置完成后会在routes目录下添加一个名为websocket.php的文件。就像定义laravel路由一样,定义各种事件非常方便。例如://Websocket::on('open',function($websocket,Request$request){//Log::info('websocket','open111+'.$websocket->getSender());//});////Websocket::on('connect',function($websocket,Request$request){//Log::info('websocket','Connected++222'.$websocket->getSender());////在套接字连接时调用。//});////Websocket::on('disconnect',function($websocket){//Log::info('websocket','Disconnected++333'.$websocket->getSender());////socketondisconnect时调用///});//在UserController的checkLogin方法上会有$websocket和$data两个参数。Websocket::on('loginCheck',"App\Http\Controllers\Api\UserController@checkLogin");Websocket::on('logout',"App\Http\Controllers\Api\UserController@sendLogout");使用控制设备:publicfunctioncheckLogin($websocket,$data){if(empty($data['holding'])){$websocket->emit('message',['code'=>self::HTTP_UNPROCESSABLE_ENTITY,'message'=>"参数错误"]);返回假;}$标志=真;$步骤=1;while($flag){$step++;if(!$this->validateLoginStatus($data['holding'])){$websocket->emit('message',['code'=>self::HTTP_UNAUTHORIZED,'message'=>"登录超时"]);取消设置($步骤);$标志=假;}else{if($step===1){$websocket->emit('message',['code'=>self::HTTP_OK,'message'=>"success"]);}}睡眠(1);}}这里的前端调用一定要注意数据包的结构。在踩到很多陷阱之前,API文档找到了正确的结构:varwebsocket=newWebSocket("ws://127.0.0.1:1215");websocket.onopen=function(evt){console.log("连接到websocketserver");//这里是关键,通道建立后,轮询很方便setInterval(function(){if(websocket.bufferedAmount==0)vardata={"holding":"eyJLQNDqj0y473pCJ6zjMTUyOTk5NzU1MgnVMQ==$d84XkeMCv7umajhMRiU"};监听消息体websocket.onmessage=function(evt){console.log(decodeMessage(evt).data))};//监听关闭消息websocket.onclose=function(evt){console.log("websocketclose");};//监听连接错误信息websocket.onerror=function(evt){console.log(evt);};functiondecodeMessage(str){returnJSON.parse(str.substring(2))[1]||[];}functionencodeMessage(event,data){returnJSON.stringify([事件,data])}Swoole扩展安装因为swoole的安装依赖于php的sockets模块的开启如果安装swoole报错,需要安装以下依赖:yum-yinstallgccpostgresql-develgcc-c++下载swoole扩展源码,按照安装步骤进行安装。性能监控查看当前$netstat-n|awk'/^tcp/{++S[$NF]}END{for(ainS)printa,S[a]}'TIME_WAIT814CLOSE_WAIT1FIN_WAIT11ESTABLISHED634SYN_RECV2LAST_ACK1常用的三种状态是:ESTABLISHED表示通信,TIME_WAIT表示主动关闭,CLOSE_WAIT表示被动关闭。删除进程查看进程数$ps-eaf|grep"swoole"|grep-v“grep”|awk'{print$2}'|wc-l批量删除进程:$ps-eaf|grep"swoole"|grep-v“grep”|awk'{print$2}'|xargskill-9重启服务。参考文章阮一峰WebSocket教程

最新推荐
猜你喜欢