当前位置:网站首页>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
边栏推荐
- 渗透测试-目录遍历漏洞
- Successfully solved: selenium common. exceptions. TimeoutException: Message: timeout: Timed out receiving message from
- Teach you to write non maintainable PHP code step by step
- Cookie & session & JSP (XII)
- Deep learning - several types of learning
- Region of Halcon: generation of multiple regions (3)
- 2.0springmvc uses restful
- ORA-00800: soft external error
- JS arguments
- Upgrade PHP to php7 The impact of X (2), the obsolescence of mcrypt decryption
猜你喜欢

本轮压力测试下,DeFi协议们表现如何?

Code scanning payment flow chart of Alipay payment function developed by PHP

高效的NoSQL数据库服务Amozon DynamoDB体验分享

Why is the TCP handshake just 3 times?

Efficient NoSQL database service Amazon dynamodb experience sharing

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

ThinkPHP 5 log management

Web3 DAPP user experience best practices

ASEMI大功率场效应管和三极管的区别

JS' sort() function
随机推荐
Kotlin Compose 监听软键盘 点击enter提交事件
渗透测试-目录遍历漏洞
Immutable learning road -- farewell to traditional copy
JS' sort() function
为什么TCP握手刚刚好是3次呢?
Student achievement management system based on SSH
华为鸿蒙开发第四课
OOP vector addition and subtraction (friend + copy construction)
jsz中的join()
小白一键重装官网下载使用方法
Bingbing's learning notes: implementation of circular queue
parallel recovery slave next change & parallel recovery push change
EL & JSTL (XIII)
ASEMI三相整流桥的工作原理
《牛客刷verilog》Part I Verilog快速入门
Which programming language is the most cumbersome to implement Hello world?
ASEMI大功率场效应管和三极管的区别
【FLink】access closed classloader classloader. check-leaked-classloader
OLAP analysis engine kylin4.0
Kotlin compose perfect todo project surface rendering background and shadow