Laravel workerman 创建并实时聊天 操作文档
1. 安装composer require workerman/workerman
2. 运行php artisan workerman start
3. 以daemon(守护进程)方式启动php artisan workerman start-d
4. php artisan workerman reload // 重新加载配置
5. php artisan workerman reload // 重启workerman
6. php artisan workerman stop // 停止workerman
7. workerman创建php artisan make:command 文件名
8. 修改文件protected $signature = '进程名 {action}';
9. workerman注册Kernel.php protected $commands = [文件类];
<?php
namespace App\Console\Commands;
use Illuminate\Auth\TokenGuard;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Workerman\Worker;
use Workerman\Lib\Timer;
use Illuminate\Support\Facades\DB;
use Exception;
use Workerman\Protocols\Http\Request;
class Workerman extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'workerman {action}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Workerman Server';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// global $worker;
// $worker = new Worker('websocket://' . env('HOST', '127.0.0.1') . ':' . env('WEBSOCKET_PORT', '1234'));
// global $argv; //$argv 在ArgvInput类中被定义了,就是$_SERVER['argv'];
// $arg = $this->argument('action');
// $argv[1] = $argv[2];
// $argv[2] = isset($argv[3]) ? "-{$argv[3]}" : '';
// Log::info($arg);
// switch ($arg) {
// // case 'restart':
// // $this->info('workerman server restarted');
// // break;
// // case 'close':
// // $this->info('workerman server stoped');
// // break;
// //default:
// case 'start':
// $this->start($request);
// break;
// }
$this->start();
}
private function start()
{
//建立socket连接
$http_worker = new Worker('websocket://127.0.0.1:2001');
// 启动4个进程对外提供服务
$http_worker->count = 1;
//定义一个属性,用来存放用户的连接信息,$connection
$http_worker->uidConnections = array();
//socket事件类中的,链接属性,调用闭包函数
$http_worker->onConnect = function ($connection) use ($http_worker) {
// 设置连接的onMessage回调
$connection->onMessage = function ($connection, $data) use ($http_worker) {
//获取用户传输过来的数据,并且进行json_decode解析
$data = json_decode($data, true);
//获取用户ID接着将用户信息$connection,存储在$http_worker->uidConnections中,
//$http_worker->uidConnections[$data['id']] = $connection;
$connection->uid = $data['user_type'].'_'.$data['id'];
$uid = $data['user_type'].'_'.$data['id'];// 发送者user_id
// Log::info($uid);
$http_worker->uidConnections[$uid] = $connection;
//给其他用户发送,该用户发送的信息,为了保持数据的实时性。
try {
DB::beginTransaction();
$uid_key = 'enterpriseUser_'. $data['fid'];// 接收者user_type._.fid
foreach ($http_worker->uidConnections as $k => $v) {
if($k == $uid_key){
$v->send(json_encode(['status' => 0, 'msg' => $data['content']]));
}
}
DB::commit();
} catch (Exception $exception) {
Log::info($exception);
DB::rollBack();
}
};
//设置用户断开连接的回调。
$connection->onClose = function ($connection) use ($http_worker) {
foreach ($http_worker->uidConnections as $k => $v) {
if ($v == $connection) {
unset($http_worker->uidConnections[$k]);
} else {
$v->send(json_encode(['status' => 0, 'msg' => $k . '下线了']));
}
}
};
/*设置心跳,为防止长链接断开 * 原理:就是设置一个定时器,定时的向客户端发送数据 * $time_interval 时间间隔* */
$time_interval = 59;
Timer::add($time_interval, function () use ($http_worker) {
if (count($http_worker->uidConnections) > 0) {
foreach ($http_worker->uidConnections as $connection) {
$connection->send(json_encode(['status' => 1, 'smg' => 'socket_hot']));
}
}
});
};
Worker::runAll();
}
}
前端js
onMounted(() => {
alert('请登录')
var url = 'ws://127.0.0.1:2001'
var ws = new WebSocket(url)
var user_id = 74620
var id = 'jobSeekerUser_' + user_id
ws.onopen = function () {
var data = {id: user_id, user_type: 'jobSeekerUser', is_true: false }
data = JSON.stringify(data)
ws.send(data)
}
ws.onmessage = function (e) {
var msg = JSON.parse(e.data)
if (msg.status == 200) {
console.log(msg.msg)
}
}
})
// 发送方法待调用
function this_test(type = 1, content = '', request_status = 1, user_id = 74620, fid = 2, user_type = 'jobSeekerUser', image_url = '', recruits_id = 0, resumes_id = 0, is_true = true) {
var url = 'ws://127.0.0.1:2001'
var ws = new WebSocket(url)// 调用了两次待优化
var id = 'jobSeekerUser_' + user_id
var tests = this
ws.onopen = function () {// 事件封装请求方法
var data = {
id: user_id,//发送者uid
// uid: id,//请求身份识别jobSeekerUser_id
content: content,
fid: fid,//接收者id
user_type: user_type,//jobSeekerUser
type: type, // 消息类型(1文字)
status: request_status,// 请求状态1发送2接收
image_url: image_url,// 图片链接
recruits_id: recruits_id,// 职位招聘信息id
resumes_id: resumes_id, //简历id
is_true: is_true// 是否发送消息请求
}
data = JSON.stringify(data)
ws.send(data)// 发送
}
ws.onmessage = function (e) {
var msg = JSON.parse(e.data)
if (msg.status == 200) {
console.log(msg.msg)
}
}
}