解析laravel使用workerman用户交互、服务器交互


Posted in PHP onApril 28, 2021

一、安装workerman

composer require workerman/workerman

二、生成命令文件

php artisan make:command Workerman

修改文件

<?php
namespace App\Console\Commands;use Illuminate\Console\Command;use Workerman\Worker;class Workerman extends Command{
    protected $signature = 'Workerman {action} {--daemonize}';
    protected $description = 'Command description';
    public function __construct()
    {
        parent::__construct();
    }
    public function handle()
    {
        global $argv;//定义全局变量
        $arg = $this->argument('action');
        $argv[1] = $arg;
        $argv[2] = $this->option('daemonize') ? '-d' : '';//该参数是以daemon(守护进程)方式启动

        global $text_worker;
        // 创建一个Worker监听2345端口,使用websocket协议通讯
        $text_worker = new Worker("websocket://0.0.0.0:2345");
        $text_worker->uidConnections = array();//在线用户连接对象
        $text_worker->uidInfo = array();//在线用户的用户信息
        // 启动4个进程对外提供服务
        $text_worker->count = 4;
        //当启动workerman的时候 触发此方法
        $text_worker->onWorkerStart =function(){

        };
        //当浏览器连接的时候触发此函数
        $text_worker->onConnect = function($connection){

        };
        //向用户发送信息的时候触发
        //$connection 当前连接的人的信息 $data 发送的数据
        $text_worker->onMessage = function($connection,$data){

        };
        //浏览器断开链接的时候触发
        $text_worker->onClose = function($connection){};
    }}

三、启动命令

$ php artisan Workerman start --daemonize
Deprecated: Directive 'track_errors' is deprecated in Unknown on line 0----------------------- WORKERMAN -----------------------------Workerman version:4.0.19          PHP version:7.2.9------------------------ WORKERS -------------------------------worker               listen                              processes status
none                 websocket://0.0.0.0:2345            4         [ok]

四、浏览器之间通信

1. HTML代码 两个html做交互
var socket = new WebSocket("ws://localhost:2345//ws");
         // 建立连接时触发 建立链接的时候,需要向workerman发送一条指令,告诉他我是谁,使用id或者用户标识作为uid,告诉workerman 例如,当前html 用户id是37
         socket.onopen = function(event) {
            console.log('连接开始...');
            socket.send('{"uid":36,"type":'login'}');
         }
         //workerman发送消息的时候,接收并打印
         socket.onmessage = function(event) {
            var msg = event.data;
            console.log(msg );
         }
2. 设置uid

浏览器发来了用户uid,需要workerman保留一下,网上有文档说在触发的时候保存,还有用session的,我试验了没成功,所有用浏览器建立链接的时候,向workerman发送一条信息来创建uid,在workerman上接收一下

//$connection 当前连接的人的信息 $data 发送的数据$text_worker->onMessage = function($connection,$data){
      $data = json_decode($data);
      if($data['type']=='login'){
         $this->create_uid($connection,$data);
      }};//创建uid方法
 public function create_uid($connection,$data){
        global $text_worker;
        $connection->uid = $data['uid'];
        //保存用户的uid
        $text_worker->uidConnections["{$connection->uid}"] = $connection;
        //向自己的浏览器返回创建成功的信息
        $connection->send("用户:[{$connection->uid}] 创建成功");
    }

这时候浏览器就会出现打印信息

3. 向其他用户发送信息

向用户是37的浏览器发送信息

//js代码
 socket.send('{"type":"login","to_uid":36,"uid":36,"message":"nihao"}');
 //workerman 
 //$connection 当前连接的人的信息 $data 发送的数据
        $text_worker->onMessage = function($connection,$data){
            $data = json_decode($data,true);
            var_dump($data);
            if($data['type']=='login'){
                $this->create_uid($connection,$data);
            }
            if($data['type']=='send_message'){
                $this->send_message($connection,$data);
            }
        };
        public function send_message($connection,$data){
            global $text_worker;
            if(isset($data['to_uid'])){
            var_dump($data['to_uid']);
            if(isset($text_worker->uidConnections["{$data['to_uid']}"])){
                $to_connection=$text_worker->uidConnections["{$data['to_uid']}"];
                $to_connection->send($data['uid'].$data['message']);
            }
        }
    }

五、服务器向浏览器通信

1. workeman监听一个本地发送的端口,在启动的时候
//当启动workerman的时候 触发此方法
        $text_worker->onWorkerStart =function(){
            //监听一个内部端口,用来接收服务器的消息,转发给浏览器
            $inner_text_worker = new Worker('Text://127.0.0.1:5678');
            $inner_text_worker->onMessage = function($connection_admin, $data)
            {
                global $text_worker;
                // $data数组格式,里面有uid,表示向那个uid的页面推送数据
                $data = json_decode($data, true);
                var_dump($data);
                $to_uid = $data['to_uid'];
                var_dump($to_uid);
                // 通过workerman,向uid的页面推送数据
                // $ret = sendMessageByUid($uid, $buffer);
                $connection = $text_worker->uidConnections[$to_uid];
                $connection->send($buffer);
                // 返回推送结果
                $connection_admin->send(true ? 'ok' : 'fail');
            };
            $inner_text_worker->listen();
        };//控制器代码class TestController extends Controller{
    public function send(){
        $client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
        // 推送的数据,包含用户,表示是给这个用户推送
        $data = array('uid'=>37,'group'=>'admin', 'message'=>'发送成功啦');
        // 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符
        fwrite($client, json_encode($data)."\n");}}

 

PHP 相关文章推荐
PHP5在Apache下的两种模式的安装
Sep 05 PHP
PHP中usort在值相同时改变原始位置问题的解决方法
Nov 27 PHP
Php中文件下载功能实现超详细流程分析
Jun 13 PHP
php获取目录所有文件并将结果保存到数组(实例)
Oct 25 PHP
smarty模板判断数组为空的方法
Jun 10 PHP
WordPress迁移时一些常见问题的解决方法整理
Nov 24 PHP
高质量PHP代码的50个实用技巧必备(下)
Jan 22 PHP
php简单统计中文个数的方法
Sep 30 PHP
php从身份证获取性别和出生年月
Feb 09 PHP
Thinkphp5 微信公众号token验证不成功的原因及解决方法
Nov 12 PHP
Ajax中的JSON格式与php传输过程全面解析
Nov 14 PHP
thinkphp3.2同时连接两个数据库的简单方法
Aug 13 PHP
PHP实现创建以太坊钱包转账等功能
Apr 21 #PHP
如何使用php生成zip压缩包
Apr 21 #PHP
PHP使用非对称加密算法RSA
laravel ajax curd 搜索登录判断功能的实现
thinkphp 获取控制器及控制器方法
Apr 16 #PHP
PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
PHP实现考试倒计时功能代码
Apr 16 #PHP
You might like
德生H-501的评价与改造
2021/03/02 无线电
如何使用PHP获取网络上文件
2006/10/09 PHP
php统计数组不同元素的个数的实例方法
2019/09/26 PHP
laravel 框架执行流程与原理简单分析
2020/02/01 PHP
利用location.hash实现跨域iframe自适应
2010/05/04 Javascript
用JQuery模仿淘宝的图片放大镜显示效果
2011/09/15 Javascript
js setTimeout opener的用法示例详解
2013/10/23 Javascript
Javascript优化技巧之短路表达式详细介绍
2015/03/27 Javascript
JavaScript SHA512&amp;SHA256加密算法详解
2015/08/11 Javascript
javascript中异常处理案例(推荐)
2016/10/03 Javascript
bootstrap日历插件datetimepicker使用方法
2016/12/14 Javascript
详解AngularJS ng-class样式切换
2017/06/27 Javascript
vue中锚点的三种方法
2018/07/06 Javascript
JavaScript设计模式之单例模式原理与用法实例分析
2018/07/26 Javascript
详解element-ui中form验证杂记
2019/03/04 Javascript
基于Vue的侧边目录组件的实现
2020/02/05 Javascript
Python入门篇之对象类型
2014/10/17 Python
详解Python中内置的NotImplemented类型的用法
2015/03/31 Python
Python自定义scrapy中间模块避免重复采集的方法
2015/04/07 Python
Python实现包含min函数的栈
2016/04/29 Python
浅谈配置OpenCV3 + Python3的简易方法(macOS)
2018/04/02 Python
Python爬虫包BeautifulSoup异常处理(二)
2018/06/17 Python
django orm 通过related_name反向查询的方法
2018/12/15 Python
Python logging模块异步线程写日志实现过程解析
2020/06/30 Python
python爬虫用request库处理cookie的实例讲解
2021/02/20 Python
北美三大旅游网站之一:Travelocity
2017/08/12 全球购物
一份Java笔试题
2012/02/21 面试题
投标邀请书范文
2014/01/31 职场文书
金融管理专业求职信
2014/07/10 职场文书
班级活动总结格式
2014/08/30 职场文书
领导班子遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
一份教室追逐打闹的检讨书
2014/09/27 职场文书
建筑专业毕业生求职信
2014/09/30 职场文书
六一晚会主持词开场白
2015/05/28 职场文书
Python基于Opencv识别两张相似图片
2021/04/25 Python
springboot集成flyway自动创表的详细配置
2021/06/26 Java/Android