解析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开发需要注意的安全问题
Sep 01 PHP
PHP JSON格式数据交互实例代码详解
Jan 13 PHP
注册页面之前先验证用户名是否存在的php代码
Jul 14 PHP
PHP中UNIX时间戳和日期间的转换与计算实例
Nov 19 PHP
php正则匹配文章中的远程图片地址并下载图片至本地
Sep 29 PHP
php编程中echo用逗号和用点号连接的区别
Mar 26 PHP
PHP排序算法之简单选择排序(Simple Selection Sort)实例分析
Apr 20 PHP
PHP聊天室简单实现方法详解
Dec 08 PHP
PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
Mar 11 PHP
PHP中str_split()函数的用法讲解
Apr 11 PHP
实例分析10个PHP常见安全问题
Jul 09 PHP
tp5 实现列表数据根据状态排序
Oct 18 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中用文本文件做数据库的实现方法
2008/03/27 PHP
php split汉字
2009/06/05 PHP
windows7下安装php的php-ssh2扩展教程
2014/07/04 PHP
CI框架学习笔记(一) - 环境安装、基本术语和框架流程
2014/10/26 PHP
解决jquery的datepicker的本地化以及Today问题
2012/05/23 Javascript
JavaScript的内存释放问题详解
2015/01/21 Javascript
自定义函数实现IE7与IE8不兼容js中trim函数的问题
2015/02/03 Javascript
JavaScript中通过prototype属性共享属性和方法的技巧实例
2015/03/13 Javascript
js编写当天简单日历效果【实现代码】
2016/05/03 Javascript
jQuery实现图片轮播效果代码(基于jquery.pack.js插件)
2016/06/02 Javascript
JQuery页面随滚动条动态加载效果的简单实现(推荐)
2017/02/08 Javascript
javascript 动态生成css代码的两种方法
2017/03/17 Javascript
jfinal与bootstrap的登出实战详解
2017/11/27 Javascript
JS中利用FileReader实现上传图片前本地预览功能
2018/03/02 Javascript
js实现跟随鼠标移动的小球
2019/08/26 Javascript
基于vue、react实现倒计时效果
2019/08/26 Javascript
JS实现移动端双指缩放和旋转方法
2019/12/13 Javascript
微信小程序实现吸顶效果
2020/01/08 Javascript
[05:17]DOTA2誓师:今天我们在这里 明天TI4等我!
2014/03/26 DOTA
Python使用稀疏矩阵节省内存实例
2014/06/27 Python
Python编程入门之Hello World的三种实现方式
2015/11/13 Python
Python工程师面试题 与Python基础语法相关
2016/01/14 Python
Python3内置模块pprint让打印比print更美观详解
2019/06/02 Python
python实现大文本文件分割
2019/07/22 Python
Python closure闭包解释及其注意点详解
2019/08/28 Python
python实现AdaBoost算法的示例
2020/10/03 Python
pycharm配置QtDesigner的超详细方法
2021/01/25 Python
荷兰最大的儿童服装店:The Kids Republic
2019/04/13 全球购物
巴西独家产品和现场演示购物网站:Shoptime
2019/07/11 全球购物
德国咖啡批发商:Coffeefair
2019/08/26 全球购物
预备党员转正思想汇报
2014/01/12 职场文书
社区安全检查制度
2014/02/03 职场文书
中学生操行评语
2014/04/24 职场文书
爱护环境建议书
2015/09/14 职场文书
漫画「你在春天醒来」第10卷封面公开
2022/03/21 日漫
win server2012 r2服务器共享文件夹如何设置
2022/06/21 Servers