当前位置: 首页 > news >正文

Linux服务器 部署飞书信息发送服务

项目介绍:

飞书信息发送服务是指将飞书信息发送服务部署到一个Linux服务器上。飞书是一款企业级的即时通讯和协作工具,支持发送消息给飞书的功能。通过部署飞书信息发送服务,可以方便内网发送信息给外网飞书。

项目代码结构展示:

文件结构解释:

  • common文件夹保存了一些基础运行文件。

  • api.py通过调用飞书开放平台的API获取租户访问令牌,其中调用了飞书的url接口。

  • logs.py将日志数据保存到文件夹logs中。

  • send_message.py实现使用飞书开放平台的API发送消息给指定用户。

  • logs文件夹保存的是消息传递过程中产生的日志信息。

  • other文件夹保存有可转换文件的部分程序,供后续开发使用。

  • static文件夹保存有html文件需要调用的css、js和json文件等配置文件。

  • templates文件夹保存有index.html文件,即网页运行文件。

  • app.py文件是整个项目的运行文件,实现了一个简单的web应用程序,用户可以通过表单提交消息,并将消息发送给另一个模块进行处理。同时,在后台记录了用户的IP地址、ID、消息和用户名等信息。 

项目代码解释:

1. api.py代码解释:

'''该代码的作用是使用飞书开放平台的 API 获取应用的访问令牌(tenant_access_token),并将其打印出来。该代码通过发送HTTP POST请求,获取飞书应用的访问令牌,并将结果打印出来,以便后续使用该令牌来访问飞书开放平台的其他API。
'''# 导入requests模块。
import requests# 飞书信息传入接口
# 定义了请求的URL,该URL用于获取应用的访问令牌。
url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'# 定义了请求的头部,指定Content-Type为application/json。
headers = {'Content-Type': 'application/json'
}# 定义了请求的数据,包括应用的app_id和app_secret。
# 得从飞书集成平台上创建一个飞书服务,从而获得其中的参数
data = {# 请求参数(从飞书内部app获得)"app_id": "cli_a5cb1xxxxxxxxxxxxx","app_secret": "qNFmmFTQqexxxxxxxxxxxxxxxxxxxxxxx"
}# 发送POST请求,将URL、头部和数据传递给requests.post()函数,并将返回的响应对象保存在response变量中。
response = requests.post(url, headers=headers, json=data)# 检查响应的状态码,如果状态码为200,则表示请求成功,继续执行下一步;否则打印请求失败的提示信息。
if response.status_code == 200:# 请求成功# 将响应的内容解析为JSON格式,保存在result变量中。result = response.json()# 处理返回结果print(result)
else:# 请求失败print('请求失败:', response.status_code)

2. logs.py代码解释:

'''该代码是一个日志收集的函数。函数名为log,接受四个参数:ip、user_id、message和username。代码的作用是将传入的日志信息保存到以年份为文件名的文件夹中的以日期为文件名的文件中。
'''
import os
import datetime# log 日志收集
def log(ip,user_id,message,username):# 获取当前时间,格式为小时-分钟-秒钟,保存到变量date中。date = datetime.datetime.now().strftime("%H-%M-%S")data = f"ip:{ip}, username:{username}, user_id:{user_id}, date:{date}, message:{message}\n"# 创建保存年文件夹的文件夹# 根据当前时间获取年份,并创建保存年份文件夹的文件夹路径,保存到变量year_folder_name中。year_folder_name = f"./logs/"+datetime.datetime.now().strftime("%Y")# 创建保存数据的文件夹和文件名# 根据当前时间获取日期,并创建保存数据的文件夹路径,保存到变量folder_name中。folder_name = f"./{year_folder_name}/"+datetime.datetime.now().strftime("%m-%d")# 如果年份文件夹路径不存在,则创建年份文件夹。if not os.path.exists(year_folder_name):os.makedirs(year_folder_name, exist_ok=True)# 如果数据文件夹路径不存在,则创建数据文件夹。if not os.path.exists(folder_name):os.makedirs(folder_name, exist_ok=True)# 根据当前时间获取文件名,并将文件路径保存到变量filepath中。file_name = datetime.datetime.now().strftime("%H-%M") + ".txt"# 检查文件是否存在#    - 如果存在,则以追加模式打开文件,并将日志信息写入文件中。#    - 如果不存在,则以写入模式创建新文件,并将日志信息写入文件中。filepath = os.path.join(folder_name, file_name)if os.path.exists(filepath):with open(filepath, "a") as file:file.write(data)else:with open(filepath, "w") as file:file.write(data)

3. send_message.py代码解释:

'''该代码实现了使用飞书开放平台的API发送消息给指定用户。
'''import json
import requests# `get_access_token`函数用于获取tenant_access_token,即应用的访问令牌,通过传入应用的app_id和app_secret作为参数,向飞书的API发送请求并返回响应结果。
def get_access_token(app_id, app_secret):"""自建应用获取 tenant_access_tokenhttps://open.feishu.cn/document/server-docs/authentication-management/access-token/tenant_access_token_internal:param app_id: 应用唯一标识:param app_secret: 应用秘钥:return:{"code": 0,"msg": "success","tenant_access_token": "t-xxx","expire": 7140}"""url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'params = {'app_id': app_id,'app_secret': app_secret}res = requests.post(url, params=params)return res.json()# `send_message`函数用于发送消息,通过传入访问令牌、消息体和查询参数作为参数,向飞书的API发送请求并返回响应结果。
def send_message(access_token, body, params):"""发送消息https://open.feishu.cn/document/server-docs/im-v1/message/create:param access_token::param body: 消息体:param params: 查询参数 {"receive_id_type":"open_id"}:return:"""url = 'https://open.feishu.cn/open-apis/im/v1/messages'headers = {'Authorization': 'Bearer ' + access_token}res = requests.post(url, params=params, headers=headers, json=body)return res.json()# `run`函数是主函数,用于执行发送消息的操作。首先获取访问令牌,然后设置查询参数为"user_id",接下来构造消息体,包含接收消息的用户ID和消息内容。最后调用`send_message`函数发送消息,并输出响应结果。
def run(message,user_id):# App IDapp_id = 'cli_a5cb1xxxxxxxxxxxxxxxx'# App Secretapp_secret = 'qNFmmFTQqecZtgjbxxxxxxxxxxxxxxx'token = get_access_token(app_id, app_secret)params = {"receive_id_type": "user_id"}# 发送接口消息payload = {"receive_id": user_id,"msg_type": "text","content": json.dumps({"text": message})}# 获取tenant_access_tokenres = send_message(token['tenant_access_token'], payload, params)print(res)

4. app.py代码解释:

'''该代码是一个简单的Flask应用程序,用于接收用户的表单数据,记录日志并发送消息给用户。用户可以通过根路径访问一个包含表单的页面,并填写表单后,提交数据到/process路径。服务器接收到数据后记录日志,并向用户发送消息。
'''
from flask import Flask, request, render_template
from common import send_message, logs# - Flask:用于创建Web应用程序的框架。
# - request:用于处理HTTP请求的模块。
# - render_template:用于渲染模板的模块。
# - send_message:自定义的模块,用于发送消息。
# - logs:自定义的模块,用于记录日志。# 定义全局变量
user_id = ''
message = ''
# 创建Flask应用程序实例:
app = Flask(__name__)# 定义路由和视图函数:
#  - 定义根路径'/'的视图函数index。
#  - 使用render_template函数渲染名为index.html的模板,并传递icon_path参数。
@app.route('/')
def index():icon_path = '/static/icon.ico'return render_template("index.html", icon_path=icon_path)# 定义/process路由和视图函数:
#  - 定义/process路径的视图函数process。
#  - 通过request.form.get方法获取POST请求中的字段值。
#  - 获取用户ID、消息内容、用户名和IP地址。
#  - 调用logs.log方法记录日志。
#  - 调用send_message.run方法发送消息。
#  - 返回收到的用户ID、消息内容和IP地址。
@app.route("/process", methods=['POST'])
def process():user_id = request.form.get('user_id')message = request.form.get('message')username = request.form.get('username')ip = request.remote_addrlogs.log(ip,user_id,message,username)send_message.run(message, user_id)return f'Received: {user_id},{message},{ip}'# 启动应用程序:
#  - 判断当前模块是否为主模块。
#  - 如果是主模块,则调用app.run方法启动应用程序,监听0.0.0.0:80地址。
#  - 0.0.0.0表示监听所有的IP地址,80为端口号。
if __name__ == '__main__':app.run(host="0.0.0.0", port=80)

5. excel_to_json.py代码解释

import openpyxl
import json
import io
# excel表格转json文件
def excel_to_json(excel_file, json_file_name):# 加载工作薄book = openpyxl.load_workbook(excel_file)# 获取sheet页sheet = book["文件名xxxxxxxxx"]# 行数max_row = sheet.max_row# 列数max_column = sheet.max_columnprint("max_row: %d, max_column: %d" % (max_row, max_column))# 结果,数组存储result = []heads = []# 解析表头for column in range(max_column):# 读取的话行列是从(1,1)开始heads.append(sheet.cell(1, column + 1).value)# 遍历每一行for row in range(max_row):if row == 0:continueone_line = {}for column in range(max_column):# 读取第二行开始每一个数据k = heads[column]cell = sheet.cell(row + 1, column + 1)value = cell.valueone_line[k] = valueprint(one_line)new_one_line = {'人员ID': one_line['人员ID'],'工号': one_line['工号'],'员工类型':one_line['员工类型'],'人员姓名': one_line['人员姓名'],'职务':one_line['职务']
}result.append(new_one_line)book.close()# 将result通过大括号包裹起来result_json = {'data': result}# 将json保存为文件save_json_file(result_json, json_file_name)# 将json保存为文件
def save_json_file(jd, json_file_name):file = io.open(json_file_name, 'w', encoding='utf-8')# 把对象转化为json对象# indent: 参数根据数据格式缩进显示,读起来更加清晰# ensure_ascii = True:默认输出ASCII码,如果把这个该成False, 就可以输出中文。txt = json.dumps(jd, indent=2, ensure_ascii=False)file.write(txt)file.close()if '__main__' == __name__:# 运行该程序使Excel文件内容转换为json文件excel_to_json(u'Excel文件.xlsx', '../static/json/result.json')

6. index.css代码解释

这段代码实现了一个基于弹性布局的聊天界面。代码中使用了CSS样式来设置页面的布局和样式。
`padding`和`box-sizing`为`border-box`来统一元素的盒模型。
`.text`类来设置文本的样式,包括字体大小、字重、字体样式和颜色。
`.box`类来设置聊天界面的背景样式和弹性布局。背景采用了渐变色,并设置了背景动画。同时设置了最小高度和居中对齐。
`@keyframes`规则来设置背景动画的关键帧。
`.box h2`类来设置标题样式。
`.chat-message`类来设置聊天消息框的样式,包括宽高、边框样式、背景样式、字体大小和颜色等。
`.chat-message .new-message`类来设置新消息框的样式,包括外边距、内边距、背景样式、字体大小和颜色等。
`.chat-message .new-message .daytime`和`.chat-message .new-message .messagebox`类来设置新消息框中的日期和消息内容的样式。
`.inputBox`类来设置输入框的样式,包括宽度和位置。
`.inputBox textarea`类来设置文本输入框的样式,包括宽高、边框样式、背景样式、字体大小和颜色等。
`.inputBox span`类来设置输入框中的提示文字的样式。
`:valid`和`:focus`来设置输入框验证状态下的样式。
`.buttonBox button`类来设置按钮的样式,包括内边距、边框样式、背景样式、字体大小和颜色等。
`:hover`来设置鼠标悬停状态下按钮的样式。
`.selectBox`类来设置下拉选框的样式,包括字体大小、边框样式和颜色等。
*{padding: 0;box-sizing: border-box;
}
.text {font-size: 20px;font-weight: 100;font-style: italic;color:rgb(136, 204, 244);padding-bottom: 3px;
}
/* 弹性布局 水平+垂直居中 */
.box{background-image: linear-gradient(125deg,#0d98d3,#27ae60,#1782ca,#a720e0,#e74c3c);background-size: 400%;animation: bgmove 30s infinite;min-height: 100vh;display: flex;justify-content: center;align-items: center;flex-direction: column;user-select: none;padding: 1.5rem;gap: 15px;
}@keyframes bgmove {0%{background-position: 0% 50%;}50%{background-position: 100% 50%;}100%{background-position: 0% 50%;}50%{background-position: 100% 50%;}0%{background-position: 0% 50%;}
}.box h2{color: rgb(136, 204, 244);font-style: oblique;font-size: 30px;padding-top: 60px;
}.chat-message {width: 700px; /* 设置宽度 */height: 400px; /* 设置高度 */border: 2px solid rgba(255, 255, 255, 0.5);background: #ffffff00;border: 5px;outline: none;font-size: 1em;color: white;box-shadow: 0px 0px 10px #b3bed3 inset;font-family: Arial, sans-serif; /* 字体 */border-radius: 5px; /* 边框圆角 */transform: translateX(20px); /* 将div元素向右移动50像素 */overflow: auto;
}.chat-message .new-message{margin: 10px;padding: 3px;margin-top: 20px;margin-bottom: 23px;width: fit-content;background: #ffffff00;border: 5px;outline: none;font-size: 1em;color: white;font-family: Arial, sans-serif; /* 字体 */border-radius: 5px; /* 边框圆角 */-webkit-user-select: text; /* Safari */-moz-user-select: text; /* Firefox */-ms-user-select: text; /* IE10+/Edge */user-select: text; /* Standard */position: relative;
}.chat-message .new-message .daytime{font-size: 13px;position: absolute;top: -15px; /* 上移10像素 */
}.chat-message .new-message .messagebox{font-size: 21px;
}.inputBox{position: relative;width: 300px;
}.inputBox textarea {width: 700px; /* 设置宽度 */height: 200px; /* 设置高度 */resize: none; /* 禁止拖拽改变大小 */border: 2px solid rgba(255, 255, 255, 0.5);background: #ffffff00;border: 5px;outline: none;font-size: 1em;transition: 0.3s;color: white;box-shadow: 0px 0px 10px #b3bed3 inset;font-family: Arial, sans-serif; /* 字体 */border-radius: 5px; /* 边框圆角 */margin-left: -180px;}.inputBox span{position: relative;top: -10px;position: absolute;left: -180px;padding: 20px;pointer-events: none;font-size: 1em;color: #fefefefe;text-transform: uppercase;transition: 0.3s;
}.inputBox textarea:valid~span,
.inputBox textarea:focus~span{color: #15dede;transform: translateX(15px) translateY(-7px);font-size: 0.65em;padding: 0 5px;background: #15acde5c;letter-spacing: 0.1em;
}.inputBox textarea:valid,
.inputBox textarea:focus{border: 1px solid #20bdce00;
}/* 按钮样式 */
.buttonBox button{padding: 10px;border-radius: 5px;background: rgba(13, 98, 132, 0);font-size: 1em;color: rgba(255, 255, 255, 0.5);border: 1px solid rgba(255, 255, 255, 0.5);font-weight: 600;box-shadow: 0px 0px 10px #dadfeb inset;}.buttonBox button:hover{color: #d5dede;border: 1px solid #50c9c3;
}.selectBox{color: rgba(255, 255, 255, 0.5);border: 1px solid rgba(255, 255, 255, 0.5);letter-spacing: 0.1em;font-size: 1em;border: 5px;text-overflow: ellipsis;overflow: hidden;white-space: nowrap;
}.selectBox span{font-size: 20px;color: white;margin: 13px -5px 0px 20px;
}.selectBox .select{font-size: 1em;background-color: rgba(254, 254, 254, 0.055);color: #f9f7c7;width: 160px;height: 35px;margin: 10px 0 0 10px;padding-left: 10px;border: none;box-shadow: 0px 0px 10px #b4c0d6 inset;font-family: Arial, sans-serif; /* 字体 */border-radius: 5px; /* 边框圆角 */
}.selectBox option {background-color: #3ebaef;
}

7. result.json代码解释

目的是用于保存发送人员数据信息

{"data": [{"人员ID": "417xxx","工号": "22xx","部门列表": "xx","直属上级": "xx","职务": "xxxx"}]
}

实现飞书信息发送服务在Linux服务器上部署

1. 准备环境:确保你的Linux服务器满足以下系统要求:

  • 系统:CentOS 7.x 或更高版本

  • 内存:4GB 以上

  • 存储:至少 1GB 可用硬盘空间

  • 网络:能够访问互联网(目的是能够访问飞书接口,可以是外网虚拟机)

2. Linux配置项目环境:

检查是否已安装Python 3.6:

$ python3 --version

如果返回Python 3.6.x的版本信息,说明已安装Python 3.6。

如果未安装Python 3.6,可使用以下命令来安装:

$ sudo apt update$ sudo apt install python3.6

检查是否安装成功:

$ python3.6 --version

确认Python安装路径:

$ which python3.6

默认路径为:/usr/bin/python3.6

安装Python包管理工具pip:

$ sudo apt install python3-pip

检查是否安装成功: 

$ pip3 --version

现在,Python 3.6环境已在Linux系统上安装完毕。

您可以使用python3.6命令来启动Python 3.6解释器,并使用pip3来安装/管理Python包。

项目依赖需求导入

将项目所需的依赖需求导入requirements.txt文件中,方便后续在Linux环境下下载配置(在终端运行)

pip freeze > requirements.txt

该命令可以将当前pycharm使用的(也可以在linux系统中使用): python解释器中的依赖包全部收集到requements.txt 文件中,为了避免收集无用的依赖包,建议给 目标项目使用虚拟环境解释器,这样就只会收集到当前项目的依赖包了。(最好在哪里创建项目就在那里使用)

3.项目部署

通过Xshell连接Linux虚拟机,再通过Xftp传输文件到Linux虚拟机上去:

Xshell官方下载网站:https://www.xshell.com/zh/all-downloads/

(Xshell通过ssh的方式连接的,Xftp通过ftp的方式连接的,可以在网上下载使用,也可用其他软件替代)

将项目移动到指定项目文件夹,可以使用mv命令来实现

mv python_Project /usr/local/feishuconnect/

查看效果:

[root@proxy-cuhnj-local admin]# ls /usr/local/feishuconnect/
python_Project

项目Linux环境依赖安装:

  • 安装项目的依赖包(requements.txt为项目收集的依赖包地址)

pip install -r requements.txt 

如果对应的Linux环境中未配置国内镜像源,导致依赖包安装缓慢,可以通过命令

pip install -i 国内镜像源地址 -r requements.txt 安装项目依赖包

  • 国内比较常用的镜像:

pip 默认源:https://pypi.python.org/simple

1.豆瓣(douban) Simple Indexicon-default.png?t=N7T8https://pypi.douban.com/simple 2.清华大学 Simple Indexicon-default.png?t=N7T8https://pypi.tuna.tsinghua.edu.cn/simple 3.阿里云 Simple Indexicon-default.png?t=N7T8https://mirrors.aliyun.com/pypi/simple 4.中国科技大学 Simple Indexicon-default.png?t=N7T8https://pypi.mirrors.ustc.edu.cn/simple

项目依赖安装完成后,打开防火墙并运行测试效果

打开服务器的防火墙8081端口

Sudo firewall-cmd --add-port=443/tcp --permanent  # 打开服务器8081端口
sudo firewall-cmd --reload         # 刷新防火墙策略
sudo firewall-cmd --list-all       # 查看 firewall 防火墙允许访问端口列表
Sudo firewall-cmd --remove-port=443/tcp --permanent   # 关闭服务器8081端口

通过python3 app.py命令来测试效果:

python3  app.py    # 运行程序测试效果

展示如上效果,并且没有报错,则为运行成功,如果报错,可以查看系统日志文件找出错误:

journalctl -xe   #查看系统日志信息

查看项目进程信息,运行状态:

netstat -anpult|grep python

项目Service服务配置:

  • 创建一个Systemd服务配置文件:

sudo vim /etc/systemd/system/feishuconnect.service
  • 在该文件中添加以下内容:

[admin@proxy-cuhnj-local python_Project]$ cat /etc/systemd/system/feishuconnect.service
[Unit]
Description=My FeishuConnect Server[Service]
ExecStart=/usr/bin/python3 /usr/local/feishuconnect/python_Project/app.py
WorkingDirectory=/usr/local/feishuconnect/python_Project/
Restart=always
User=admin
Group=admin[Install]
WantedBy=multi-user.target
[admin@proxy-cuhnj-local python_Project]$ 
  • 保存并关闭文件

  • 使用以下命令来启用并启动Systemd服务:

sudo systemctl enable feishuconnect.service sudo systemctl start feishuconnect.service

这将使您的FeishuConnect服务器在系统启动时自动启动,并且您可以使用Systemd命令来管理它,例如启动、停止、重启或查看状态。

sudo systemctl stop feishuconnect.service # 停止服务 
sudo systemctl restart feishuconnect.service # 重启服务 
sudo systemctl status feishuconnect.service # 查看服务状态

修改:将Service服务修改为80端口

首先先停止Service服务

sudo systemctl stop feishuconnect.service # 停止服务

修改项目内的运行程序app.py (将端口port 修改为 80 端口) 

修改Service服务的权限

由于将服务端口修改为了80(host="0.0.0.0",port=80),而80端口只有特权用户(例如root用户)才能占用。这是因为在低于1024的端口上进行绑定时,只有root用户才有权限。

刷新Service服务,查看Service服务状态

sudo systemctl daemon-reload # 更新Service配置 
sudo systemctl restart feishuconnect.service # 重启服务 
sudo systemctl status feishuconnect.service # 查看服务状态

测试项目效果:

项目代码下载:

链接:https://pan.baidu.com/s/1B7H_3ZZA100aqJnI6p1DwA?pwd=fwvg 
提取码:fwvg

相关文章:

Linux服务器 部署飞书信息发送服务

项目介绍: 飞书信息发送服务是指将飞书信息发送服务部署到一个Linux服务器上。飞书是一款企业级的即时通讯和协作工具,支持发送消息给飞书的功能。通过部署飞书信息发送服务,可以方便内网发送信息给外网飞书。 项目代码结构展示: …...

用C#也能做机器学习?

前言✨ 说到机器学习,大家可能都不陌生,但是用C#来做机器学习,可能很多人还第一次听说。其实在C#中基于ML.NET也是可以做机器学习的,这种方式比较适合.NET程序员在项目中集成机器学习模型,不太适合专门学习机器学习&a…...

Python PDF格式转PPT格式

要将PDF文件转换为PPT,我实在python3.9 环境下转成功的,python3.11不行。 需要 pip install PyMuPDF代码说话 # -*- coding: utf-8 -*-""" author: 赫凯 software: PyCharm file: xxx.py time: 2023/12/21 11:20 """im…...

搭建知识付费平台?明理信息科技为你提供全程解决方案

明理信息科技saas知识付费平台 在当今数字化时代,知识付费已经成为一种趋势,越来越多的人愿意为有价值的知识付费。然而,公共知识付费平台虽然内容丰富,但难以满足个人或企业个性化的需求和品牌打造。同时,开发和维护…...

漫谈UNIX、Linux、UNIX-Like

漫谈UNIX、Linux、UNIX-Like 使用了这么多年Redhat、Ubuntu等Linux、Windows、Solaris操作系统,你是否对UNIX、Unix-Like(类UNIX)还是不太清楚?我以前一直认为Unix-Like就等于Linux。其实,由UNIX派生出来而没有取得UN…...

Netty Review - Netty与Protostuff:打造高效的网络通信

文章目录 概念PrePomServer & ClientProtostuffUtil 解读测试小结 概念 Pre 每日一博 - Protobuf vs. Protostuff&#xff1a;性能、易用性和适用场景分析 Pom <dependency><groupId>com.dyuproject.protostuff</groupId><artifactId>protostuff-…...

在ClickHouse数据库中启用预测功能

在这篇博文中&#xff0c;我们将介绍如何将机器学习支持的预测功能与 ClickHouse 数据库集成。ClickHouse 是一个快速、开源、面向列的 SQL 数据库&#xff0c;对于数据分析和实时分析非常有用。该项目由 ClickHouse&#xff0c; Inc. 维护和支持。我们将探索它在需要数据准备以…...

目标检测YOLO实战应用案例100讲-树上果实识别与跟踪计数(续)

目录 3.2 损失函数优化 3.3 实验过程 3.3.1 果实图像采集 3.3.2 数据扩增...

Docker 文件和卷 权限拒绝

一 创作背景 再复制Docker影像文件或访问Docker容器内已安装卷上的文件时我们常常会遇到&#xff1a;“权限被拒绝”的错误&#xff0c;在此&#xff0c;您将了解到为什么会出现“权限被拒绝”的错误以及如何解决这个问题。 二 目的 在深入探讨 Docker 容器中的 Permission De…...

Appium Server 启动失败常见原因及解决办法

Error: listen EADDRINUSE: address already in use 0.0.0.0:4723 如下图&#xff1a; 错误原因&#xff1a;Appium 默认的4723端口被占用 解决办法&#xff1a; 出现该提示&#xff0c;有可能是 Appium Server 已启动&#xff0c;关闭已经启动的 Appium Server 即可。472…...

将Abp默认事件总线改造为分布式事件总线

文章目录 原理创建分布式事件总线实现自动订阅和事件转发 使用启动Redis服务配置传递Abp默认事件传递自定义事件 项目地址 原理 本地事件总线是通过Ioc容器来实现的。 IEventBus接口定义了事件总线的基本功能&#xff0c;如注册事件、取消注册事件、触发事件等。 Abp.Events…...

Jupyter Notebook修改默认工作目录

1、参考修改Jupyter Notebook的默认工作目录_jupyter文件路径-CSDN博客修改配置文件 2.在上述博客内容的基础上&#xff0c;这里不是删除【%USERPROFILE%】而是把这个地方替换为所要设置的工作目录路径&#xff0c; 3.【起始位置】也可以更改为所要设置的工作目录路径&#x…...

高校/企业如何去做数据挖掘呢?

随着近年来人工智能及大数据、云计算进入爆发时期&#xff0c;依托三者进行的数据分析、数据挖掘服务已逐渐成为各行业进行产业升级的载体&#xff0c;缓慢渗透进我们的工作和生活&#xff0c;成为新时代升级版的智能“大案牍术”。 那么对于多数企业来说&#xff0c;如何做数据…...

数据仓库-数据治理小厂实践

一、简介 数据治理贯穿数仓中数据的整个生命周期&#xff0c;从数据的产生、加载、清洗、计算&#xff0c;再到数据展示、应用&#xff0c;每个阶段都需要对数据进行治理&#xff0c;像有些比较大的企业都是有自己的数据治理平台或者会开发一些便捷的平台&#xff0c;对于没有平…...

【C++多线程编程】(五)之 线程生命周期管理join() 与 detach()

在C中&#xff0c;std::thread 类用于创建和管理线程。std::thread 提供了两种主要的方法来控制线程的生命周期&#xff1a;join 和 detach。 detach方式&#xff0c;启动的线程自主在后台运行&#xff0c;当前的代码继续往下执行&#xff0c;不等待新线程结束。join方式&…...

金融信贷场景的风险“要素”与主要“风险点”

目录 要素一:贷款对象 风险点1:为不具备主体资格或主体资格有瑕疵的借款人发放贷款 风险表现: 防控措施: 风险点2:向国家限控行业发放贷款 风险表现: 防控措施: 风险点3:受理不符合准入条件的客户申请 风险表现: 防控措施: 要素二:金额 风险点4:过渡授…...

ubuntu下docker安装,配置python运行环境

参考自: 1.最详细ubuntu安装docker教程 2.使用docker搭建python环境 首先假设已经安装了docker&#xff0c;卸载原来的docker 在命令行中运行&#xff1a; sudo apt-get updatesudo apt-get remove docker docker-engine docker.io containerd runc 安装docker依赖 apt-get…...

在Docker中安装kafka遇到问题记录

命令含义解答&#xff1a; 在docker安装kafka的时候&#xff0c;启动kafka的时候会执行下面语句&#xff1a; docker run -d --log-driver json-file --log-opt max-size100m --log-opt max-file2 --name kafka -p 9092:9092 -e KAFKA_BROKER_ID0 -e KAFKA_ZOOKEEPER_CONNEC…...

aws-waf-cdn 基于规则组的永黑解决方案

1. 新建waf 规则组 2. 为规则组添加规则 根据需求创建不同的规则 3. waf中附加规则组 &#xff08;此时规则组所有规则都会附加到waf中&#xff0c;但是不会永黑&#xff09; 此刻&#xff0c;可以选择测试下规则是否生效&#xff0c;测试前确认保护资源绑定无误 4. 创建堆…...

如何实现免费无限流量云同步笔记软件Obsidian?

目录 前言 如何实现免费无限流量云同步笔记软件Obsidian&#xff1f; 一、简介 软件特色演示&#xff1a; 二、使用免费群晖虚拟机搭建群晖Synology Drive服务&#xff0c;实现局域网同步 1 安装并设置Synology Drive套件 2 局域网内同步文件测试 三、内网穿透群晖Synol…...

GPTs | Actions应用案例

上篇文章说道&#xff0c;如何使用创建的GPTs通过API接口去获取外部的一些信息&#xff0c;然后把获取的外部信息返回给ChatGPT让它加工出来&#xff0c;回答你的问题&#xff0c;今天我们就来做一个通俗易懂的小案例&#xff0c;让大家来初步了解一下它的使用法&#xff01; …...

Python Opencv实践 - 手势音量控制

本文基于前面的手部跟踪功能做一个手势音量控制功能&#xff0c;代码用到了前面手部跟踪封装的HandDetector.这篇文章在这里&#xff1a; Python Opencv实践 - 手部跟踪-CSDN博客文章浏览阅读626次&#xff0c;点赞11次&#xff0c;收藏7次。使用mediapipe库做手部的实时跟踪&…...

关于Selenium的网页对象单元测试的设计模式

写在前面&#xff1a;经过了实践总结一下经验&#xff0c;心得进行一个分享。 首先driver是可以单独抽出来的&#xff0c;变成一个driver函数放在driver.py。 from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver…...

基于多反应堆的高并发服务器【C/C++/Reactor】(上)

&#xff08;一&#xff09;初始化服务器端用于监听的套接字 Server.h #pragma once // 初始化监听的套接字 int initListenFd(unsigned short port); Server.c int initListenFd(unsigned short port) {// 1.创建监听的fdint lfd socket(AF_INET, SOCK_STREAM, 0);if(lf…...

腾讯云debian服务器的连接与初始化

目录 1. 远程连接2. 软件下载3. 设置开机自启动 1. 远程连接 腾讯云给的服务器在安装好系统之后&#xff0c;只需要在防火墙里面添加一个白名单&#xff08;ip 或者域名&#xff09;就能访问了。 浏览器打开https://www.ipip.net/&#xff0c;在左下角找到自己所用的WIFI的公…...

医保购药小程序:智能合约引领医疗数字革新

在医疗领域&#xff0c;医保购药小程序通过引入智能合约技术&#xff0c;为用户提供更为高效、安全的购药体验。本文将通过简单的智能合约代码示例&#xff0c;深入探讨医保购药小程序如何利用区块链技术中的智能合约&#xff0c;实现医保结算、购药监控等功能&#xff0c;为医…...

神经网络:深度学习优化方法

1.有哪些方法能提升CNN模型的泛化能力 采集更多数据&#xff1a;数据决定算法的上限。 优化数据分布&#xff1a;数据类别均衡。 选用合适的目标函数。 设计合适的网络结构。 数据增强。 权值正则化。 使用合适的优化器等。 2.BN层面试高频问题大汇总 BN层解决了什么问…...

Unity中Shader旋转矩阵(二维旋转矩阵)

文章目录 前言一、旋转矩阵的原理1、我们以原点为中心&#xff0c;旋转坐标轴θ度2、求 P~2x~&#xff1a;3、求P~2y~:4、最后得到 P~2~点 的点阵5、该点阵可以拆分为以下两个矩阵相乘的结果 二、在Shader中&#xff0c;使用该旋转矩阵实现围绕 z 轴旋转1、在属性面板定义 floa…...

前端面试题(计算机网络):options请求方法及使用场景

OPTIONS请求方法及使用场景 回答思路&#xff1a;什么是options请求-->options请求方法-->options使用场景什么是options请求&#xff1f;&#xff08;浅入&#xff09;扩展&#xff1a;常见的HTTP请求有什么&#xff1f;扩展&#xff1a;常见的HTTP请求的作用&#xff1…...

使用docker-compose管理docker服务

使用docker-compose管理docker服务 1&#xff0c;创建docker-compose.yml version: 3 services:javaapp:build: context: ./javaappdockerfile: Dockerfileports:- "9202:9202"- "19202:19202"goapp:build: context: ./goappdockerfile: Dockerfileports…...

快站微信网站制作/免费b站推广软件

最近准备玩一下Oracle Golden Gate&#xff0c;需要搭个新环境&#xff0c;安装过程记录一下。操作系统版本&#xff1a;Oracle Linux Server release 5.7Oracle版本&#xff1a;Oracle Database 11g Release 2 (11.2.0.1.0) for Linux x86一、安装前的环境配置1. 检查官方文档…...

wordpress媒体默认链接/灰色行业推广平台网站

使用 <script setup>组合式 API 的语法糖的时候&#xff0c;defineProps报错&#xff1a; 代码如下&#xff1a; 第一次写vue3的项目&#xff0c;真的是到处都是坑啊&#xff0c;我就不断的百度百度再百度&#xff0c;发现再 module.exports {root: true,env: {node: …...

江山有做网站开发吗/游戏推广合作

ENTER键可以让光标移到下一个输入框 <input οnkeydοwn"if(event.keyCode13)event.keyCode9" >只能是中文 <input οnkeyup"valuevalue.replace(/[ -~]/g,)" οnkeydοwn"if(event.keyCode13)event.keyCode9">屏蔽输入法 <input…...

做棋牌网站要什么源码/做电商如何起步

int ChangeNum(char* str) { char revstr[16]{0}; //根据十六进制字符串的长度&#xff0c;这里注意数组不要越界 int num[16]{0}; int count1; int result0; int length; length strlen(str); memcpy(revstr,"0x",2); memcpy(revstr 2,str,length); length …...

微信公众号网站建设/2345纯净版推广包

原文出处&#xff1a;https://wiki.ubuntu.com/IptablesHowTo 原文作者&#xff1a;UbuntuWiki 授权许可&#xff1a;创作共享协议 GNU FDL 翻译人员&#xff1a;denven 校对人员&#xff1a;5451vs5451 贡献者&#xff1a; 适用版本&#xff1a; 文章状态&#xff1a;翻译完成…...

wordpress小工具文件/南京网络营销服务

原生js实现上拉加载其实超级简单&#xff0c;把原理整明白了你也会&#xff0c;再也不用去引一个mescroll啦~ 好了&#xff0c;废话不多说&#xff0c;开始进入正题&#xff1a;上拉加载是怎么去做的&#xff0c;原理就是监听滚动条滑到页面底部&#xff0c;然后就去做一次请求…...