laravel整合workerman做消息推送系统
官方建议分离 workerman和mvc框架的结合,我去,这不是有点脑缺氧吗?
大量的业务逻辑,去独立增加方法和类库在写一次,实际业务中是不现实和不实际的
gateway增加一些这方面的工作,但是我看了源码之后,就发现还是只能自己做
先增加composer require workerman/workerman 或者walkor/workerman ,但是官方的github是 walkor/workerman,注意一下
可以去 https://packagist.org查看是否有包
首先结合Console做命令
建立一个Command
<?php namespace App\Console\Commands; use Illuminate\Console\Command;
use Workerman\Worker;
use App\Work\WorkermanWork; class Workerman extends Command { protected $taskserver;
/*
* 操作参数
* 注意只能在
* start 启动
* stop 停止
* relaod 只能重启逻辑代码,核心workerman_init无法重启,注意看官方文档
* status 查看状态
* connections 查看连接状态(需要Workerman版本>=3.5.0)
*
*/
protected $action = array('start', 'stop', 'reload', 'status', 'connections'); /**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'Workerman {action}'; /**
* The console command description.
*
* @var string
*/
protected $description = 'Workerman'; /**
* Create a new command instance.
*
* @return void
*/
public function __construct() {
parent::__construct();
} /**
* Execute the console command.
*
* @return mixed
*
* 注意
*
*/
public function handle() {
$action = $this->argument('action'); if (!in_array($action, $this->action)) {
$this->error('Error Action');
exit;
}
//初始化workerman
WorkermanWork::workerman_init($action);
} }
注册到Kernel
class Kernel extends ConsoleKernel { /**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [ \App\Console\Commands\Workerman::class,
];
WorkermanWork的内容
<?php namespace App\Work; use App\Work\BaseWork as Base;
use Illuminate\Support\Facades\DB;
use App\Work\CommonWork;
use Workerman\Worker;
use Workerman\Lib\Timer;
use App\Models\OperationLog;
use App\Models\Users; class WorkermanWork extends Base { static $connection_count = 0; public static function workerman_init($action = null) {
global $argv; $argv[0] = 'workerman:websocket';
$argv[1] = $action;
$argv[2] = '-d';
// 心跳
define('HEARTBEAT_TIME', 30);
//初始化
$worker = new Worker("websocket://172.17.1.247:9099");
$worker->name = 'MessagePushWorker';
//linux 用户线上是www
// $worker->user = 'www';
//守护模式信息输出文件地址
// $worker->stdoutFile = "./workerman.log";
//工作进程总数 测试环境4个
$worker->count = 4;
//正式环境
// $ws->count = 10;
//建立链接 处理逻辑
$worker->onConnect = function($connection) {
// 有新的客户端连接时,连接数+1
self::$connection_count++;
self::onConnect($connection);
};
//接受消息 处理逻辑
$worker->onMessage = function($connection, $data) { self::onMessage($connection, $data);
};
//关闭链接 处理逻辑
$worker->onClose = function($connection) {
// 客户端关闭时,连接数-1
self::$connection_count--;
self::onClose($connection);
}; // 进程启动后设置一个30秒运行一次的定时器
// $worker->onWorkerStart = function($worker) {
// Timer::add(30, function()use($worker) {
//
// });
// };
// 开始
Worker::runAll();
} //建立链接 处理逻辑
public static function onConnect($connection) {
//测试5秒一次 线上30秒一次
Timer::add(10, function() use($connection) { if (!empty($_SESSION['user_id'])) {
$Users = Users::where('id', $_SESSION['user_id'])->first();
if (!empty($Users)) {
$message_count = OperationLog::where('user_id', $_SESSION['user_id'])->where('is_read', 1)->count();
$message_list = OperationLog::where('user_id', $_SESSION['user_id'])->where('is_read', 1)->orderBy('id', 'desc')->get(['content', 'id', 'create_time'])->toArray(); if (!empty($message_list)) {
$connection->send(json_encode(['code' => 200, 'msg' => '请求成功', 'data' => $message_list, 'connections' => self::$connection_count, 'message_count' => $message_count]));
}
}
// else {
// $connection->send(json_encode(['code' => 201, 'msg' => '无效user_id', 'connections' => self::$connection_count]));
// }
}
// else {
// $retrun_data = json_encode(['code' => 201, 'msg' => 'session user_id不存在', 'connections' => self::$connection_count]);
// $connection->send($retrun_data);
// }
});
} //接受消息 处理逻辑
public static function onMessage($connection, $data) {
//解析数据,非合法的json数据不处理
if (!empty($data)) {
if (is_json($data)) {
$data = json_decode($data, true);
switch ($data['type']) {
// 客户端回应服务端的心跳
case 'ping':
$connection->send(json_encode(['code' => 200, 'msg' => '服务存活', 'data' => [], 'connections' => self::$connection_count]));
case 'login':
$Users = Users::where('id', $data['user_id'])->first();
if (empty($Users)) {
$connection->send(json_encode(['code' => 201, 'msg' => '用户ID无效或者错误', 'data' => [], 'connections' => self::$connection_count]));
} else {
$_SESSION['user_id'] = $data['user_id'];
$connection->send(json_encode(['code' => 200, 'msg' => '登录成功', 'data' => [], 'connections' => self::$connection_count]));
}
}
}
} else {
$connection->send(json_encode(['code' => 201, 'msg' => '数据请求为空', 'data' => [], 'connections' => self::$connection_count]));
} // $data = $data . '----总共有连接数:' . self::$connection_count;
// $connection->send("return_data: $data ");
} //关闭链接 处理逻辑
public static function onClose($connection) { } }
建立socket的时间设置一个10秒的定时器,这个基于session的控制,登录之后立即请求发送
{"type":"login","user_id":"24"}
因为如果登录,就检索OperationLog表里属于这个用户ID的消息,每10秒推送一次数据
运行 命令
php artisan Workerman start 启动
$argv[2] = '-d';
注释掉就是测试模式,加上就是守护模式,就是线上使用的
2019年7月12日09:43:56
注意:上面是临时测试代码。业务代码使用try catch处理异常和错误
laravel整合workerman做消息推送系统的更多相关文章
- MPush开源消息推送系统:简洁、安全、支持集群
引言由于之前自己团队需要一个消息推送系统来替换JPUSH,一直找了很久基本没有真正可用的开源系统所有就直接造了个轮子,造轮子的时候就奔着开源做打算的,只是后来创业项目失败一直没时间整理这一套代码,最近 ...
- 开源实时消息推送系统 MPush
系统介绍 mpush,是一款开源的实时消息推送系统,采用java语言开发,服务端采用模块化设计,具有协议简洁,传输安全,接口流畅,实时高效,扩展性强,可配置化,部署方便,监控完善等特点.同时也是少有的 ...
- laravel整合workerman做聊天室
测试工具 http://www.blue-zero.com/WebSocket/ 2018年8月6日17:28:24 <?php namespace App\Console\Commands; ...
- 【转】SpringMVC整合websocket实现消息推送及触发
1.创建websocket握手协议的后台 (1)HandShake的实现类 /** *Project Name: price *File Name: HandShake.java *Packag ...
- laravel 5.8 实现消息推送
以下教程是基于5.6 的,在使用5.8实现时遇到一些问题,做一下记录 在我看来,实时通信才是 APP 应用的将来. Socket 服务通常不是那么容易实现,但是 Laravel Echo 服务改变了这 ...
- netty-socketio整合springboot消息推送
netty-socketio整合springboot消息推送 1.netty-socketio消息推送 1)在项目中常常涉及到消息推送的情况,消息推送要求的实时性,使用传统的方式已经不能满足需求了: ...
- 了解iOS消息推送一文就够:史上最全iOS Push技术详解
本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表. 1.引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ.微信等IM界面处于前台时,聊天消息和指 ...
- 我有 7种 实现web实时消息推送的方案,7种!
技术交流,公众号:程序员小富 大家好,我是小富- 我有一个朋友- 做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能. 不过他还没想好用什么方式做,这里 ...
- Android P正式版即将到来:后台应用保活、消息推送的真正噩梦
1.前言 对于广大Android开发者来说,Android O(即Android 8.0)还没玩热,Andriod P(即Andriod 9.0)又要来了. 下图上谷歌官方公布的Android P ...
随机推荐
- windows 下 bat 计划任务删除保留时间内文件
date windows 打印时间戳 年:echo %date:~,% 月:echo %date:~,% 日:echo %date:~,% 星期:echo %date:~,% 小时:echo %t ...
- xheditor编辑器上传图片
之前在用csdn的时候,觉得他们家的编辑器挺好用,精美,简洁,大方,功能强大.最近自己的项目也要用到编辑器,我就想起了xheditor. 好多大网站都用到它~好棒! 我把xheditor用于文章模块, ...
- vue组件,通过props父组件给子组件传值,WTF, 子组件报错undefined???
如果是正常操作,找了半天又找不到为什么undefined, 那很可能是props的命名出了问题: 不要用小驼峰式命名 例如这种childrenData 这种形式就会报错undefined 请尽量用全 ...
- .net core web api 与httpclient发送和接收文件及数据
客户端 HttpClient var url = $"https://localhost:44323/api/values/posttest?resource_source=yangwwme ...
- codeforces 493 div1 e
题解: 和这件zhcs的那题有点像 第一种做法是考虑i,i+1之间的贡献 这样子就是矩形加减然后求矩形最小值个数 另一种做法是我们从左向右维护mx-nx-r+l 跟之前那题一样我们知道这个的最小值为0 ...
- 学习使人快乐5-JavaWeb应用的组成结构
开发JavaWeb应用时,不同类型的文件有严格的存放规则,否则不仅可能会使web应用无法访问,还会导致web服务器启动报错 WebRoot →Web应用所在目录,一般情况下虚拟目录要配置到此文件夹当中 ...
- Sicily T-primes
DescriptionWe know that prime numbers are positive integers that have exactly two distinct positive ...
- XOR UVALive - 8512 -区间线性基合并
UVALive - 8512 题意 :给出一个包含n个元素的数组A以及一个k,接下来进行q次询问,每次询问给出 l 和 r , 要你求出从A[l] , A[l+1] , A[l + 2],...,A[ ...
- 拷贝JAR包
package com.cici; import java.io.File; import java.io.FileInputStream; import java.util.ArrayList; i ...
- iphone手机浏览器文本框不触发输入中文的keyup事件
问题描述:iphone手机浏览器文本框不触发输入中文的keyup事件,在输入中文之后需要点击回退按键,才会开始搜索.问题分析:iphone手机的输入法(不管是第三方还是自带)能检测到英文或者数字的ke ...