Merge branch 'main' of git.xiongxiao.me:abearxiong/dnake
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
```sh
|
||||||
|
# 安装 python 环境 ,安装项目
|
||||||
|
uv sync
|
||||||
|
|
||||||
|
uv run python main.py
|
||||||
|
|
||||||
|
pm2 start "uv run app.py" --name "dnake-socket-app"
|
||||||
|
```
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export default defineConfig({
|
|||||||
// 添加 rehype 插件
|
// 添加 rehype 插件
|
||||||
],
|
],
|
||||||
// 启用 MDX 表达式
|
// 启用 MDX 表达式
|
||||||
optimize: true,
|
optimize: true
|
||||||
}),
|
}),
|
||||||
react(), //
|
react(), //
|
||||||
// sitemap(), // sitemap must be site has a domain
|
// sitemap(), // sitemap must be site has a domain
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@kevisual/me-dnake-docs",
|
"name": "@kevisual/me-dnake-docs",
|
||||||
"version": "0.0.1",
|
"version": "0.0.2",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"basename": "/root/me-dnake-docs",
|
"basename": "/root/me-dnake-docs",
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"pub": "envision deploy ./dist -k me-dnake-docs -v 0.0.1 -u",
|
"pub": "envision deploy ./dist -k me-dnake-docs -v 0.0.2 -u -y yes",
|
||||||
"sn": "pnpm dlx shadcn@latest add "
|
"sn": "pnpm dlx shadcn@latest add "
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
@@ -16,39 +16,39 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^4.3.7",
|
"@astrojs/mdx": "^4.3.12",
|
||||||
"@astrojs/react": "^4.4.0",
|
"@astrojs/react": "^4.4.2",
|
||||||
"@astrojs/sitemap": "^3.6.0",
|
"@astrojs/sitemap": "^3.6.0",
|
||||||
"@kevisual/query": "^0.0.29",
|
"@kevisual/query": "^0.0.29",
|
||||||
"@kevisual/query-login": "^0.0.6",
|
"@kevisual/query-login": "^0.0.7",
|
||||||
"@kevisual/registry": "^0.0.1",
|
"@kevisual/registry": "^0.0.1",
|
||||||
"@tailwindcss/vite": "^4.1.14",
|
"@tailwindcss/vite": "^4.1.17",
|
||||||
"astro": "^5.14.5",
|
"astro": "^5.16.3",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.19",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"lucide-react": "^0.546.0",
|
"lucide-react": "^0.555.0",
|
||||||
"nanoid": "^5.1.6",
|
"nanoid": "^5.1.6",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
"react-toastify": "^11.0.5",
|
"react-toastify": "^11.0.5",
|
||||||
"tailwind-merge": "^3.3.1",
|
"tailwind-merge": "^3.4.0",
|
||||||
"zustand": "^5.0.8"
|
"zustand": "^5.0.9"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@kevisual/types": "^0.0.10",
|
"@kevisual/types": "^0.0.10",
|
||||||
"@types/react": "^19.2.2",
|
"@types/react": "^19.2.7",
|
||||||
"@types/react-dom": "^19.2.2",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-basic-ssl": "^2.1.0",
|
"@vitejs/plugin-basic-ssl": "^2.1.0",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"tailwindcss": "^4.1.14",
|
"tailwindcss": "^4.1.17",
|
||||||
"tw-animate-css": "^1.4.0"
|
"tw-animate-css": "^1.4.0"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.18.3",
|
"packageManager": "pnpm@10.24.0",
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"@tailwindcss/oxide",
|
"@tailwindcss/oxide",
|
||||||
"esbuild",
|
"esbuild",
|
||||||
|
|||||||
954
docs/pnpm-lock.yaml
generated
954
docs/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
26
docs/src/layouts/MDXPost.astro
Normal file
26
docs/src/layouts/MDXPost.astro
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
import '../styles/global.css';
|
||||||
|
export interface Props {
|
||||||
|
title?: string;
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title, description } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>{title || '文档'}</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.2.0/github-markdown.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/github-dark.min.css">
|
||||||
|
</head>
|
||||||
|
<body class="bg-gray-50 min-h-screen">
|
||||||
|
<div class="container mx-auto px-4 py-8 max-w-4xl">
|
||||||
|
<article class="markdown-body bg-white rounded-lg shadow-lg p-8">
|
||||||
|
<slot />
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
## ADB
|
---
|
||||||
|
title: "ADB 命令文档"
|
||||||
|
description: "Android Debug Bridge 常用命令和使用说明"
|
||||||
|
layout: ../layouts/MDXPost.astro
|
||||||
|
---
|
||||||
|
|
||||||
|
# ADB 命令文档
|
||||||
|
|
||||||
这是关于 Android Debug Bridge 的文档。
|
这是关于 Android Debug Bridge 的文档。
|
||||||
|
|
||||||
|
|||||||
57
docs/src/pages/home.mdx
Normal file
57
docs/src/pages/home.mdx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
title: "Home 配置文档"
|
||||||
|
description: "Home Assistant 自动化配置文档"
|
||||||
|
layout: ../layouts/MDXPost.astro
|
||||||
|
---
|
||||||
|
|
||||||
|
# home配置文档
|
||||||
|
|
||||||
|
## configuration.yaml
|
||||||
|
|
||||||
|
配置调用rest_command服务,文件地址在 docker 内部根目录下,`config/configuration.yaml` 位置
|
||||||
|
|
||||||
|
添加以下内容
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
rest_command:
|
||||||
|
set_floor_notify:
|
||||||
|
url: http://host.docker.internal:3001/api/router?path=floor
|
||||||
|
method: POST
|
||||||
|
content_type: application/json
|
||||||
|
```
|
||||||
|
|
||||||
|
然后配置脚本位置 `config/scripts.yaml` 文件,添加以下内容(scripts 被 configuration.yaml 引用)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
notify_floor:
|
||||||
|
alias: "发送楼层消息"
|
||||||
|
description: "通过本地服务发送楼层通知"
|
||||||
|
sequence:
|
||||||
|
- service: rest_command.set_floor_notify
|
||||||
|
```
|
||||||
|
|
||||||
|
## 触发使用
|
||||||
|
|
||||||
|
home 可视化页面可以编辑自动化,编辑后台也可以,在 automations.yaml 文件中添加以下类似内容
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: '1760892271622'
|
||||||
|
alias: 打开电梯
|
||||||
|
description: 打开电梯,上13楼来
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id:
|
||||||
|
- event.xiaomi_cn_1076466578_hub1_virtual_event_e_4_1
|
||||||
|
from:
|
||||||
|
to:
|
||||||
|
conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: event.xiaomi_cn_1076466578_hub1_virtual_event_e_4_1
|
||||||
|
attribute: 事件名称
|
||||||
|
state: 打开电梯
|
||||||
|
actions:
|
||||||
|
- action: script.notify_floor
|
||||||
|
metadata: {}
|
||||||
|
data: {}
|
||||||
|
mode: single
|
||||||
|
```
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import '../styles/global.css';
|
import '../styles/global.css';
|
||||||
|
|
||||||
const links = [
|
const links = [
|
||||||
|
|
||||||
{
|
{
|
||||||
link: './adb/',
|
link: './adb/',
|
||||||
title: 'ADB 文档',
|
title: 'ADB 文档',
|
||||||
@@ -13,41 +14,52 @@ const links = [
|
|||||||
{
|
{
|
||||||
link: './ip/',
|
link: './ip/',
|
||||||
title: 'IP 相关文档, IPTABLES 配置,如何从A 局域网 ping 同B 局域网',
|
title: 'IP 相关文档, IPTABLES 配置,如何从A 局域网 ping 同B 局域网',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
link: './python/',
|
||||||
|
title: 'Python 脚本运行文档',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
link: './home/',
|
||||||
|
title: 'homeassistant 触发脚本文档方法',
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
<html lang='zh-CN'>
|
<html lang='zh-CN'>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset='UTF-8' />
|
||||||
<title>My Homepage</title>
|
<title>My Homepage</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src='https://cdn.tailwindcss.com'></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-gray-50 min-h-screen">
|
<body class='bg-gray-50 min-h-screen'>
|
||||||
<div class="container mx-auto px-4 py-8">
|
<div class='container mx-auto px-4 py-8'>
|
||||||
<h1 class="text-3xl font-bold text-gray-800 mb-8 text-center">文档导航</h1>
|
<h1 class='text-3xl font-bold text-gray-800 mb-2 text-center'>文档导航</h1>
|
||||||
|
<h2 class="text-lg font-medium text-gray-700 mb-6 text-center">代码地址: <a href="https://git.xiongxiao.me/me/dnake" class="text-blue-600 hover:text-blue-800 underline transition-colors duration-200">git.xiongxiao.me</a></h2>
|
||||||
<div class="max-w-2xl mx-auto">
|
<div class='max-w-2xl mx-auto'>
|
||||||
<ul class="space-y-4">
|
<ul class='space-y-4'>
|
||||||
{links.map((item) => (
|
{
|
||||||
<li>
|
links.map((item) => (
|
||||||
<a
|
<li>
|
||||||
href={item.link}
|
<a
|
||||||
class="block p-6 bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300 border border-gray-200 hover:border-blue-300 group"
|
href={item.link}
|
||||||
>
|
class='block p-6 bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300 border border-gray-200 hover:border-blue-300 group'>
|
||||||
<h2 class="text-xl font-semibold text-gray-800 group-hover:text-blue-600 transition-colors duration-200">
|
<h2 class='text-xl font-semibold text-gray-800 group-hover:text-blue-600 transition-colors duration-200'>{item.title}</h2>
|
||||||
{item.title}
|
<p class='text-gray-600 mt-2'>点击查看详细文档</p>
|
||||||
</h2>
|
<div class='flex items-center mt-3 text-blue-500 group-hover:text-blue-700'>
|
||||||
<p class="text-gray-600 mt-2">点击查看详细文档</p>
|
<span class='text-sm'>查看文档</span>
|
||||||
<div class="flex items-center mt-3 text-blue-500 group-hover:text-blue-700">
|
<svg
|
||||||
<span class="text-sm">查看文档</span>
|
class='w-4 h-4 ml-2 transform group-hover:translate-x-1 transition-transform duration-200'
|
||||||
<svg class="w-4 h-4 ml-2 transform group-hover:translate-x-1 transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
fill='none'
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
stroke='currentColor'
|
||||||
</svg>
|
viewBox='0 0 24 24'>
|
||||||
</div>
|
<path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 5l7 7-7 7' />
|
||||||
</a>
|
</svg>
|
||||||
</li>
|
</div>
|
||||||
))}
|
</a>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
# iptables
|
---
|
||||||
|
title: "网络配置文档"
|
||||||
|
description: "IP地址配置、iptables路由规则和网络安全设置"
|
||||||
|
layout: ../layouts/MDXPost.astro
|
||||||
|
---
|
||||||
|
|
||||||
|
# 网络配置文档
|
||||||
|
|
||||||
## 提示词
|
## 提示词
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
# ip地址
|
---
|
||||||
|
title: "设备网络配置"
|
||||||
|
description: "Dnake设备网络地址配置和ADB连接管理"
|
||||||
|
layout: ../layouts/MDXPost.astro
|
||||||
|
---
|
||||||
|
|
||||||
|
# 设备网络配置
|
||||||
|
|
||||||
## dnake的设备信息
|
## dnake的设备信息
|
||||||
|
|
||||||
|
|||||||
11
docs/src/pages/posts/dnake-2.md
Normal file
11
docs/src/pages/posts/dnake-2.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# 1. 允许转发从eth1到eth0的SIP数据包(目的192.168.9.4:5060)
|
||||||
|
iptables -A FORWARD -i eth1 -o eth0 -p udp --dport 5060 -d 192.168.9.4 -j ACCEPT
|
||||||
|
|
||||||
|
# 2. 允许转发从eth0返回eth1的SIP响应包(源192.168.9.4:5060)
|
||||||
|
iptables -A FORWARD -i eth0 -o eth1 -p udp --sport 5060 -s 192.168.9.4 -j ACCEPT
|
||||||
|
|
||||||
|
# 3. DNAT:将eth1收到的5060端口UDP包转发到192.168.9.4:5060
|
||||||
|
iptables -t nat -A PREROUTING -i eth1 -p udp --dport 5060 -j DNAT --to-destination 192.168.9.4:5060
|
||||||
|
|
||||||
|
# 4. SNAT:修改转发包的源地址为设备eth0的IP(192.168.9.57),确保192.168.9.4的响应能回传给设备
|
||||||
|
iptables -t nat -A POSTROUTING -o eth0 -p udp --dport 5060 -d 192.168.9.4 -j SNAT --to-source 192.168.9.57
|
||||||
150
docs/src/pages/python.mdx
Normal file
150
docs/src/pages/python.mdx
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
---
|
||||||
|
title: "Python 代码示例"
|
||||||
|
description: "SIP 消息发送和 FastAPI 服务示例"
|
||||||
|
layout: ../layouts/MDXPost.astro
|
||||||
|
---
|
||||||
|
|
||||||
|
# python 代码示例
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# 安装 python 环境 ,安装项目
|
||||||
|
uv sync
|
||||||
|
```
|
||||||
|
|
||||||
|
## 运行 python 脚本
|
||||||
|
|
||||||
|
main.py 主模块
|
||||||
|
|
||||||
|
```python
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
|
||||||
|
def send_sip_message():
|
||||||
|
# 配置参数
|
||||||
|
target_ip = "192.168.3.3" # 设备eth1的IP(转发入口)
|
||||||
|
target_port = 5060 # 转发端口
|
||||||
|
mac_local_ip = "192.168.3.33"# Mac的本地IP(与Via头部一致)
|
||||||
|
sender_sip = "3011302" # 发送方SIP用户
|
||||||
|
sender_ip = "192.168.9.57" # 设备eth0的IP(转发后源IP)
|
||||||
|
receiver_sip = "3019901" # 接收方SIP用户
|
||||||
|
receiver_ip = "192.168.9.4" # 目标IP
|
||||||
|
|
||||||
|
# 生成唯一标识
|
||||||
|
call_id = f"{int(time.time())}" # 基于时间戳的Call-ID
|
||||||
|
tag = f"{int(time.time() % 1000000)}" # 随机tag
|
||||||
|
branch = f"z9hG4bK{int(time.time())}" # Via分支标识
|
||||||
|
|
||||||
|
# XML消息体(业务数据)
|
||||||
|
xml_body = '''<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<params>
|
||||||
|
<to>sip:{receiver_sip}@{receiver_ip}:5060</to>
|
||||||
|
<elev>1</elev>
|
||||||
|
<direct>2</direct>
|
||||||
|
<floor>13</floor>
|
||||||
|
<family>2</family>
|
||||||
|
<app>elev</app>
|
||||||
|
<event>appoint</event>
|
||||||
|
<event_url>/elev/appoint</event_url>
|
||||||
|
</params>'''.format(receiver_sip=receiver_sip, receiver_ip=receiver_ip)
|
||||||
|
|
||||||
|
# 计算消息体长度(字节数)
|
||||||
|
content_length = len(xml_body.encode('utf-8'))
|
||||||
|
|
||||||
|
# 构造SIP MESSAGE请求(严格使用\r\n换行)
|
||||||
|
sip_message = f'''MESSAGE sip:{receiver_sip}@{receiver_ip}:5060 SIP/2.0
|
||||||
|
Via: SIP/2.0/UDP {mac_local_ip}:5060;rport;branch={branch}
|
||||||
|
From: <sip:{sender_sip}@{sender_ip}:5060>;tag={tag}
|
||||||
|
To: <sip:{receiver_sip}@{receiver_ip}:5060>
|
||||||
|
Call-ID: {call_id}@{mac_local_ip}
|
||||||
|
CSeq: 20 MESSAGE
|
||||||
|
Content-Type: text/plain
|
||||||
|
Max-Forwards: 70
|
||||||
|
User-Agent: DnakeVoip v1.0
|
||||||
|
Content-Length: {content_length}
|
||||||
|
|
||||||
|
{xml_body}'''
|
||||||
|
|
||||||
|
# 替换换行符为\r\n(确保符合SIP协议)
|
||||||
|
sip_message = sip_message.replace('\n', '\r\n')
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 创建UDP socket并发送消息
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
||||||
|
# 设置超时时间(5秒)
|
||||||
|
sock.settimeout(5)
|
||||||
|
# 发送消息
|
||||||
|
sock.sendto(sip_message.encode('utf-8'), (target_ip, target_port))
|
||||||
|
print(f"已发送SIP消息到 {target_ip}:{target_port}")
|
||||||
|
print("\n发送的消息内容:")
|
||||||
|
print(sip_message)
|
||||||
|
|
||||||
|
# 尝试接收响应(可选)
|
||||||
|
try:
|
||||||
|
response, addr = sock.recvfrom(4096)
|
||||||
|
print(f"\n收到来自 {addr} 的响应:")
|
||||||
|
print(response.decode('utf-8', errors='ignore'))
|
||||||
|
except socket.timeout:
|
||||||
|
print("\n未收到响应(可能对方未回复或网络延迟)")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"发送失败:{str(e)}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
send_sip_message()
|
||||||
|
```
|
||||||
|
|
||||||
|
app.py
|
||||||
|
|
||||||
|
```python
|
||||||
|
from fastapi import FastAPI, Query
|
||||||
|
import httpx
|
||||||
|
import asyncio
|
||||||
|
import uvicorn
|
||||||
|
from main import send_sip_message
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
"""主函数内容"""
|
||||||
|
print("执行main函数...")
|
||||||
|
# 执行发送SIP消息
|
||||||
|
send_sip_message()
|
||||||
|
return {"message": "main function executed - SIP message sent"}
|
||||||
|
|
||||||
|
async def test():
|
||||||
|
"""测试函数内容"""
|
||||||
|
print("执行test函数...")
|
||||||
|
# 在这里添加你的test函数逻辑
|
||||||
|
return {"message": "test function executed"}
|
||||||
|
|
||||||
|
@app.api_route("/api/router", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"])
|
||||||
|
async def router(path: str = Query(...)):
|
||||||
|
"""路由处理器"""
|
||||||
|
try:
|
||||||
|
# 根据path参数执行不同的函数
|
||||||
|
if path == "floor":
|
||||||
|
result = await main()
|
||||||
|
elif path == "test":
|
||||||
|
result = await test()
|
||||||
|
else:
|
||||||
|
return {"error": f"Unknown path: {path}"}
|
||||||
|
|
||||||
|
return {"success": True, "data": result}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return {"success": False, "error": str(e)}
|
||||||
|
|
||||||
|
@app.api_route("/", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"])
|
||||||
|
async def root():
|
||||||
|
"""健康检查端点"""
|
||||||
|
return {"message": "FastAPI server is running"}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 监听所有IPv6地址的3001端口
|
||||||
|
uvicorn.run(
|
||||||
|
"app:app",
|
||||||
|
host="::", # 监听所有IPv6地址
|
||||||
|
port=3001,
|
||||||
|
reload=True
|
||||||
|
)
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user