解析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 相关文章推荐
sqlyog 中文乱码问题的设置方法
Oct 19 PHP
PHP中return 和 exit 、break和contiue 区别与用法
Apr 09 PHP
php设计模式之命令模式的应用详解
May 21 PHP
PHP Class&amp;Object -- 解析PHP实现二叉树
Jun 25 PHP
php上传文件,创建递归目录的实例代码
Oct 18 PHP
PHP使用Alexa API获取网站的Alexa排名例子
Jun 12 PHP
PHP邮件群发机实现代码
Feb 16 PHP
简单理解PHP的面向对象编程方式
May 17 PHP
Yii支持多域名cors原理的实现
Dec 05 PHP
php多进程模拟并发事务产生的问题小结
Dec 07 PHP
laravel实现Auth认证,登录、注册后的页面回跳方法
Sep 30 PHP
php解析非标准json、非规范json的方式实例
May 10 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
我的论坛源代码(三)
2006/10/09 PHP
配置Apache2.2+PHP5+CakePHP1.2+MySQL5运行环境
2009/04/25 PHP
PHP中的错误处理、异常处理机制分析
2012/05/07 PHP
PHP函数checkdnsrr用法详解(Windows平台用法)
2016/03/21 PHP
Yii2中简单的场景使用介绍
2017/06/02 PHP
PHP经典设计模式之依赖注入定义与用法详解
2019/05/21 PHP
关于js中window.location.href,location.href,parent.location.href,top.location.href的用法与区别
2010/10/18 Javascript
用jquery生成二级菜单的实例代码
2013/06/24 Javascript
自定义jquery模态窗口插件无法在顶层窗口显示问题
2014/05/29 Javascript
使用jquery解析XML的方法
2014/09/05 Javascript
JavaScript SHA512&amp;SHA256加密算法详解
2015/08/11 Javascript
Angularjs处理页面闪烁的解决方法
2017/03/09 Javascript
详解Vue.js 2.0 如何使用axios
2017/04/21 Javascript
jQuery实现的文字逐行向上间歇滚动效果示例
2017/09/06 jQuery
浅谈node模块与npm包管理工具
2018/01/03 Javascript
详解Angular6 热加载配置方案
2018/08/18 Javascript
mpvue性能优化实战技巧(小结)
2019/04/17 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
2019/07/10 jQuery
vue实现输入框自动跳转功能
2020/05/20 Javascript
uniapp电商小程序实现订单30分钟倒计时
2020/11/01 Javascript
[02:54]DOTA2英雄基础教程 撼地者
2014/01/14 DOTA
Python读取mp3中ID3信息的方法
2015/03/05 Python
Python利用前序和中序遍历结果重建二叉树的方法
2016/04/27 Python
Swift中的协议(protocol)学习教程
2016/07/08 Python
Python实现PS图像明亮度调整效果示例
2018/01/23 Python
python tensorflow学习之识别单张图片的实现的示例
2018/02/09 Python
Python 脚本获取ES 存储容量的实例
2018/12/27 Python
django框架自定义模板标签(template tag)操作示例
2019/06/24 Python
文件上传服务器-jupyter 中python解压及压缩方式
2020/04/22 Python
Python参数传递及收集机制原理解析
2020/06/05 Python
新手常见Python错误及异常解决处理方案
2020/06/18 Python
布局和排版教程 纯css3实现图片三角形排列
2014/10/17 HTML / CSS
Html5 APP中监听返回事件处理的方法示例
2018/03/15 HTML / CSS
什么是TCP/IP
2014/07/27 面试题
合同范本之电脑出租
2019/08/13 职场文书
中国现代文学之经典散文三篇
2019/09/18 职场文书