解析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 相关文章推荐
上传多个文件的PHP脚本
Nov 26 PHP
windows xp下安装pear
Dec 02 PHP
php中让上传的文件大小在上传前就受限制的两种解决方法
Jun 24 PHP
ThinkPHP模板判断输出Present标签用法详解
Jun 30 PHP
一款简单实用的php操作mysql数据库类
Dec 08 PHP
PHP创建word文档的方法(平台无关)
Mar 29 PHP
PHP使用SOAP扩展实现WebService的方法
Apr 01 PHP
微信支付PHP SDK ―― 公众号支付代码详解
Sep 13 PHP
php表单文件iframe异步上传实例讲解
Jul 26 PHP
PHP将数据导出Excel表中的实例(投机型)
Jul 31 PHP
Yii1.1框架实现PHP极光推送消息通知功能
Sep 06 PHP
PHP的mysqli_sqlstate()函数讲解
Jan 23 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
DOTA2 1月28日更新:监管系统降临刀塔世界
2021/01/28 DOTA
Ajax PHP分页演示
2007/01/02 PHP
thinkphp3.0 模板中函数的使用
2012/11/13 PHP
限制ckeditor上传图片文件大小的方法
2013/11/15 PHP
PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
2014/08/18 PHP
实现php删除链表中重复的结点
2018/09/27 PHP
php获取微信openid方法总结
2019/10/10 PHP
用函数式编程技术编写优美的 JavaScript
2006/11/25 Javascript
常用简易JavaScript函数
2009/04/09 Javascript
select 控制网页内容隐藏于显示的实现代码
2010/05/25 Javascript
『jQuery』名称冲突使用noConflict方法解决
2013/04/22 Javascript
JS简单实现元素复制示例附图
2013/11/19 Javascript
快速掌握Node.js之Window下配置NodeJs环境
2016/03/21 NodeJs
ui组件之input多选下拉实现方法(带有搜索功能)
2016/07/14 Javascript
基于百度地图实现产品销售的单位位置查看功能设计与实现
2016/10/21 Javascript
VueJs与ReactJS和AngularJS的异同点
2016/12/12 Javascript
Bootstrap 3 按钮标签实例代码
2017/02/21 Javascript
实现图片首尾平滑轮播(JS原生方法—节流)
2017/10/17 Javascript
JavaScript引用类型Function实例详解
2018/08/09 Javascript
详解Vue.js使用Swiper.js在iOS
2018/09/10 Javascript
使用vue for时为什么要key【推荐】
2019/07/11 Javascript
Javascript前端下载后台传来的文件流代码实例
2020/08/18 Javascript
浅谈JavaScript 声明提升
2020/09/14 Javascript
Python的Flask框架中实现登录用户的个人资料和头像的教程
2015/04/20 Python
使用OpenCV circle函数图像上画圆的示例代码
2019/12/27 Python
对Tensorflow中Device实例的生成和管理详解
2020/02/04 Python
Python如何用wx模块创建文本编辑器
2020/06/07 Python
大数据分析用java还是Python
2020/07/06 Python
Django数据库迁移常见使用方法
2020/11/12 Python
Python大批量搜索引擎图像爬虫工具详解
2020/11/16 Python
使用Python制作一盏 3D 花灯喜迎元宵佳节
2021/02/26 Python
canvas画布实现手写签名效果的示例代码
2019/04/23 HTML / CSS
Moda Operandi官网:美国奢侈品电商,海淘秀场T台同款
2020/05/26 全球购物
物业公司采购员岗位职责
2013/12/31 职场文书
党的群众路线教育实践活动学习心得体会
2014/03/03 职场文书
土木工程毕业答辩开场白
2015/05/29 职场文书