当前位置:网站首页>Implementation of websocket long connection by workman under laravel
Implementation of websocket long connection by workman under laravel
2022-06-25 04:52:00 【Kiway.】
Laravel Next Workerman Realization websocket A long connection
- install workerman
composer require workerman/workerman -vvv
- establish laravel Custom command
php artisan make:command Workerman
After executing this command, the \app\Console\Commands Generate under folder Workerman.php file
- Workerman.php File code :
<?php
namespace App\Console\Commands;
use Workerman\Worker;
use Illuminate\Console\Command;
class Workerman extends Command {
private $server;
// -d Whether or not to debug Way to run
protected $signature = 'workerman {action} {-d?}';
protected $description = 'Start a Workerman server.';
public function __construct() {
parent::__construct();
}
/** * Execute the console command. * * @return mixed */
public function handle() {
global $argv;
$context = array(
// more ssl Please refer to the manual for options http://php.net/manual/zh/context.ssl.php
'ssl' => array(
// Please use absolute path
'local_cert' => '/www/server/panel/vhost/cert/www.example.com/fullchain.pem', // It can also be crt file
'local_pk' => '/www/server/panel/vhost/cert/www.example.com/privkey.pem',
'verify_peer' => false,
// 'allow_self_signed' => true, // If it is a self signed certificate, you need to turn on this option
)
);
// The setting here is websocket agreement ( Any port , But you need to ensure that it is not occupied by other programs )
$worker = new Worker('websocket://0.0.0.0:2000', $context);
// Set up transport Turn on ssl,websocket+ssl namely wss
$worker->transport = 'ssl';
// $worker->onMessage = function($con, $msg) {
// $con->send('ok');
// };
$this->server = $worker;
// $this->server = new Worker("websocket://0.0.0.0:2000");
$arg = $this->argument('action');
$argv[1] = $argv[2];
$argv[2] = isset($argv[3]) ? "-{
$argv[3]}" : '';
switch ($arg) {
case 'start':
$this->start();
break;
case 'stop':
$this->stop();
break;
case 'restart':
$this->restart();
break;
case 'reload':
$this->reload();
break;
}
}
private function start() {
// start-up 4 Two processes provide services to the outside world
$this->server->count = 4;
$handler = \App::make('handlers\WorkermanHandler');
// Call back when connecting
$this->server->onConnect = [$handler, 'onConnect'];
// Callback when receiving client information
$this->server->onMessage = [$handler, 'onMessage'];
// Callback after process startup
$this->server->onWorkerStart = [$handler, 'onWorkerStart'];
// Callback triggered when disconnected
$this->server->onClose = [$handler, 'onClose'];
// function worker
Worker::runAll();
}
private function stop() {
$worker = $this->server;
// Set this instance to receive reload Whether the signal is reload restart
$worker->reloadable = false;
$worker->onWorkerStop = function($worker)
{
echo "Worker reload...\n";
};
// function worker
Worker::runAll();
}
private function restart() {
$worker = $this->server;
// Set this instance to receive reload Whether the signal is reload restart
$worker->reloadable = true;
$worker->onWorkerStart = function($worker)
{
echo "Worker restart...\n";
};
// function worker
Worker::runAll();
}
private function reload() {
$worker = $this->server;
// Set this instance to receive reload Whether the signal is reload restart
$worker->reloadable = false;
$worker->onWorkerStart = function($worker)
{
echo "Worker reload...\n";
};
// function worker
Worker::runAll();
}
}`
- workerman Referenced execution file
app\Console\Commands\handlers\WorkermanHandler.php file
<?php
namespace handlers;
use Workerman\Lib\Timer;
use Illuminate\Support\Facades\Redis;
use App\Log\LogController;
// Heartbeat interval 10 second
define('HEARTBEAT_TIME',100);
class WorkermanHandler {
const check = 0;
// Handles client connections
public function onConnect($connection) {
echo " Link successful ";
}
public function editLog($function,$param,$res){
$log=new LogController();
// if($this->log == '1'){
$log->Success(' Interface :'.$function.'; Upload parameters are as follows :'.json_encode($param).'; Returns the parameter :'.json_encode($res));
// }
}
// public function onMessage($connection, $data) {
// $connection->send($data);
// }
// Processing client messages
public function onMessage($connection, $data) {
$this->editLog($function='onMessage',$data,'');
// The time when the last data uploaded is obtained
$connection->lastMessageTime = time();
// $connection->send($data);
// Heartbeat bag
if($data!='{"t2yp3e":"213213","sae1acr213et":"sadasdas"}'){
//RSA Decrypt
if(self::check == 1){
$myfile = fopen("rsa/rsa_private_key.pem", "r") or die("Unable to open file!");
$private_key = fread($myfile,filesize("rsa/rsa_private_key.pem"));
$pi_key = openssl_pkey_get_private($private_key);
$encrypted = str_replace(' ', '+',$data);
$decrypted = "";
// Decrypt
openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);// Private key decryption
fclose($myfile);
// Decryption content is empty
if($decrypted==''){
$connection->send(' Validation failed ');
}
// $connection->send($decrypted);
// Array parameter
$data = json_decode($decrypted);
$this->editLog($function='onMessage',$data,'');
}else{
// Test with
$connection->send($data);
$data = json_decode($data);
}
}else{
$connection->send($data);
$data='';
}
if($data!=''){
// Do what you want to do
}
// Fault code
if(!empty($data->code)){
// Do what you want to do
}
// Record speed and other data ( Details are activated ) Negligible
if(!empty($data->bluetooth)){
$key_detail = 'detail'.$data->bluetooth;
$detail = Redis::get($key_detail);
if($detail){
// The data of the graph
$key_curve = $data->bluetooth.'curve';
$curve = Redis::get($key_curve);
if(!empty($curve)){
$curve = unserialize($curve);
// echo json_encode($curve);
// How many elements the array is full will automatically clear the first element
// if(count($curve)>5){
// array_shift($curve);
// }
array_push($curve,['speed'=>$data->speed??'0','voltage'=>$data->voltage??'0','electric_current'=>$data->current??'0','output_power'
=>$data->outpower??'0','Motherboardtemperature'=>$data->mTemperature??'0','Motortemperature'=>$data->eTemperature??'0','createtime'=>date('Y-m-d H:i:s',time())]);
Redis::setex($key_curve, 10, serialize($curve));
}else{
$curve = array();
array_push($curve,['speed'=>$data->speed??'0','voltage'=>$data->voltage??'0','electric_current'=>$data->current??'0','output_power'
=>$data->outpower??'0','Motherboardtemperature'=>$data->mTemperature??'0','Motortemperature'=>$data->eTemperature??'0','createtime'=>date('Y-m-d H:i:s',time())]);
Redis::setex($key_curve, 10, serialize($curve));
}
}else{
echo 'detail is not';
}
$open = Redis::get($data->bluetooth.'open');
if($open == '1'){
$export = Redis::get($data->bluetooth.'export');
if(!empty($export)){
$export = unserialize($export);
array_push($curve,['speed'=>$data->speed??'0','voltage'=>$data->voltage??'0','electric_current'=>$data->current??'0','output_power'
=>$data->outpower??'0','Motherboardtemperature'=>$data->mTemperature??'0','Motortemperature'=>$data->eTemperature??'0','createtime'=>date('Y-m-d H:i:s',time())]);
Redis::setex($data->bluetooth.'export', 300, serialize($export));
}else{
$export = array();
array_push($curve,['speed'=>$data->speed??'0','voltage'=>$data->voltage??'0','electric_current'=>$data->current??'0','output_power'
=>$data->outpower??'0','Motherboardtemperature'=>$data->mTemperature??'0','Motortemperature'=>$data->eTemperature??'0','createtime'=>date('Y-m-d H:i:s',time())]);
Redis::setex($data->bluetooth.'export', 300, serialize($export));
}
}
}
// Activation details ( Request for details websocket Trigger when )mTemperature
if(!empty($data->bluetooth)){
$key_detail = 'detail'.$data->bluetooth;// by 1 when , The graph stores data such as speed
Redis::setex($key_detail,'10', 1);
// Obtain the speed and other data of the curve
$key_curve = $data->bluetooth.'curve';
$curve = Redis::get($key_curve);
$connection->send(json_encode(unserialize($curve)));
}
if(!empty($id)){
if(!empty($data->code)&&$data->code!=''){
\DB::table('dlc_websocket')->where('id',$id)->update(['code'=>$data->code]);
}
//id assignment
$connection->id = $id;
}
// }
}
// Handle client disconnects
public function onClose($connection) {
echo "connection closed from ip {
$connection->getRemoteIp()}\n";
}
public function onWorkerStart($worker) {
Timer::add(1, function () use ($worker) {
$time_now = time();
foreach ($worker->connections as $connection) {
// It's possible that connection I haven't heard from you yet , be lastMessageTime Set to current time
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// The last communication interval is greater than the heartbeat interval , The client is considered offline , Close the connection
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
if($connection->id){
\DB::table('dlc_websocket')->where('id',$connection->id)->delete();
// \DB::table('dlc_websocket')->where('id',$connection->id)->update(['status'=>0]);
}
// Callback after disconnection
echo "Client ip {
$connection->getRemoteIp()} timeout!!!\n"; $connection->close();
}
}
});
}
}
The first file is the configuration workerman Basic information of , You can configure the https, The long connection will be wss instead of ws. The second file is used to process the received data , For example, for storage , Front end page drawing display, etc .
- start-up workerman
php artisan Workerman start d
- close workerman
php artisan Workerman stop d
边栏推荐
- Web3 DApp用户体验最佳实践
- win11蓝牙无法连接怎么办?win11蓝牙无法连接的解决方法
- buuctf web
- Opensea PHP development kit
- 成功解决:selenium.common.exceptions.TimeoutException: Message: timeout: Timed out receiving message from
- Vscode 设置clang-format
- Web3 DAPP user experience best practices
- parallel recovery slave next change & parallel recovery push change
- JS call() and apply()
- Cannot import name 'escape' from 'jinja2' [solved successfully]
猜你喜欢

30岁了开始自学编程,家里比较困难还来得及吗?

固态硬盘开盘数据恢复的方法

How to download and use Xiaobai one click reload on the official website

以太网是什么要怎么连接电脑

win11蓝牙无法连接怎么办?win11蓝牙无法连接的解决方法

OLAP analysis engine kylin4.0

多睡觉,能减肥,芝加哥大学最新研究:每天多睡1小时,等于少吃一根炸鸡腿...

台式电脑连不上wifi怎么办

At the age of 30, I began to learn programming by myself. Is it still time for me to have difficulties at home?

The solution of wechat applet switchtab unable to take parameters
随机推荐
Kotlin compose perfect todo project surface rendering background and shadow
ROS2/DDS/QoS/主题的记录
Startup mode of SoC verification environment
Precise delay based on Cortex-M3 and M4 (systick delay of system timer can be used for STM32, aducm4050, etc.)
[Flink] problems and solutions of the continuous growth of checkpoint size in rocksdb incremental mode
cannot import name ‘escape’ from ‘jinja2’【成功解决】
小白一键重装官网下载使用方法
初识 Flutter 的绘图组件 — CustomPaint
OOP 向量加减(友元+拷贝构造)
Filter & listener (XIV)
How to make colleagues under the same LAN connect to their own MySQL database
「 每日一练,快乐水题 」1108. IP 地址无效化
Coordinate system left multiply right multiply
【FLink】access closed classloader classloader. check-leaked-classloader
DMA double buffer mode of stm32
Google Earth Engine(GEE)——全球JRC/GSW1_1/YearlyHistory数据集的批量下载(中国区域)
How do the defi protocols perform under this round of stress test?
MySQL concept and operation (III)
为什么SQL语句命中索引比不命中索引要快?
Introduction to the hardest core PWN in the whole network_ Graphic analysis