在 Laravel 中使用 Workerman 进行 socket 通讯
1.安装 Workerman
由于要使用客户端点对点通讯,选择了 workerman/gateway-worker
的扩展包,它已经引入了 workerman/workerman
。
$ composer require workerman/gateway-worker
2.创建 Workerman 启动文件
创建一个 artisan 命令行工具来启动 Socket 服务端,在 app/Console/Commands 目录下建立命令行文件。
<?php
namespace App\Console\Commands;
use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use Illuminate\Console\Command;
use Workerman\Worker;
class WorkermanCommand extends Command
{
protected $signature = 'workman {action} {--d}';
protected $description = 'Start a Workerman server.';
public function handle()
{
global $argv;
$action = $this->argument('action');
$argv[0] = 'wk';
$argv[1] = $action;
$argv[2] = $this->option('d') ? '-d' : '';
$this->start();
}
private function start()
{
$this->startGateWay();
$this->startBusinessWorker();
$this->startRegister();
Worker::runAll();
}
private function startBusinessWorker()
{
$worker = new BusinessWorker();
$worker->name = 'BusinessWorker';
$worker->count = 1;
$worker->registerAddress = '127.0.0.1:1236';
$worker->eventHandler = \App\Workerman\Events::class;
}
private function startGateWay()
{
$gateway = new Gateway("websocket://0.0.0.0:2346");
$gateway->name = 'Gateway';
$gateway->count = 1;
$gateway->lanIp = '127.0.0.1';
$gateway->startPort = 2300;
$gateway->pingInterval = 30;
$gateway->pingNotResponseLimit = 0;
$gateway->pingData = '{"type":"@heart@"}';
$gateway->registerAddress = '127.0.0.1:1236';
}
private function startRegister()
{
new Register('text://0.0.0.0:1236');
}
}
3.创建事件监听文件
创建一个 app/Workerman/Events.php 文件来监听处理 workman 的各种事件。
<?php
namespace App\Workerman;
class Events
{
public static function onWorkerStart($businessWorker)
{
}
public static function onConnect($client_id)
{
}
public static function onWebSocketConnect($client_id, $data)
{
}
public static function onMessage($client_id, $message)
{
}
public static function onClose($client_id)
{
}
}
4.启动 Workerman 服务端
在命令行里面执行,支持的命令大概有 start|stop|restart,其中 -d 的意思是 daemon 模式。
$ php artisan workman start -d
当你看到如下结果的时候,workman已经启动成功了。
Workerman[wk] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.5.11 PHP version:7.1.11
------------------------ WORKERS -------------------------------
user worker listen processes status
root Gateway websocket://0.0.0.0:2346 1 [OK]
root BusinessWorker none 1 [OK]
root Register text://0.0.0.0:1236 1 [OK]
----------------------------------------------------------------
Press Ctrl+C to stop. Start success.
onWorkerStart
表述能力不是很好,按照这个流程,可以很快的搭建起基于 workerman 的 socket 服务端,其中的运行配置参数等,大家自行百度吧。
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
高认可度评论:
针对 Windows 下无法启动的问题,参考:windows操作系统下如何初始化多个Worker,做了一点特殊处理,也可以自己改进
1、命令行文件,改动
2、项目根目录,新建
start_for_win.bat
执行效果截图:
Waring: App\Workerman\Events::onMessage is not callable
解决了,events引用错了
集成进来以后能在 workerman 的各种事件里适用 laravel ORM 吗? 貌似不行.
@overfalse 可以使用的啊
@overfalse
@小陈叔叔 我集成 Workerman , 然后在 Workerman 的回调里面适用 orm, 前几分钟可以, 再久一点就不行了, 应该是生命周期问题. 不知道你这里有没解决方案.
@overfalse GatewayWorker最好不处理任何业务逻辑,如果你需要服务端向客户端推送数据的话可以用Gateway的API(GatewayClient),这样你就可以在controller调用api就行。
@overfalse 这个还真没试过,只是集成了有些东西还没来的急去重构,如果数据库断开的话,你可以看一下数据库的重连机制,或者是使用长连接
很不错!
不错的整合文章,谢谢分享。
@小陈叔叔 你是不是少了一条用php artisan创建文件的命令了啊?
@overfalse 你需要断线重连机制。
做完啊,stop,reload, -d
@HectorChan 自动创建和手动创建的结果都是一样的 主要是这个思路
如果一个项目有多个 TCP 的情况下如何处理呢?
比如:2346 端口用于 Websocket ,2347 端口用于 TCP 的情况。
陈叔 现在我们部署到线上之后 使用了supervisor来进行管理 然后代码里面是4个进程 但是过一段时间后出来了很多进程 您遇到过吗
@Echor supervisor默认的配置,会把PID文件 存在tmp文件夹下面,tmp偶尔会被清空
https://www.cjango.com/d/38.html 参考一下我这篇看看,不知道能不能解决你的问题
@小陈叔叔 行 谢谢陈叔 我先看看 谢谢您!
请问具体用法有说明文档么 ,没用过socket 想学习下
请问在
Events
中有办法验证jwt
用户吗?@overfalse 参考这个http://doc2.workerman.net/326107 然后通过http请求去调用workerman 服务器做 workerman服务器只做专门的消息推送服务器,这样的话就可以了
@小陈叔叔 pid文件有时候会被清理,您遇见过吗?pid清理后只影响stop和status命令,有什么危害吗?
用的-d,pid是存在vendor扩展包下的
我知道了,ci的时候被清了 :joy:
感谢分享。
我要用--d才能start
发消息收不到啊
@Echor 这个问题你解决了吗?我现在也遇到了 T.T
一定要用Gateway吗
win10怎么启动么
Command "workerman" is not defined.
如果windows遇到输入命令后不显示进程也不报错。
问题原因:
Windows无法进行同时启动多个协议
由于PHP-CLI在windows系统无法实现多进程以及守护进程,所以windows版本Workerman建议仅作开发调试使用。
启动命令应该是:
针对 Windows 下无法启动的问题,参考:windows操作系统下如何初始化多个Worker,做了一点特殊处理,也可以自己改进
1、命令行文件,改动
2、项目根目录,新建
start_for_win.bat
执行效果截图:
[@Hachiko](https://learnku.com/users/22249) 我用workerman而已。没用gateway,所以我只开一个worker
一样是卡住。出不来
请教一下大佬,我的定制协议文件应该放在哪呢
说好的socket 怎么成websocket了 :sob:
事件类中的方法会自动触发么?我没看到任何关联
在windows下可以使用吗,我的websocket连不上
如何使用laravel的功能测试来测试workman
Artisan::call('socket:connect stop');
我在
start
加了进程守护,然后想通过程序重启socket, 结果提示Only run in command line mode
请问如何重启socket,通过程序
我想问一下,1236 , 2346 , 2300 这三个端口都是做什么的?哪些需要外网开放啊?
注释有点少
我想请教下,怎么配置wss,就是 server.pem,server.key 文件路径
配置wss的方法
正确的启动命令是 php artisan gateway-worker:server start –daemon(两个横杠)
我有写一个包,觉得不错的可以用用 github.com/aoeng/laravel-workerman
记录一个问题。我这边的场景:当收到消息后,在队列里塞一个1分钟执行的任务,任务的内容是广播给当前小组的人一条信息。然后队列任务执行失败了!报错“ErrorException: stream_socket_client(): Unable to connect to tcp://127.0.0.1:1236 ”,因为我把端口号改成 1238了。普通法消息都没问题,但是为啥队列里的代码去用1236呢?找了下源码,在vendor\workerman\gateway-worker\src\Lib\Gateway.php 里有个静态的 $registerAddress = 127.0.0.1:1236。肯定就是它了!因为队列也是常驻内存,所以这种静态的只能改源码了!