使用场景公司原有业务消息推送由前端ajax圆眉请求后端接口完成。那我新来的,让我换成websocket双向通信进行消息推送。业务场景=>PC浏览器打开后台系统后,如果有业务订单,会时时推送到PC,PC时时进行语音播报。安装框架的步骤composercreate-projecthyperf/hyperf-skeleton【注意一定要符合框架的环境,安装】安装websocketserver的composer安装包1.`composerrequirehyperf/websocket-server`安装websocket客户端,安装的原因是http请求后,websocket客户端直接与websocket服务器建立连接,然后推送消息。1.`composerrequirehyperf/websocket-client`修改config文件中的server.php配置文件。有时,配置文件不存在,需要手动创建。1.server.php配置文件代码:server.php配置文件代码【改成自己的端口号】SWOOLE_PROCESS,'servers'=>[['name'=>'http','type'=>Server::SERVER_HTTP,'host'=>'0.0.0.0','port'=>8098,'sock_type'=>SWOOLE_SOCK_TCP,'callbacks'=>[SwooleEvent::ON_REQUEST=>[Hyperf\\HttpServer\\Server::class,'onRequest'],],],['name'=>'ws','type'=>Server::SERVER\_WEBSOCKET,'host'=>'0.0.0.0','port'=>8099,'sock_type'=>SWOOLE_SOCK_TCP,'回调'=>[SwooleEvent::ON_HAND_SHAKE=>[Hyperf\\WebSocketS服务器\\Server::class,'onHandShake'],SwooleEvent::ON_MESSAGE=>[Hyperf\\WebSocketServer\\Server::class,'onMessage'],SwooleEvent::ON_CLOSE=>[Hyperf\\WebSocketServer\\Server::class,'onClose'],],],],'settings'=>['enable_coroutine'=>true,'worker_num'=>swoole_cpu_num(),'pid_file'=>BASE_PATH。'/runtime/hyperf.pid','open_tcp_nodelay'=>true,'max_coroutine'=>100000,'open_http2\_protocol'=>true,'max_request'=>100000,'socket_buffer_size'=>2*1024*1024,],'callbacks'=>[SwooleEvent::ON_BEFORE_START=>[Hyperf\\Framework\\Bootstrap\\ServerStartCallback::class,'beforeStart'],SwooleEvent::ON_WORKER_START=>[Hyperf\\Framework\\Bootstrap\\WorkerStartCallback::class,'onWorkerStart'],SwooleEvent::ON_PIPE_MESSAGE=>[Hyperf\\Framework\\Bootstrap\\PipeMessageCallback::class,'onPipeMessage'],],];api和websocketserver链接的路由代码,routes.php替换成对应的controller和methodwebsocketserver代码VoiceBroadcastWebSocketController.phpredis=$container->get(\Redis::class);$this->logger=$loggerFactory->get('log','default');}//onmessage方法接收客户端或服务器消息publicfunctiononMessage(WebSocketServer$server,Frame$frame):void{$recvData=json_decode($frame->data);如果(!is_object($recvData)){$this->checkData($frame->data,$frame->fd);}else{$this->sendData($server,$frame->data,$frame->fd);}}/***检查数据*@param$string*@param$fd*@returnstring*/functioncheckData($string,$fd){if(!is_string($string)){$this->logger->error('字符串类型错误');返回'??字符串类型错误';}$海峡rray=explode('_',$string);$shopIds=json_decode($string[1],true);if(!is_array($shopIds)||empty($shopIds)){$this->logger->error('参数错误');返回'参数错误';}echo"Allmappedsuccessfully"}/***发送消息到PC*/publicfunctionsendData($server,$sendData,$fd){$recvData=json_encode($sendData,true);$uid=$recvData['uid'];$data=$recvData['数据'];$fdsArr=$this->redis->sMembers('jiayouwa:websocket:voiceSet_'.$uid);echo'voiceSet_'.$uid;$data=['result'=>true,'code'=>0,'msg'=>'操作成功','data'=>$data,];if(count($fdsArr)){foreach($fdsArras$key=>$value){try{$server->push(intval($value),json_encode($data));echo"线程:$fd向线程$value发送消息\\n";}catch(\\Throwable$e){//增加重试次数$this->service->push($recvData,1);//删除数据$this->redis->sRem('jiayouwa:websocket:voiceSet_'.$uid,$value);继续;}}}}publicfunctiononClose(Server$server,int$fd,int$reactorId):void{echo"$fd\-closed\\n";}publicfunctiononOpen(WebSocketServer$server,Request$request):void{echo"Thread:$request\->fd\-open\\n";}}http客户端链接websocket文件VoiceBroadcastController.php/***设备发送数据**@paramVoiceBroadcastRequest$request*@paramResponseInterface$response*@return\\Psr\\Http\\Message\\ResponseInterface*/publicfunctionvoiceBroadcast(VoiceBroadcastRequest$request,ResponseInterface$response){$serviceType=$request->input('service_type',0);}$name=$request->input('name','');$商店NameId=$request->input('shop_name_id',0);//判断redis中存在$fdsArr=$this->redis->sMembers('jiayouwa:websocket:voiceSet_'.$shopNameId);if(!count($fdsArr)){return$this->returnSuccess([],true,0,'shop_name_id不存在');}$data=['uid'=>$shopNameId,'service'=>'voiceBroadcast','data'=>array(array('service_type'=>$serviceType,'name'=>$name,),),];//向webSocket发送数据$this->connectWebSocket($data);返回$this->returnSuccess();}/***连接websocket并发送数据*@param$data*@returnarray*/publicfunctionconnectWebSocket($data){$client=$this->clientFactory->create($this->webSocketIp);$client->push(json_encode($data));}PC端请求websocket代码注意用hyperf框架实现太简单了,下载websocket客户端和服务端composer包即可。如果要实现点对点的消息推送,只需要在fd进程中将你的uid映射到redis的key=>value即可。如果要实现一次推送到多台PC,设置uid=>[1,2,3,4,5]使用redis集合类型即可。代码仅供参考。如果您有任何问题,请发表评论。文章的写作今年才开始,文笔不好。请多多包涵。Hyperf框架地址:https://doc.hyperf.io/#/
