解析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 什么是PEAR?(第二篇)
Mar 19 PHP
PHP采集相关教程之一 CURL函数库
Feb 15 PHP
win2003服务器使用WPS的COM组件的一些问题解决方法
Jan 11 PHP
smarty基础之拼接字符串的详解
Jun 18 PHP
关于PHP内存溢出问题的解决方法
Jun 25 PHP
php5.3 注意事项说明
Jul 01 PHP
使用PHP Socket 编程模拟Http post和get请求
Nov 25 PHP
php中引用符号(&amp;)的使用详细介绍
Dec 06 PHP
Yii CFileCache 获取不到值的原因分析
Feb 08 PHP
浅谈PHP中类和对象的相关函数
Apr 26 PHP
PHP实现模拟http请求的方法分析
Dec 20 PHP
PHP实现无限极分类的两种方式示例【递归和引用方式】
Mar 25 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
PHP5中使用PDO连接数据库的方法
2010/08/01 PHP
PHP中通过HTTP_USER_AGENT判断是否为手机移动终端的函数代码
2013/02/14 PHP
PHP面向对象程序设计类的定义与用法简单示例
2016/12/27 PHP
利用PHP判断文件是否为图片的方法总结
2017/01/06 PHP
[原创]php token使用与验证示例【测试可用】
2017/08/30 PHP
JavaScript 基础篇(一)
2012/03/30 Javascript
使用js解决由border属性引起的div宽度问题
2013/11/26 Javascript
Node.js中的流(Stream)介绍
2015/03/30 Javascript
JavaScritp添加url参数并将参数加入到url中及更改url参数的方法
2015/10/26 Javascript
jQuery+ajax的资源回收处理机制分析
2017/01/07 Javascript
jQuery实现标签页效果实战(4)
2017/02/08 Javascript
微信小程序 sha1 实现密码加密实例详解
2017/07/06 Javascript
react-native-fs实现文件下载、文本存储的示例代码
2017/09/22 Javascript
vue.js todolist实现代码
2017/10/29 Javascript
javascript实现数字配对游戏的实例讲解
2017/12/14 Javascript
vue首次赋值不触发watch的解决方法
2018/09/11 Javascript
vue-cli3+typescript初体验小结
2019/02/28 Javascript
JS实现继承的几种常用方式示例
2019/06/22 Javascript
react结合bootstrap实现评论功能
2020/05/30 Javascript
Vue + element 实现多选框组并保存已选id集合的示例代码
2020/06/03 Javascript
nodeJs项目在阿里云的简单部署
2020/11/27 NodeJs
[01:03:38]2014 DOTA2国际邀请赛中国区预选赛5.21 CNB VS CIS
2014/05/22 DOTA
[01:59]翻天覆地,因你而变,7.20版本地图更新速览
2018/11/24 DOTA
浅谈python requests 的put, post 请求参数的问题
2019/01/02 Python
Django 权限认证(根据不同的用户,设置不同的显示和访问权限)
2019/07/24 Python
python GUI库图形界面开发之PyQt5菜单栏控件QMenuBar的详细使用方法与实例
2020/02/28 Python
HTML5 Canvas API中drawImage()方法的使用实例
2016/03/25 HTML / CSS
仓管员岗位职责范文
2013/11/08 职场文书
影视制作岗位职责
2013/12/04 职场文书
2014年两会学习心得体会
2014/03/10 职场文书
二手车交易协议书标准版
2014/11/16 职场文书
2014年新农村建设工作总结
2014/12/01 职场文书
专项资金申请报告
2015/05/15 职场文书
技能培训通讯稿
2015/07/18 职场文书
k-means & DBSCAN 总结
2021/04/27 Python
idea编译器vue缩进报错问题场景分析
2021/07/04 Vue.js