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();}
相关文章:
tp5+workman(GatewayWorker) 安装及使用
一、安装thinkphp5 1、宝塔删除php禁用函数putenv、pcntl_signal_dispatch、pcntl_wai、pcntl_signal、pcntl_alarm、pcntl_fork,执行安装命令。 composer create-project topthink/think5.0.* tp5 --prefer-dist 2、配置好站点之后,浏览器打开访问成…...
vscode安装Prettier插件,对vue3项目进行格式化
之前vscode因为安装了Vue Language Features (Volar)插件,导致Prettier格式化失效,今天有空,又重新设置了一下 1. 插件要先安装上 2. 打开settings.json {"editor.defaultFormatter": "esbenp.prettier-vscode","…...
macOS跨进程通信: XPC 创建实例
一:简介 XPC 是 macOS 里苹果官方比较推荐和安全的的进程间通信机制。 集成流程简单,但是比较绕。 主要需要集成 XPC Server 这个模块,这个模块最终会被 apple 的根进程 launchd 管理和以独立进程的方法唤起和关闭, 我们主app 进…...
Ubuntu18.04 升级Ubuntu20.04
文章目录 背景升级方法遇到的问题 背景 因项目环境需要,欲将Ubuntu18.04升级至Ubuntu20.04,参考网上其他小伙伴的方法,也遇到了一个问题,特此记录一下,希望能帮助其他有同样问题的小伙伴。 升级方法 参考:…...
自动化测试怎么做?看完你就懂了。。。
前言 我想应该有很多测试人员应该有这样的疑虑,自动化测试要怎么去做,现在我把自己的一些学习经验分享给大家,希望对你们有帮助,有说的不好的地方,还请多多指教! 对于测试人员来说,不管进行功…...
小秋SLAM入门实战opencv所有文章汇总
opencv_core和 opencv_imgcodecs是 OpenCV(开源计算机视觉库)的两个主要模块 【如何使用cv::erode()函数对图像进行腐蚀操作】 头文件用途 用OpenCV创建一张类型为CV_8UC1的单通道随机灰度图像 用OpenCV创建一张灰度黑色图像并设置某一列为白色 OpenCV创…...
2023年终总结(脚踏实地,仰望星空)
回忆录 2023年,经历非常多的大事情,找工作、实习、研究生毕业、堂哥结婚、大姐买车、申博、读博、参加马拉松,有幸这一年全家人平平安安,在稳步前进。算是折腾的一年,杭州、赣州、武汉、澳门、珠海、遵义来回跑。完成…...
Transforer逐模块讲解
本文将按照transformer的结构图依次对各个模块进行讲解: 可以看一下模型的大致结构:主要有encode和decode两大部分组成,数据经过词embedding以及位置embedding得到encode的时输入数据 输入部分 embedding就是从原始数据中提取出单词或位置&…...
macOS进程间通信的常用技术汇总
macOS进程间通信的常用技术汇总 命令行传参。yyds管道(pipe), 匿名管道, c的技术,可以跨平台使用 只能在父子进程间通信,由于是单向的管道,只能单方面传输数据。 如果需要双向传输,需要建立双向的两条管道才行 匿名管…...
高德地图信息窗体设置
1. 添加默认信息窗体 //构建信息窗体中显示的内容var info [];info.push(<div style"height: 36px; line-height: 45px; padding: 0px 20px; white-space:nowrap;">位置:北京</div>);info.push(<div style"height: 36px; line-heig…...
isEmpty 和 isBlank 的用法区别,居然一半的人答不上来.....
isEmpty 和 isBlank 的用法区别 isEmpty系列isBank系列 hi!我是沁禹~ 也许你两个都不知道,也许你除了isEmpty/isNotEmpty/isNotBlank/isBlank外,并不知道还有isAnyEmpty/isNoneEmpty/isAnyBlank/isNoneBlank的存在, come on ,让我们一起来探索org.apache…...
数据分析求职-简历准备
简历在整个求职过程中的重要性不言而喻,今天咱们来聊求职过程中简历准备的那些事儿~ 1. 简历究竟有啥用 求职的流程简单说就是:网申->笔试->面试->offer 其中网申环节,简历100%决定了你的通过与否,这个点大家都知道。…...
亚马逊店铺遇到账号申诉模版分享
1.表达诚意,先认错再说:我知道,最近我们在Amazon.com上作为卖家的表现已经低于亚马逊和我们自己的质量标准。 2.清楚分明的格式:我们库存管理的混乱导致了延迟发货,更糟糕的是,物品无法使用。当延迟发货和…...
2023年广东省网络安全A模块(笔记详解)
模块A 基础设施设置与安全加固 一、项目和任务描述: 假定你是某企业的网络安全工程师,对于企业的服务器系统,根据任务要求确保各服务正常运行,并通过综合运用登录和密码策略、流量完整性保护策略、事件监控策略、防火墙策略等多…...
竞赛保研 基于机器视觉的银行卡识别系统 - opencv python
1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的银行卡识别算法设计 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng…...
书摘:C 嵌入式系统设计模式 04
本书的原著为:《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》,讲解的是嵌入式系统设计模式,是一本不可多得的好书。 本系列描述我对书中内容的理解。 实现类的最简单方法是使用文件作为封装…...
C 练习实例16 - 最大公约数和最小公倍数
题目:输入两个正整数a和b,求其最大公约数和最小公倍数 数学:最大公约数*最小公倍数a*b 例如:a16,b20。最小公倍数80,最大公约数4。80*416*20。 算法:辗转相除法,又称欧几里德算法…...
GAN-概念和应用场景
概念和应用 生成对抗网络 (GAN) 的 18 个令人印象深刻的应用 by 杰森布朗利 on July 12, 2019 in 生成对抗网络110 鸣叫 共享 生成对抗网络 (GAN) 是一种用于生成建模的神经网络架构。 生成式建模涉及使用模型生成可…...
LeetCode(36)有效的数独 ⭐⭐
请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 注…...
用LCD显示字符‘A‘
#include<reg51.h> //包含单片机寄存器的头文件 #include<intrins.h> //包含_nop_()函数定义的头文件 sbit RSP2^0; //寄存器选择位,将RS位定义为P2.0引脚 sbit RWP2^1; //读写选择位,将RW位定义为P2.1引脚 sbit EP2^2; //使能…...
Zookeeper相关问题及答案(2024)
1、ZooKeeper是什么?它的主要用途是什么? ZooKeeper 是一个由 Apache 预先开发和维护的开源服务器,用于协调分布式应用程序。它是一个集中式服务,为分布式应用提供一致性保障,配置管理,命名,同…...
1.大数据概述
目录 概述hadoophadoop 模块hadoop 发行版apache社区版本CDP(CDHHDP)其它云产商框架选择 hadoop 安装 结束 概述 先了解几个常用的网站 apache 官网hadoop 官网hadoop githubhttps://github.com/apache/xxx [https://github.com/apache/spark (example)] hadoop hadoop 模块…...
NGUI基础-Widget
目录 Widget是什么 Widget组件包含的属性 Pivot Depth Size snap Aspect Free Based on Width Based on Height Widget是什么 在Unity UI系统中,"Widget"是指UI元素的基类,它为UI元素提供了位置、大小和锚点等基本属性。通过使用&qu…...
SpringBoot集成沙箱支付
前言 支付宝沙箱支付(Alipay Sandbox Payment)是支付宝提供的一个模拟支付环境,用于开发和测试支付宝支付功能的开发者工具。在真实的支付宝环境中进行支付开发和测试可能涉及真实资金和真实用户账户,而沙箱环境则提供了一个安全…...
BUUCTF--gyctf_2020_borrowstack1
这是一题栈迁移的题目,先看看保护: 黑盒测试: 用户可输入两次内容,接着看看IDA中具体程序流程: 我们看到溢出内容只有0x10的空间给我们布局,这显然是不足以我们布置rop的。因此肯定就是栈迁移了。迁到什么地…...
图像分割-Grabcut法(C#)
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 本文的VB版本请访问:图像分割-Grabcut法-CSDN博客 GrabCut是一种基于图像分割的技术,它可以用于将图像中的…...
C# WPF上位机开发(Web API联调)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 很多时候,客户需要开发的不仅仅是一个上位机系统,它还有其他很多配套的系统或设备,比如物流小车、立库、数字孪…...
c语言:用结构体求平均分|练习题
一、题目 用c语言的结构体,求4位学生成绩的平均分 如图: 二、代码截图【带注释】 三、源代码【带注释】 #include <stdio.h> float aver();//声明平均分函数 void printScore();//声明打印函数 //设置结构体, struct student { …...
echarts 仪表盘进度条 相关配置
option {series: [{type: gauge,min: 0,//最大值max: 100, //最小值startAngle: 200,//仪表盘起始角度。圆心 正右手侧为0度,正上方为90度,正左手侧为180度。endAngle: -20,//仪表盘结束角度splitNumber: 100, //仪表盘刻度的分割段数itemStyle: {color…...
Simpy:Python之离散时间序列仿真
Simpy:Python之离散时间序列仿真 文章目录 Simpy:Python之离散时间序列仿真简介基本使用语法简单案例在数据中心中的应用案例 简介 下载地址网站: https://pypi.org/project/simpy/ 有关教程网站: https://simpy.readthedocs.…...
深圳品牌网站开发/推广app赚钱
一对多 示例场景: 用户与其发布的帖子(用户表与帖子表)角色与所属于该角色的用户(角色表与多用户表)示例代码class Role(db.Model):"""角色表"""__tablename__ rolesid db.Column(db.Integer, primary_keyTrue)name db.Column(db.…...
删除wordpress文章日期/百度关键词推广方案
一、目的 减少操作系统安装过程中人机交互过程,实现选择光盘安装后,无需其他人机交互过程即可自动完成操作系统的安装。 二、环境和软件工具 环境:Linux Ubuntu/CentOS操作系统(其他发行版未作尝试) 软件ÿ…...
上海高端网站建设公/外贸网站搭建
8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?linux除了正常的rwx权限外,还有一类附加权限。即:SET位权限(suid、sgid)&粘滞位权限(sticky)SET位权限set位权限(suid、sgid)是为了使“…...
上海做网站好的公司/淄博搜索引擎优化
归并排序(Merge Sort)是一种基于分治思想的排序算法,它将待排序数组分成两个子数组,然后对这两个子数组分别进行排序,最后将两个已排序的子数组合并成一个有序数组。归并排序是一种稳定的排序算法,具体体现…...
固原网站建设/武汉百度推广seo
Jmail控件的操作很简单,实现收发邮件只需几行代码,但经常会有人遇到收邮件时,部分内容是乱码的问题,比如读取别人转发的邮件时,经过我的测试,所有转发邮件Jmail都未能正常读取。是什么原因呢?见…...
成都网站建设网络公司/营销网站做的好的公司
最近在学习lua,使用的过程中每次都会查资料,刚好在博客园上看一位朋友的分享,为了节省时间直接复制过来了,感谢这位朋友的分享到 http://www.cnblogs.com/whiteyun/category/203671.html table.concat(ta…...