解析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 相关文章推荐
一个改进的UBB类
Oct 09 PHP
PHP中防止SQL注入攻击和XSS攻击的两个简单方法
Apr 15 PHP
将博客园(cnblogs.com)数据导入到wordpress的代码
Jan 06 PHP
PHP+Mysql+Ajax+JS实现省市区三级联动
May 23 PHP
ThinkPHP框架设计及扩展详解
Nov 25 PHP
phpQuery让php处理html代码像jQuery一样方便
Jan 06 PHP
你应该知道PHP浮点数知识
May 13 PHP
Yii2针对指定url的生成及图片等的引入方法小结
Jul 18 PHP
PHP目录操作实例总结
Sep 27 PHP
支付宝支付开发――当面付条码支付和扫码支付实例
Nov 04 PHP
解析 thinkphp 框架中的部分方法
May 07 PHP
laravel 使用auth编写登录的方法
Sep 30 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
PHP实现文件安全下载
2006/10/09 PHP
复杂检索数据并分页显示的处理方法
2006/10/09 PHP
我的论坛源代码(一)
2006/10/09 PHP
PHP项目开发中最常用的自定义函数整理
2010/12/02 PHP
PHP模拟http请求的方法详解
2016/11/09 PHP
thinkphp框架类库扩展操作示例
2019/11/26 PHP
麦鸡的TAB切换功能结合了javascript和css
2007/12/17 Javascript
谈谈jQuery Ajax用法详解
2015/11/27 Javascript
jQuery查看选中对象HTML代码的方法
2016/06/17 Javascript
Bootstrap表单布局样式源代码
2016/07/04 Javascript
老生常谈原生JS执行环境与作用域
2016/11/22 Javascript
jQuery简易时光轴实现方法示例
2017/03/13 Javascript
JavaScript数据结构之二叉树的计数算法示例
2017/04/13 Javascript
在Vue项目中使用d3.js的实例代码
2018/05/01 Javascript
nodejs文件夹深层复制功能
2019/09/03 NodeJs
小程序使用分包的示例代码
2020/03/23 Javascript
详解JavaScript中new操作符的解析和实现
2020/09/04 Javascript
vue3.0搭配.net core实现文件上传组件
2020/10/29 Javascript
[02:08:58]2014 DOTA2国际邀请赛中国区预选赛 Ne VS CIS
2014/05/22 DOTA
[42:25]EG vs Spirit Supermajor 败者组 BO3 第二场 6.4
2018/06/05 DOTA
[02:04]完美世界城市挑战赛秋季赛报名开始 谁是solo路人王?
2019/10/10 DOTA
深入浅析Python的类
2018/06/22 Python
python 循环数据赋值实例
2019/12/02 Python
使用python快速实现不同机器间文件夹共享方式
2019/12/22 Python
tensorflow自定义激活函数实例
2020/02/04 Python
Python 字典中的所有方法及用法
2020/06/10 Python
Python装饰器结合递归原理解析
2020/07/02 Python
Django视图类型总结
2021/02/17 Python
实例教程 纯CSS3打造非常炫的加载动画效果
2014/11/05 HTML / CSS
html5 canvas绘制放射性渐变色效果
2018/01/04 HTML / CSS
德国黑胶唱片、街头服装及运动鞋网上商店:HHV
2018/08/24 全球购物
自我评价范文
2013/12/22 职场文书
银行员工犯错检讨书
2014/09/16 职场文书
西双版纳导游词
2015/02/03 职场文书
中学生自我评价2015
2015/03/03 职场文书
2015年国庆晚会主持词
2015/07/01 职场文书