tp5+workman(GatewayWorker) 安装及使用

一、安装thinkphp5

1、宝塔删除php禁用函数putenv、pcntl_signal_dispatch、pcntl_wai、pcntl_signal、pcntl_alarm、pcntl_fork,执行安装命令。

composer create-project topthink/think=5.0.* tp5  --prefer-dist

2、配置好站点之后,浏览器打开访问成功。

二、tp5安装GatewayWorker

1、进入tp5目录,安装GatewayWorker

composer require workerman/gateway-worker

如果报错安装指定版本

2、安装workman

composer require workerman/workerman

如果报错安装指定版本

3、安装gatewayclient

composer require workerman/gatewayclient

如果报错安装指定版本

三、使用GatewayWorker  

注:我已修改默认端口号,在宝塔开启端口号

1、创建文件   tp5/public/start.php

<?php
/*** run with command* php start.php start*/ini_set('display_errors', 'on');
use Workerman\Worker;if(strpos(strtolower(PHP_OS), 'win') === 0)
{exit("start.php not support windows, please use start_for_win.bat\n");
}// 检查扩展
if(!extension_loaded('pcntl'))
{exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}if(!extension_loaded('posix'))
{exit("Please install posix extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}// 标记是全局启动
define('GLOBAL_START', 1);require_once __DIR__ . '/../vendor/autoload.php';
// 加载所有Applications/*/start.php,以便启动所有服务 application更改为自己文件夹名字,我的为websocket
foreach(glob(__DIR__.'/../api/websocket/start*.php') as $start_file)
{require_once $start_file;
}
// 运行所有服务
Worker::runAll();

2、创建文件  tp5/api/Socket/Events.php  (创建php文件,或者下载demo复制过去即可)

<?php
/*** This file is part of workerman.** Licensed under The MIT License* For full copyright and license information, please see the MIT-LICENSE.txt* Redistributions of files must retain the above copyright notice.** @author walkor<walkor@workerman.net>* @copyright walkor<walkor@workerman.net>* @link http://www.workerman.net/* @license http://www.opensource.org/licenses/mit-license.php MIT License*//*** 用于检测业务代码死循环或者长时间阻塞等问题* 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload* 然后观察一段时间workerman.log看是否有process_timeout异常*/
//declare(ticks=1);use \GatewayWorker\Lib\Gateway;/*** 主逻辑* 主要是处理 onConnect onMessage onClose 三个方法* onConnect 和 onClose 如果不需要可以不用实现并删除*/
class Events
{/*** 当客户端连接时触发* 如果业务不需此回调可以删除onConnect* * @param int $client_id 连接id*/public static function onConnect($client_id){echo "【新的客户端链接】:client_id:".$client_id.PHP_EOL;// 向当前client_id发送数据 Gateway::sendToClient($client_id, "Hello $client_id\r\n");// 向所有人发送Gateway::sendToAll("$client_id login\r\n");}/*** 当客户端发来消息时触发* @param int $client_id 连接id* @param mixed $message 具体消息*/public static function onMessage($client_id, $message){// 向所有人发送 Gateway::sendToAll("$client_id said $message\r\n");}/*** 当用户断开连接时触发* @param int $client_id 连接id*/public static function onClose($client_id){// 向所有人发送 GateWay::sendToAll("$client_id logout\r\n");}
}

3、创建文件tp5/application/Socket/start_businessworker.php

<?php
/*** This file is part of workerman.** Licensed under The MIT License* For full copyright and license information, please see the MIT-LICENSE.txt* Redistributions of files must retain the above copyright notice.** @author walkor<walkor@workerman.net>* @copyright walkor<walkor@workerman.net>* @link http://www.workerman.net/* @license http://www.opensource.org/licenses/mit-license.php MIT License*/
use Workerman\Worker;
use Workerman\WebServer;
use GatewayWorker\Gateway;
use GatewayWorker\BusinessWorker;
use Workerman\Autoloader;// 自动加载类
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/Events.php';// bussinessWorker 进程
$worker = new BusinessWorker();
// worker名称
$worker->name = 'YourAppBusinessWorker';
// bussinessWorker进程数量
$worker->count = 4;
// 服务注册地址
$worker->registerAddress = '127.0.0.1:23222';//这行代码防止出现报错:Waring: Events::onMessage is not callable
$worker->eventHandler = 'Events';// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START'))
{Worker::runAll();
}

4、创建文件tp5/application/Socket/start_gateway.php

<?php
/*** This file is part of workerman.** Licensed under The MIT License* For full copyright and license information, please see the MIT-LICENSE.txt* Redistributions of files must retain the above copyright notice.** @author walkor<walkor@workerman.net>* @copyright walkor<walkor@workerman.net>* @link http://www.workerman.net/* @license http://www.opensource.org/licenses/mit-license.php MIT License*/
use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;// 自动加载类
require_once __DIR__ . '/../../vendor/autoload.php';// gateway 进程,这里使用Text协议,可以用telnet测试
$gateway = new Gateway("websocket://0.0.0.0:24222");
// gateway名称,status方便查看
$gateway->name = 'moods';
// gateway进程数
$gateway->count = 4;
// 本机ip,分布式部署时使用内网ip
$gateway->lanIp = '127.0.0.1';
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
$gateway->startPort = 2900;
// 服务注册地址
$gateway->registerAddress = '127.0.0.1:23222';// 心跳间隔
//$gateway->pingInterval = 1;
// 心跳数据
//$gateway->pingData = '{"type":"ping"}';/*
// 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
$gateway->onConnect = function($connection)
{$connection->onWebSocketConnect = function($connection , $http_header){// 可以在这里判断连接来源是否合法,不合法就关掉连接// $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接if($_SERVER['HTTP_ORIGIN'] != 'http://kedou.workerman.net'){$connection->close();}// onWebSocketConnect 里面$_GET $_SERVER是可用的// var_dump($_GET, $_SERVER);};
};
*/// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START'))
{Worker::runAll();
}

5、创建文件tp5/application/Socket/start_register.php

<?php
/*** This file is part of workerman.** Licensed under The MIT License* For full copyright and license information, please see the MIT-LICENSE.txt* Redistributions of files must retain the above copyright notice.** @author walkor<walkor@workerman.net>* @copyright walkor<walkor@workerman.net>* @link http://www.workerman.net/* @license http://www.opensource.org/licenses/mit-license.php MIT License*/
use \Workerman\Worker;
use \GatewayWorker\Register;// 自动加载类
require_once __DIR__ . '/../../vendor/autoload.php';// register 必须是text协议
$register = new Register('text://0.0.0.0:23222');// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START'))
{Worker::runAll();
}

6、启动websocket程序

1、防火墙打开8282、1236端口,执行下面命令

//运行php start.php start//linux运行php start.php start -d//停止php start.php stop//检测端口是否以被占用
netstat -an | grep 80//关闭某个进程
sudo kill -9 进程ID如果修改文件后一定要先停止在运行一下文件,否则不生效

四、使用GatewayWorker发布广播

1、创建文件tp5/application/index/controller/Index.php,执行这个方法就可以向所有人发布广播了。

<?php
namespace app\index\controller;
use GatewayClient\Gateway;
class Index
{public function index(){Gateway::sendToAll(" index发的消息 \r\n");}
}

后面逻辑,自己处理即可

测试发信息内容为

 测试地址: http://www.jsons.cn/websocket/

用户1

用户2

下面是我写的一个例子

数据库:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for cmf_chat
-- ----------------------------
DROP TABLE IF EXISTS `cmf_chat`;
CREATE TABLE `cmf_chat`  (`id` int(11) NOT NULL AUTO_INCREMENT,`user_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用于查找聊天记录',`operation_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作类型:send_message发送信息,login登录',`send_uid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '发送人',`send_client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`to_uid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '收信息人',`to_client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`openid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'openid',`content_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '发送信息类型:text文本',`content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '发送信息',`signature` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '唯一签名',`date` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '日期',`time` bigint(20) NULL DEFAULT NULL COMMENT '时间',`create_time` bigint(20) NULL DEFAULT NULL COMMENT '创建时间',`update_time` bigint(20) NULL DEFAULT NULL COMMENT '更新时间',`delete_time` bigint(20) NULL DEFAULT 0 COMMENT '软删除',`me_client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '存入聊天记录' ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of cmf_chat
-- ----------------------------SET FOREIGN_KEY_CHECKS = 1;

1.安装mysql,插架

使用workerman/mysql 扩展

composer require workerman/mysql

2.处理逻辑   Events.php

<?php
/*** This file is part of workerman.** Licensed under The MIT License* For full copyright and license information, please see the MIT-LICENSE.txt* Redistributions of files must retain the above copyright notice.** @author    walkor<walkor@workerman.net>* @copyright walkor<walkor@workerman.net>* @link      http://www.workerman.net/* @license   http://www.opensource.org/licenses/mit-license.php MIT License*//*** 用于检测业务代码死循环或者长时间阻塞等问题* 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload* 然后观察一段时间workerman.log看是否有process_timeout异常*///declare(ticks=1);use \GatewayWorker\Lib\Gateway;/*** 主逻辑* 主要是处理 onConnect onMessage onClose 三个方法* onConnect 和 onClose 如果不需要可以不用实现并删除*/error_reporting(0);class Events
{/*** 新建一个类的静态成员,用来保存数据库实例*/public static $db = null;/*** 进程启动后初始化数据库连接 两者都可以*/public static function onWorkerStart($worker){//使用gateway_worker扩展self::$db = new \GatewayWorker\Lib\DbConnection('47.****.188', '3306', 'kf***od_com', 'Gyt***4jb65cD', 'kf***d_com');//使用workerman/mysql 扩展//        self::$db = new \Workerman\MySQL\Connection('host', 'port', 'user', 'password', 'db_name');}/*** 当客户端连接时触发* 如果业务不需此回调可以删除onConnect** @param int $client_id 连接id*/public static function onConnect($client_id){// 向当前client_id发送数据$restult = ['operation_type' => 'login','me_client_id'   => $client_id,'content_type'   => "text",'content'        => "$client_id login success",'signature'      => cmf_random_string(100),'date'           => date('Y-m-d H:i:s'),'time'           => time(),'create_time'    => time(),];//存入数据库self::$db->insert('cmf_chat')->cols($restult)->query();//转换为json格式$send_message = json_encode($restult, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);//给自己发送注册成功Gateway::sendToClient($client_id, $send_message);// 向所有人发送//Gateway::sendToAll("$client_id login\r\n");}/*** 当客户端发来消息时触发* @param int   $client_id 连接id* @param mixed $message   具体消息*/public static function onMessage($client_id, $message){//写个日志文件$contents = json_encode($message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);//写入日志$filename = '../api/websocket/log/';!is_dir($filename) && mkdir($filename, 0755, true);$file_hwnd = fopen($filename . date('Y-m-d') . ".log", "a+");fwrite($file_hwnd, "$client_id----$contents" . "\r\n");fclose($file_hwnd);//数据格式转为数组$message = json_decode($message, true);// 向指定人发送$restult = ['operation_type' => 'send_message','send_client_id' => isset($message['send_client_id']) ? $message['send_client_id'] : '',//用户client_id'send_uid'       => isset($message['send_uid']) ? $message['send_uid'] : '',//或者用户uid'to_client_id'   => isset($message['to_client_id']) ? $message['to_client_id'] : '','to_uid'         => isset($message['to_uid']) ? $message['to_uid'] : '','openid'         => isset($message['openid']) ? $message['openid'] : '','content_type'   => "text",'content'        => $message['content'],'signature'      => cmf_random_string(100),'date'           => date('Y-m-d H:i:s'),'time'           => time(),'create_time'    => time(),];//存入数据库self::$db->insert('cmf_chat')->cols($restult)->query();//转换为json格式$send_message = json_encode($restult, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);//给指定人发信息if ($restult['to_client_id']) Gateway::sendToClient($restult['to_client_id'], $send_message);if ($restult['to_uid']) Gateway::sendToUid($restult['to_uid'], $send_message);//在给自己信息同步一下if ($restult['send_client_id']) Gateway::sendToClient($restult['send_client_id'], $send_message);if ($restult['send_uid']) Gateway::sendToUid($restult['send_uid'], $send_message);//向所有人发送//Gateway::sendToAll("$send_message content\r\n");}/*** 当用户断开连接时触发* @param int $client_id 连接id*/public static function onClose($client_id){// 向所有人发送//GateWay::sendToAll("$client_id logout\r\n");}/*** 发送请求,将数据存入数据库中* @param $url* @param $data*/public function add_chat($url, $data){$ch = curl_init($url);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $data);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);$response = curl_exec($ch);//        if ($response === false) {//            echo 'Curl error: ' . curl_error($ch);//        } else {//            echo 'Response: ' . $response;//        }curl_close($ch);}}

3.前端例子

<!DOCTYPE html>
<html><head><title>WebSocket Example</title><script>// 创建WebSocket连接  var socket = new WebSocket("ws://47.94.223.188:24222");// 连接打开时触发的事件处理函数  socket.onopen = function(event) {console.log("连接已建立");};// 发送消息到服务器  function sendMessage() {var messageInput = document.getElementById("message");var message = messageInput.value;//获取自己的client_idvar me_client_id = document.getElementById("me_client_id").value;//发送信息 var send_message = {'operation_type': 'send_message','send_client_id': me_client_id,//'send_uid': me_client_id,'to_uid': 'w001', 'openid': 1,'content_type': 'text','content': message,}const jsonString = JSON.stringify(send_message);socket.send(jsonString);// messageInput.value = "";}// 接收到消息时触发的事件处理函数  socket.onmessage = function(event) {var messageContainer = document.getElementById("message-container");var messageElement = document.createElement("p");//返回数据&处理成数组格式var result = event.data;var jsonObject = JSON.parse(result);//如果类型为 operation_type==login 存一下me_client_idif (jsonObject['operation_type'] == 'login') {var me_client_id = document.getElementById("me_client_id");me_client_id.value = jsonObject.me_client_id;}messageElement.textContent = event.data;messageContainer.appendChild(messageElement);};// 连接关闭时触发的事件处理函数  socket.onclose = function(event) {console.log("连接已关闭");};// 连接发生错误时触发的事件处理函数  socket.onerror = function(error) {console.error("WebSocket 错误: " + error);};</script></head><body><h1>WebSocket Example</h1><input type="text" id="me_client_id"><input type="text" id="message"><button onclick="sendMessage()">发送</button><div id="message-container"></div></body>
</html>

4.拿到client_id 绑定uid

    /*** 获取所有在线人数* @return array* https://kf1***om/api/wxapp/send/get_all_uid_list*/public function get_all_uid_list(){$restult = Gateway::getAllUidList();dump($restult);exit();}/*** client_id与uid绑定* 传入自己的client_id和openid,自动绑定为w+用户id  例如w1,w2,w100005* @return array* https://kf****om/api/wxapp/send/bind_uid*/public function bind_uid(){$client_id = '7f0000010b5400000004';$uid       = 'w002';Gateway::bindUid($client_id, $uid);dump(cmf_random_string(100, 3));exit();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/231762.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件验收测试计划、验收测试报告案例模板参考

1. 概述 1.1. 编写目的 1.2. 测试背景 1.3. 测试依据 1.4. 测试对象 1.5. 测试资源 2. 测试方式与环境 2.1. 测试方式 2.2. 测试环境 3. 测试结果 3.1. 功能适合性和准确性 3.1.1. 总体统计 3.1.2. 详细结果 3.2. 安全性 3.3. 可靠性和性能 4. 总体分析 5. 测试…

bat批处理文件_输出内容到文本

文章目录 1、echo str > test.txt&#xff08;覆盖原有内容&#xff09;2、echo str >> test.txt&#xff08;不覆盖原有内容&#xff0c;追加&#xff09; 1、echo str > test.txt&#xff08;覆盖原有内容&#xff09; 2、echo str >> test.txt&#xff0…

Spring Cloud Gateway 缓存区异常

目录 1、问题背景 2、分析源码过程 3、解决办法 最近在测试环境spring cloud gateway突然出现了异常&#xff0c;在这里记录一下&#xff0c;直接上干货 1、问题背景 测试环境spring cloud gateway遇到以下异常 DataBufferLimitException: Exceeded limit on max bytes t…

Docker nginx容器代理播放m3u8视频文件(HLS)

文章目录 Docker Nginx容器代理播放M3U8文件教程获取Nginx Docker镜像设置Nginx配置文件用 ffmpeg 将 MP4 文件转换成 m3u8 文件运行Docker容器测试M3U8流其他问题我用vlc都能播放http://192.168.121.50/forest4kTest.m3u8和http://192.168.121.50/forest4kTest.mp4&#xff0c…

【HBase】——优化

1 RowKey设计 重要&#xff1a;一条数据的唯一标识就是 rowkey&#xff0c;那么这条数据存储于哪个分区&#xff0c;取决于 rowkey 处于 哪个一个预分区的区间内&#xff0c;设计 rowkey的主要目的 &#xff0c;就是让数据均匀的分布于所有的 region 中&#xff0c;在一定程度…

HTML 使用 ruby 给汉字加拼音

使用 ruby 给汉字加拼音 兼容性 使用 ruby 给汉字加拼音 大家有没有遇到过要给汉字头顶上加拼音的需求? 如果有的话, 你是怎么解决的呢? 如果费尽心思, 那么你可能走了很多弯路, 因为 HTML 原生就有这样的标签来帮我们实现类似的需求. <ruby> ruby 本身是「红宝石」…

大学物理-实验篇——测量误差与数据处理(测量分类、误差、有效数字、逐差法)

目录 测量分类 测量次数角度 测量条件角度 误差 误差分类 系统误差 随机误差 异常值 误差描述 精密度&#xff08;Precision&#xff09; 正确度&#xff08;Trueness&#xff09; 准确度/精确度&#xff08;Accuracy&#xff09; 随机误差的处理 直接测量 算术…

一起玩儿物联网人工智能小车(ESP32)——27. 旋转编码器的使用方法

摘要&#xff1a;本文介绍旋转编码器的使用方法 旋转编码器是一种机电设备&#xff0c;可将轴或轴的角位置或运动转换为模拟或数字输出信号&#xff0c;在工业控制中发挥着举足轻重的作用。旋转编码器目前被广泛的应用在数控机床、印刷设备、包装机械、输送带、电梯、机器人、风…

WeNet语音识别+Qwen-72B-Chat Bot+Sambert-Hifigan语音合成

WeNet语音识别Qwen-72B-Chat Bot&#x1f47e;Sambert-Hifigan语音合成 简介 利用 WeNet 进行语音识别&#xff0c;使用户能够通过语音输入与系统进行交互。接着&#xff0c;Qwen-72B-Chat Bot作为聊天机器人接收用户的语音输入或文本输入&#xff0c;提供响应并与用户进行对话…

Docker overlay2文件busy,容器不能删除问题解决

文章目录 在删除docker容器的时候报错,说设备正忙通过 docker ps -a 查看有两个状态的dead的容器解决方法&#xff1a;1.查看所有挂载的设备2.截取设备的进程id3.清理进程(kill掉即可) 在删除docker容器的时候报错,说设备正忙 Error response from daemon: Driver overlay2 fai…

【ARMv8架构系统安装PySide2】

ARMv8架构系统安装PySide2 Step1. 下载Qt资源包Step2. 配置和安装Qt5Step3. 检查Qt-5.15.2安装情况Step4. 安装PySide2所需的依赖库Step5. 下载和配置PySide2Step6. 检验PySide2是否安装成功 Step1. 下载Qt资源包 if you need the whole Qt5 (~900MB): wget http://master.qt…

Meshlab界面和菜单初步认识

文章目录 界面认识菜单 界面认识 顾名思义&#xff0c;MeshLab即网格实验室&#xff0c;用于处理三维对象&#xff0c;并有着针对网格基于网格操作的各种工具&#xff0c;是一个功能强大的三维几何处理系统。因其开源&#xff0c;直接搜官网下载即可。安装过程无坑&#xff0c…

vue icon 本地正常 线上打包失败变乱码

出现这个原因是因为sass解析的问题 Node版本高的话可以通过升级sass版本 并且配置vue.config规避这个问题 //给sass配置的东西 这个对应的版本是sass 1.39.0 本人node版本v14 升级sass版本后出现报错css: {loaderOptions: {scss: {additionalData: import "/styles/var…

C#,入门教程(10)——常量、变量与命名规则的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(09)——运算符的基础知识https://blog.csdn.net/beijinghorn/article/details/123908269 C#用于保存计算数据的元素&#xff0c;称为“变量”。 其中一般不改变初值的变量&#xff0c;称为常变量&#xff0c;简称“常量”。 无论…

nginx 二、配置域名

文章目录 一、配置本地域名查看虚拟机ip修改hosts文件测试域名是否配置成功 二、配置aliyun域名三、实践1.创建html2.配置nginx3.测试服务器内部测试页面测试 总结 docker中启动nginx容器完成如下操作&#xff0c;对于docker安装nginx可以看这篇文章 nginx 一、安装与conf浅析 …

zookeeper应用场景之分布式的ID生成器

1. 分布式ID生成器的使用场景 在分布式系统中&#xff0c;分布式ID生成器的使用场景非常之多&#xff1a; 大量的数据记录&#xff0c;需要分布式ID。大量的系统消息&#xff0c;需要分布式ID。大量的请求日志&#xff0c;如restful的操作记录&#xff0c;需要唯一标识&#x…

element中Tree 树形控件实现多选、展开折叠、全选全不选、父子联动、默认展开、默认选中、默认禁用、自定义节点内容、可拖拽节点、手风琴模式

目录 1.代码实现2. 效果图3. 使用到的部分属性说明4. 更多属性配置查看element官网 1.代码实现 <template><div class"TreePage"><el-checkboxv-model"menuExpand"change"handleCheckedTreeExpand($event, menu)">展开/折叠&l…

如何保障集团下达的政策要求有效落地

随着新一轮国企改革的推进&#xff0c;很多国有企业建立了集团化的管控体系。通过集团化经营管理的模式&#xff0c;帮助国有企业凝聚更强的竞争力&#xff0c;集团企业通过资源整合、反向投资、控股、参股等手法创造业务板块之间的协同、互补效应&#xff0c;从而实现战略联动…

gitlab 配置 二

一 环境说明 群晖Nas DS418DELL XPS serverGitlab ce 二 需要实现的功能 外网可以访问&#xff0c;gitlab使用https的方式访问。wiki issue 等都可以上传图片和附件。 三 操作步骤 因为群晖上有证书&#xff0c;并且由群晖做转发功能。因此证书上&#xff0c;采用群晖的证书…

Sqlmap参数设置

Sqlmap参数设置 &#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388; --------------------------------------------注意---------…