解析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 相关文章推荐
用Flash图形化数据(一)
Oct 09 PHP
杏林同学录(五)
Oct 09 PHP
增加反向链接的101个方法 站长推荐
Jan 31 PHP
PHP session常见问题集锦及解决办法总结
Mar 18 PHP
php自动获取关键字的方法
Jan 06 PHP
php模拟登陆的实现方法分析
Jan 09 PHP
php实现对两个数组进行减法操作的方法
Apr 17 PHP
php中关于socket的系列函数总结
May 18 PHP
PHP利用超级全局变量$_POST来接收表单数据的实例
Nov 05 PHP
phpmailer绑定邮箱的实现方法
Dec 01 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
Mar 27 PHP
PHP连接MySQL数据库操作代码实例解析
Jul 11 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
收音机频率指针指示不准确和灵敏度低问题
2021/03/02 无线电
屏蔽机器人从你的网站搜取email地址的php代码
2012/11/14 PHP
PHP 提取图片img标记中的任意属性的简单实例
2013/12/10 PHP
老生常谈php 正则中的i,m,s,x,e分别表示什么
2017/03/02 PHP
Aster vs KG BO3 第二场2.19
2021/03/10 DOTA
ExtJS扩展 垂直tabLayout实现代码
2009/06/21 Javascript
jquery 简单图片导航插件jquery.imgNav.js
2010/03/17 Javascript
jQuery 核心函数以及jQuery对象
2010/03/23 Javascript
Javascript实现简单二级下拉菜单实例
2014/06/15 Javascript
实现js保留小数点后N位的代码
2014/11/13 Javascript
基于jQuery实现点击最后一行实现行自增效果的表格
2016/01/12 Javascript
JS添加或修改控件的样式(Class)实现方法
2016/10/15 Javascript
js返回顶部实例分享
2016/12/21 Javascript
常用的javascript设计模式
2017/01/11 Javascript
jQuery基于Ajax方式提交表单功能示例
2017/02/10 Javascript
关于jQuery EasyUI 中刷新Tab选项卡后一个页面变形的解决方法
2017/03/02 Javascript
Vue实现带进度条的文件拖动上传功能
2018/02/23 Javascript
vuex中的 mapState,mapGetters,mapActions,mapMutations 的使用
2018/04/13 Javascript
Vue实现购物车详情页面的方法
2019/08/20 Javascript
JavaScript 严格模式(use strict)用法实例分析
2020/03/04 Javascript
ant design vue中日期选择框混合时间选择器的用法说明
2020/10/27 Javascript
[01:55]《走出家门看比赛》——DOTA2 2015国际邀请赛同城线下观战
2015/07/18 DOTA
Django使用模板后无法找到静态资源文件问题解决
2019/07/19 Python
python使用minimax算法实现五子棋
2019/07/29 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
2019/08/27 Python
Pytorch之Tensor和Numpy之间的转换的实现方法
2020/09/03 Python
Html5 canvas画图白板踩坑
2020/06/01 HTML / CSS
韩国现代百货官网:Hmall
2018/03/21 全球购物
Expedia西班牙:预订酒店、机票、旅行和廉价度假套餐
2019/04/10 全球购物
英国电信商店:BT Shop
2019/12/17 全球购物
期中考试复习计划
2015/01/19 职场文书
学习焦裕禄观后感
2015/06/09 职场文书
跳高加油稿
2015/07/21 职场文书
幼儿园语言教学反思
2016/02/23 职场文书
制作能在nginx和IIS中使用的ssl证书
2021/06/21 Servers
世界十大儿童漫画书排名,法国国宝漫画排第五,第二是轰动日本连环
2022/03/18 欧美动漫