返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >laravel与workerman结合
  • 889
分享到

laravel与workerman结合

laravelphp服务器 2023-09-04 17:09:50 889人浏览 八月长安
摘要

安装workerman composer require workerman/workerman 生成命令 PHP artisan make:command Workerman

安装workerman

composer require workerman/workerman

生成命令

PHP artisan make:command Workerman
phpnamespace 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监听2347端口,使用websocket协议通讯        $text_worker = new Worker("WEBSocket://0.0.0.0:2347");        $text_worker->uidConnections = array();//在线用户连接对象        $text_worker->uidInfo = array();//在线用户的用户信息        // 启动1个进程对外提供服务,这里设置多个进程在服务端发送客户端时会有问题        $text_worker->count = 1;        //当启动workerman的时候 触发此方法        $text_worker->onWorkerStart =function(){                    };        //当浏览器连接的时候触发此函数        $text_worker->onConnect = function($connection){        };        //向用户发送信息的时候触发        //$connection 当前连接的人的信息 $data 发送的数据        $text_worker->onMessage = function($connection,$data){                    };        //浏览器断开链接的时候触发        $text_worker->onClose = function($connection){};        Worker::runAll();    }}

修改文件

App\Console\Kernel
这样就可以运行:php artisan Workerman start 命令

    protected $commands = [        Commands\Workerman::class,    ];

启动命令

# php artisan Workerman startWorkerman[artisan] start in DEBUG mode------------------------------------------- WORKERMAN --------------------------------------------Workerman version:4.1.6          PHP version:8.0.18           Event-Loop:\Workerman\Events\Select-------------------------------------------- WORKERS ---------------------------------------------proto   user            worker          listen                      processes    status           tcp     root            none            websocket://0.0.0.0:2347    1             [OK]            --------------------------------------------------------------------------------------------------

浏览器之间通信

后端

//$connection 当前连接的人的信息 $data 发送的数据$text_worker->onMessage = function($connection,$data){     $data = JSON_decode($data, true);     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}] 创建成功");}

打开两个新的页面、打开控制台选择 Console

// 第一个页面var socket = new WebSocket("ws://127.0.0.1:2347//ws");// 建立连接时触发 建立链接的时候,需要向workerman发送一条指令,告诉他我是谁,使用id或者用户标识作为uid,告诉workerman 例如,当前html 用户id是36socket.onopen = function(event) {   console.log('连接开始...');   socket.send('{"uid":36,"type":"login"}');}//workerman发送消息的时候,接收并打印socket.onmessage = function(event) {   var msg = event.data;   console.log(msg );}//第二个页面var socket = new WebSocket("ws://127.0.0.1:2347//ws");// 建立连接时触发 建立链接的时候,需要向workerman发送一条指令,告诉他我是谁,使用id或者用户标识作为uid,告诉workerman 例如,当前html 用户id是37socket.onopen = function(event) {   console.log('连接开始...');   socket.send('{"uid":37,"type":"login"}');}//workerman发送消息的时候,接收并打印socket.onmessage = function(event) {   var msg = event.data;   console.log(msg );}

在这里插入图片描述


向其他用户发送信息
后端

$text_worker->onMessage = function($connection,$data){    $data = json_decode($data, true);    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']);        }    }}

页面,在uid为37的worker下

socket.send('{"type":"send_message","to_uid":36,"uid":37,"message":"nihao"}');

在这里插入图片描述

服务器向浏览器通信

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的页面推送数据        $buffer = json_decode($data, true);        var_dump($buffer);        $to_uid = $buffer['to_uid'];        var_dump($to_uid);                // 通过workerman,向uid的页面推送数据        $connection = $text_worker->uidConnections[$to_uid];        $ret = $connection->send($data);        // 返回推送结果        $connection_admin->send($ret ? 'ok' : 'fail');    };    $inner_text_worker->listen();};Route::get('/', function () {    $client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);    // 推送的数据,包含用户,表示是给这个用户推送    $data = array ('uid'=>37,'group'=>'admin', 'message'=>'发送成功啦', 'to_uid'=>36);     // 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符    fwrite($client, json_encode($data)."\n");        echo fread($client, 8192);});

在这里插入图片描述

添加心跳的完整代码

namespace App\Console\Commands;use Illuminate\Console\Command;use Workerman\Worker;use Workerman\Timer;// 心跳间隔55秒define('HEARTBEAT_TIME', 55);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:2347");        $text_worker->uidConnections = array();//在线用户连接对象        $text_worker->uidInfo = array();//在线用户的用户信息        // 启动4个进程对外提供服务        $text_worker->count = 1;        //当启动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的页面推送数据                $buffer = json_decode($data, true);                //var_dump($buffer);                $to_uid = $buffer['to_uid'];                //var_dump($to_uid);    // 通过workerman,向uid的页面推送数据                if(isset($text_worker->uidConnections[$to_uid])){                    $connection = $text_worker->uidConnections[$to_uid];                    $ret = $connection->send($data);                } else {                    var_dump($to_uid . ': not define');                    $ret = false;                }                // 返回推送结果                $connection_admin->send($ret ? 'ok' : 'fail');            };                        $inner_text_worker->listen();                        // 进程启动后设置一个每10秒运行一次的定时器            Timer::add(10, function(){                global $text_worker;                $time_now = time();                foreach($text_worker->connections as $connection) {                    // 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间                    if (empty($connection->lastMessageTime)) {                        $connection->lastMessageTime = $time_now;                        continue;                    }                    // 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接                    if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {                        var_dump("delete:" . $connection->uid);                        unset($text_worker->uidConnections["{$connection->uid}"]);                        $connection->close();                    }                }            });        };        //当浏览器连接的时候触发此函数        $text_worker->onConnect = function($connection){        };        //向用户发送信息的时候触发        //$connection 当前连接的人的信息 $data 发送的数据        $text_worker->onMessage = function($connection,$data){        // 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间    $connection->lastMessageTime = time();    // 其它业务逻辑...            $data = json_decode($data, true);            if($data['type']=='login'){                $this->create_uid($connection,$data);            }            if($data['type']=='send_message'){                $this->send_message($connection,$data);            }        };        //浏览器断开链接的时候触发        $text_worker->onClose = function($connection){};        Worker::runAll();    }        //创建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}] 创建成功");    }        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']);            }        }    }}

测试数据库连接

use Workerman\Worker;use Workerman\Connection\TcpConnection;require_once __DIR__ . '/vendor/autoload.php';$worker = new Worker('Http://0.0.0.0:2345');$worker->onWorkerStart = function($worker){    // 将db实例存储在全局变量中(也可以存储在某类的静态成员中)    global $db;    $db = new \Workerman\Mysql\Connection(        '127.0.0.1',//host        '3306',//port        'test_db',//user        '***',//passWord        'test_db'//db_name    );};$worker->onMessage = function(TcpConnection $connection, $data){    // 通过全局变量获得db实例    global $db;    // 执行sql    $all_tables = $db->query('show tables');    $connection->send(json_encode($all_tables));};// 运行workerWorker::runAll();

来源地址:https://blog.csdn.net/believer_li/article/details/129179586

--结束END--

本文标题: laravel与workerman结合

本文链接: https://lsjlt.com/news/393916.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • laravel与workerman结合
    安装workerman composer require workerman/workerman 生成命令 php artisan make:command Workerman ...
    99+
    2023-09-04
    laravel php 服务器
  • Laravel接入workerman
    前言:此处,我们采用基于workerman开发的GatewayWorker作为socket的核心组件,因为,workerman是一个纯粹的socket类库,相对于GatewayWorker来说,更底层,更需要开发者有多进程的编程经验,而...
    99+
    2023-09-04
    laravel php linux websocket
  • laravel-admin与vue结合怎么用
    这篇文章主要介绍laravel-admin与vue结合怎么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!由于 Laravel-admin 采用的是 pjax 的方式刷新页面,意味着...
    99+
    2024-04-02
  • Laravel如何整合Workerman命令行监听MQTT
    这篇文章主要介绍“Laravel如何整合Workerman命令行监听MQTT”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Laravel如何整合Workerman命令行监听MQTT”文章能帮助大家解...
    99+
    2023-07-04
  • PHP笔记-Workerman整合到Laravel中并创建websocket
    今天想把websocket搭建起来,查了下原始的Laravel并没有这个功能,发现php中websocket用workerman好像比较多。 在此将他们结合下,但结合时发现了一些问题。此篇博文虽然以及结合起来了,但是在某些情况下,建议还是分...
    99+
    2023-09-08
    php 开发语言
  • ThinkPHP6.0 workerman/mqtt 与phpMQTT配合使用
    第一步:下载phpMQTT扩展下载地址,然后放在了扩展文件夹中 第二步:下载  workerman/mqtt 官方地址  通过composer进行安装 composer require workerman/mqtt 因为我是之前有用wo...
    99+
    2023-09-04
    PHP MQTT workerman linux Mosquitto
  • Laravel中如何接入workerman
    这篇文章主要介绍“Laravel中如何接入workerman”,在日常操作中,相信很多人在Laravel中如何接入workerman问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Laravel中如何接入wor...
    99+
    2023-07-04
  • thinkphp6整合workerman教程
    thinkphp6安装workerman命令: composer require topthink/think-worker 第一步,创建一个自定义命令类文件,运行指令 php think make:command Spider spide...
    99+
    2023-09-02
    php 开发语言
  • Laravel和Python:UNIX Shell的完美结合?
    Laravel和Python都是非常流行的编程语言,各有其独特的优点。但是,在一些特定场景下,它们的结合可能会产生非常有趣的效果。本文将介绍如何将Laravel和Python结合起来,使用UNIX Shell作为它们的桥梁。 为什么需要将...
    99+
    2023-11-01
    shell laravel unix
  • laravel passport与手机短信登录结合方法是什么
    本篇内容主要讲解“laravel passport与手机短信登录结合方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“laravel passport与手机短信登录结合方法是什么”吧!准备...
    99+
    2023-06-22
  • laravel如何结合vue添加权限
    这篇文章主要介绍laravel如何结合vue添加权限,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、添加(权限)节点1.1、引入vue使用vue进行界面管理,实现添加功能我们在这个目录下存入vue.js:1.2、添...
    99+
    2023-06-20
  • ASP 重定向接口与 Laravel 的结合,是如何实现的?
    ASP 重定向接口是一种方便的方法,可以将请求重定向到另一个 URL。与之相似的,Laravel 也提供了重定向功能。那么,ASP 重定向接口和 Laravel 的结合,是如何实现的呢? 首先,我们需要了解 ASP 重定向接口和 Lara...
    99+
    2023-06-23
    重定向 接口 laravel
  • Java和Laravel是否能够完美结合?
    Java和Laravel是两种不同的编程语言,Java是一种面向对象的编程语言,广泛应用于企业级应用程序开发和互联网应用程序开发;Laravel是一种开源的PHP Web应用程序框架,它采用了MVC架构模式,具有简单、优雅、直观的语法。 ...
    99+
    2023-09-26
    laravel shell api
  • 文件框架架构的新选择:Go与Laravel的完美结合?
    文件框架架构是一种常用的开发方式,通过文件夹层次结构将代码进行组织。在现代应用程序开发中,有许多文件框架框架选择可供开发人员使用。其中,Go和Laravel是两个备受瞩目的框架,它们的完美结合在文件框架架构中也不例外。 Go是一个开源编程...
    99+
    2023-06-25
    laravel 文件 框架
  • 用NativePHP与Laravel相结合,创造卓越的桌面应用程序
    将NativePHP融入Laravel,实现出色的桌面应用程序摘要:在开发桌面应用程序时,使用Laravel作为后端框架可以极大地提高开发效率和代码质量。然而,Laravel主要用于Web开发,如果要将其用于桌面应用程序,需要融合Nativ...
    99+
    2023-12-20
    桌面应用程序 laravel NativePHP
  • laravel结合vue添加权限的实现示例
    目录一、添加(权限)节点1.1、引入vue1.2、添加模版(vue、jquery)1.3、添加节点控制器逻辑1.4、模型中定义修改器1.5、效果:一、添加(权限)节点 1.1、引入v...
    99+
    2024-04-02
  • Unix、Python和Laravel:三者之间的完美结合?
    Unix、Python和Laravel是三个在不同领域中广泛使用的工具。Unix是一种操作系统,Python是一种编程语言,而Laravel是一种PHP框架。虽然它们之间没有直接的联系,但是它们可以通过一些技巧结合起来,从而提高我们的工作...
    99+
    2023-10-14
    unix load laravel
  • Python 与 Laravel,谁更适合同步开发?
    Python 和 Laravel 都是非常流行的编程语言和框架,它们各自拥有自己的优点和适用场景。但是,当我们需要同时开发前后端应用时,究竟是 Python 更适合还是 Laravel 更适合呢?本文将会从多个角度进行分析比较,希望能为大家...
    99+
    2023-08-27
    同步 laravel spring
  • DISTINCT与聚合函数的结合使用
    在SQL中,DISTINCT关键字用于返回唯一不重复的值,而聚合函数用于对数据进行统计或计算,例如SUM、COUNT、AVG等。这两者可以结合使用,以实现对唯一值进行统计或计算。 例如,可以使用DISTINCT和COUNT结合使用,以统计某...
    99+
    2024-08-03
    sql server
  • 将 MySQL 与 Apache 结合使用
    MySQL 和 Apache 是两个独立的软件,可以在同一台服务器上安装和运行。下面是将 MySQL 和 Apache 结合使用的一...
    99+
    2023-10-20
    MySQL
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作