mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 07:03:53 +08:00
Merge pull request #1011 from xinnan-tech/simple_ota_server
为最简化安装环境提供OTA基础信息接口
This commit is contained in:
@@ -156,8 +156,8 @@ server:
|
||||
|
||||
| 部署方式 | 特点 | 适用场景 | Docker部署文档 | 源码部署文档 |
|
||||
|---------|------|---------|---------|---------|
|
||||
| **最简化安装** | 智能对话、IOT功能,数据存储在配置文件 | 低配置环境,无需数据库,仅支持虾哥1.6.0及以下固件版本 | [Docker只运行Server](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%80docker%E5%8F%AA%E8%BF%90%E8%A1%8Cserver) | [本地源码只运行Server](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E5%8F%AA%E8%BF%90%E8%A1%8Cserver)|
|
||||
| **全模块安装** | 智能对话、IOT、OTA、智控台,数据存储在数据库 | 完整功能体验,支持虾哥最新固件 |[Docker运行全模块](./docs/Deployment_all.md#%E6%96%B9%E5%BC%8F%E4%B8%80docker%E8%BF%90%E8%A1%8C%E5%85%A8%E6%A8%A1%E5%9D%97) | [本地源码运行全模块](./docs/Deployment_all.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E8%BF%90%E8%A1%8C%E5%85%A8%E6%A8%A1%E5%9D%97) |
|
||||
| **最简化安装** | 智能对话、IOT功能,数据存储在配置文件 | 低配置环境,无需数据库 | [Docker只运行Server](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%80docker%E5%8F%AA%E8%BF%90%E8%A1%8Cserver) | [本地源码只运行Server](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E5%8F%AA%E8%BF%90%E8%A1%8Cserver)|
|
||||
| **全模块安装** | 智能对话、IOT、OTA、智控台,数据存储在数据库 | 完整功能体验 |[Docker运行全模块](./docs/Deployment_all.md#%E6%96%B9%E5%BC%8F%E4%B8%80docker%E8%BF%90%E8%A1%8C%E5%85%A8%E6%A8%A1%E5%9D%97) | [本地源码运行全模块](./docs/Deployment_all.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E8%BF%90%E8%A1%8C%E5%85%A8%E6%A8%A1%E5%9D%97) |
|
||||
|
||||
> 💡 提示:以下是按最新代码部署后的测试平台,有需要可烧录测试,并发为6个,每天会清空数据
|
||||
|
||||
|
||||
+12
-7
@@ -240,7 +240,7 @@ selected_module:
|
||||
LLM: ChatGLMLLM
|
||||
TTS: EdgeTTS
|
||||
# 默认不开启记忆,如需开启请看配置文件里的描述
|
||||
Memory: nomem
|
||||
Memory: nomem
|
||||
# 默认不开启意图识别,如需开启请看配置文件里的描述
|
||||
Intent: nointent
|
||||
```
|
||||
@@ -276,21 +276,26 @@ LLM:
|
||||
如果你能看到,类似以下日志,则是本项目服务启动成功的标志。
|
||||
|
||||
```
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - Server is running at ws://xxx.xx.xx.xx:8000/xiaozhi/v1/
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - =======上面的地址是websocket协议地址,请勿用浏览器访问=======
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - 如想测试websocket请用谷歌浏览器打开test目录下的test_page.html
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - =======================================================
|
||||
250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-OTA接口是 http://192.168.4.123:8002/xiaozhi/ota/
|
||||
250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-Websocket地址是 ws://192.168.4.123:8000/xiaozhi/v1/
|
||||
250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-=======上面的地址是websocket协议地址,请勿用浏览器访问=======
|
||||
250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-如想测试websocket请用谷歌浏览器打开test目录下的test_page.html
|
||||
250427 13:04:20[0.3.11_SiFuChTTnofu][__main__]-INFO-=======================================================
|
||||
```
|
||||
|
||||
正常来说,如果您是通过源码运行本项目,日志会有你的接口地址信息。
|
||||
但是如果你用docker部署,那么你的日志里给出的接口地址信息就不是真实的接口地址。
|
||||
|
||||
最正确的方法,是根据电脑的局域网IP来确定你的接口地址。
|
||||
如果你的电脑的局域网IP比如是`192.168.1.25`,那么你的接口地址就是:`ws://192.168.1.25:8000/xiaozhi/v1/`。
|
||||
如果你的电脑的局域网IP比如是`192.168.1.25`,那么你的接口地址就是:`ws://192.168.1.25:8000/xiaozhi/v1/`,对应的OTA地址就是:`http://192.168.1.25:8002/xiaozhi/ota/`。
|
||||
|
||||
这个信息很有用的,后面`编译esp32固件`需要用到。
|
||||
|
||||
接下来,你就可以开始 [编译1.6.0版本esp32固件](firmware-build.md)了。
|
||||
接下来,你就可以开始操作你的esp32设备了,你可以`自行编译esp32固件`也可以配置使用`虾哥编译好的1.6.1以上版本的固件`。两个任选一个
|
||||
|
||||
1、 [编译自己的esp32固件](firmware-build.md)了。
|
||||
|
||||
2、 [基于虾哥编译好的固件配置自定义服务器](firmware-setting.md)了。
|
||||
|
||||
|
||||
以下是一些常见问题,供参考:
|
||||
|
||||
@@ -169,7 +169,7 @@ docker logs -f xiaozhi-esp32-server
|
||||
如果你能看到,类似以下日志,则是Server启动成功的标志。
|
||||
|
||||
```
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - Server is running at ws://xxx.xx.xx.xx:8000/xiaozhi/v1/
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - Websocket地址是 ws://xxx.xx.xx.xx:8000/xiaozhi/v1/
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - =======上面的地址是websocket协议地址,请勿用浏览器访问=======
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - 如想测试websocket请用谷歌浏览器打开test目录下的test_page.html
|
||||
25-02-23 12:01:09[core.websocket_server] - INFO - =======================================================
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
# 编译1.6.0版本esp32固件
|
||||
|
||||
## 第1步 配置环境
|
||||
先按照这个教程配置项目环境[《Windows搭建 ESP IDF 5.3.2开发环境以及编译小智》](https://icnynnzcwou8.feishu.cn/wiki/JEYDwTTALi5s2zkGlFGcDiRknXf)
|
||||
|
||||
## 第2步 打开配置文件
|
||||
配置好编译环境后,下载虾哥iaozhi-esp32项目源码,
|
||||
|
||||
|
||||
从这里下载虾哥[xiaozhi-esp32项目1.6.0版本源码](https://github.com/78/xiaozhi-esp32/archive/refs/tags/v1.6.0.zip)。
|
||||
|
||||
从这里下载虾哥[xiaozhi-esp32项目1.6.0版本源码](https://github.com/78/xiaozhi-esp32/archive/refs/tags/v1.6.0.zip)。
|
||||
|
||||
从这里下载虾哥[xiaozhi-esp32项目1.6.0版本源码](https://github.com/78/xiaozhi-esp32/archive/refs/tags/v1.6.0.zip)。
|
||||
|
||||
下载后,解压缩包,打开`xiaozhi-esp32/main/Kconfig.projbuild`文件。
|
||||
|
||||
|
||||
## 第3步 修改WEBSOCKET地址
|
||||
找到`WEBSOCKET_URL`的`default`的内容,把`wss://api.tenclass.net/xiaozhi/v1/`
|
||||
改成你自己的地址,例如,我的接口地址是`ws://192.168.1.25:8000/xiaozhi/v1/`,就把内容改成这个。
|
||||
|
||||
修改前:
|
||||
|
||||
```
|
||||
config WEBSOCKET_URL
|
||||
depends on CONNECTION_TYPE_WEBSOCKET
|
||||
string "Websocket URL"
|
||||
default "wss://api.tenclass.net/xiaozhi/v1/"
|
||||
help
|
||||
Communication with the server through websocket after wake up.
|
||||
```
|
||||
|
||||
修改后(示例):
|
||||
|
||||
```
|
||||
config WEBSOCKET_URL
|
||||
depends on CONNECTION_TYPE_WEBSOCKET
|
||||
string "Websocket URL"
|
||||
default "ws://192.168.1.25:8000/xiaozhi/v1/"
|
||||
help
|
||||
Communication with the server through websocket after wake up.
|
||||
```
|
||||
|
||||
注意:你的地址是`ws://`开头,不是`wss://`开头,一定不要写错了。
|
||||
|
||||
注意:你的地址是`ws://`开头,不是`wss://`开头,一定不要写错了。
|
||||
|
||||
注意:你的地址是`ws://`开头,不是`wss://`开头,一定不要写错了。
|
||||
|
||||
## 第4步 设置编译参数
|
||||
|
||||
设置编译参数
|
||||
|
||||
```
|
||||
# 终端命令行进入xiaozhi-esp32的根目录
|
||||
cd xiaozhi-esp32
|
||||
# 例如我使用的板子是esp32s3,所以设置编译目标为esp32s3,如果你的板子是其他型号,请替换成对应的型号
|
||||
idf.py set-target esp32s3
|
||||
# 进入菜单配置
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||

|
||||
|
||||
进入菜单配置后,再进入`Xiaozhi Assistant`,将`CONNECTION_TYPE`设置为`Websocket`
|
||||
回退到主菜单,再进入`Xiaozhi Assistant`,将`BOARD_TYPE`设置你板子的具体型号
|
||||
保存退出,回到终端命令行。
|
||||
|
||||

|
||||
|
||||
## 第5步 编译固件
|
||||
|
||||
```
|
||||
idf.py build
|
||||
```
|
||||
|
||||
## 第6步 打包bin固件
|
||||
|
||||
```
|
||||
cd scripts
|
||||
python release.py
|
||||
```
|
||||
|
||||
上面的打包命令执行完成后,会在项目根目录下的`build`目录下生成固件文件`merged-binary.bin`。
|
||||
这个`merged-binary.bin`就是要烧录到硬件上的固件文件。
|
||||
|
||||
注意:如果执行到第二命令后,报了“zip”相关的错误,请忽略这个错误,只要`build`目录下生成固件文件`merged-binary.bin`
|
||||
,对你没有太大影响,请继续。
|
||||
|
||||
## 第7步 烧录固件
|
||||
将esp32设备连接电脑,使用chrome浏览器,打开以下网址
|
||||
|
||||
```
|
||||
https://espressif.github.io/esp-launchpad/
|
||||
```
|
||||
|
||||
打开这个教程,[Flash工具/Web端烧录固件(无IDF开发环境)](https://ccnphfhqs21z.feishu.cn/wiki/Zpz4wXBtdimBrLk25WdcXzxcnNS)。
|
||||
翻到:`方式二:ESP-Launchpad 浏览器WEB端烧录`,从`3. 烧录固件/下载到开发板`开始,按照教程操作。
|
||||
|
||||
烧录成功且联网成功后,通过唤醒词唤醒小智,留意server端输出的控制台信息。
|
||||
|
||||
## 常见问题
|
||||
以下是一些常见问题,供参考:
|
||||
|
||||
[1、为什么我说的话,小智识别出来很多韩文、日文、英文](./FAQ.md)
|
||||
|
||||
[2、为什么会出现“TTS 任务出错 文件不存在”?](./FAQ.md)
|
||||
|
||||
[3、TTS 经常失败,经常超时](./FAQ.md)
|
||||
|
||||
[4、使用Wifi能连接自建服务器,但是4G模式却接不上](./FAQ.md)
|
||||
|
||||
[5、如何提高小智对话响应速度?](./FAQ.md)
|
||||
|
||||
[6、我说话很慢,停顿时小智老是抢话](./FAQ.md)
|
||||
|
||||
[7、我想通过小智控制电灯、空调、远程开关机等操作](./FAQ.md)
|
||||
+19
-2
@@ -1,14 +1,31 @@
|
||||
# esp32固件编译
|
||||
|
||||
## 第1步 准备你的ota地址
|
||||
如果你按照教程使用的是全模块部署,就应该会有ota地址。
|
||||
|
||||
如果你,使用的是本项目0.3.12版本,不管是简单Server部署还是全模块部署,都会有ota地址。
|
||||
|
||||
由于简单Server部署和全模块部署的OTA地址设置方式不一样,请你选择下面的具体方式:
|
||||
|
||||
### 如果你用的是简单Server部署
|
||||
此刻,请你用浏览器打开你的ota地址,例如我的ota地址
|
||||
```
|
||||
http://192.168.1.25:8002/xiaozhi/ota/
|
||||
```
|
||||
如果显示“OTA接口运行正常,向设备发送的websocket地址是:ws://xxx:8000/xiaozhi/v1/
|
||||
|
||||
你可以使用项目自带的`test_page.html`测试一下,是否能连上ota页面输出的websocket地址。
|
||||
|
||||
如果访问不到,你需要到配置文件`.config.yaml`里修改`server.websocket`的地址,重启后再重新测试,直到`test_page.html`能正常访问。
|
||||
|
||||
成功后,请往下进行第2步
|
||||
|
||||
### 如果你用的是全模块部署
|
||||
此刻,请你用浏览器打开你的ota地址,例如我的ota地址
|
||||
```
|
||||
http://192.168.1.25:8002/xiaozhi/ota/
|
||||
```
|
||||
|
||||
如果显示“OTA接口运行正常,websocket集群数量:X”。那就往下。
|
||||
如果显示“OTA接口运行正常,websocket集群数量:X”。那就往下进行2步。
|
||||
|
||||
如果显示“OTA接口运行不正常”,大概是你还没在`智控台`配置`Websocket`地址。那就:
|
||||
|
||||
|
||||
@@ -177,5 +177,5 @@ public interface Constant {
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
public static final String VERSION = "0.3.11";
|
||||
public static final String VERSION = "0.3.12";
|
||||
}
|
||||
@@ -3,9 +3,13 @@ import sys
|
||||
import signal
|
||||
from config.settings import load_config, check_config_file
|
||||
from core.websocket_server import WebSocketServer
|
||||
from core.ota_server import SimpleOtaServer
|
||||
from core.utils.util import check_ffmpeg_installed
|
||||
from config.logger import setup_logging
|
||||
from core.utils.util import get_local_ip
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
|
||||
async def wait_for_exit():
|
||||
@@ -34,6 +38,41 @@ async def main():
|
||||
# 启动 WebSocket 服务器
|
||||
ws_server = WebSocketServer(config)
|
||||
ws_task = asyncio.create_task(ws_server.start())
|
||||
ota_task = None
|
||||
|
||||
read_config_from_api = config.get("read_config_from_api", False)
|
||||
if not read_config_from_api:
|
||||
# 启动 Simple OTA 服务器
|
||||
ota_server = SimpleOtaServer(config)
|
||||
ota_task = asyncio.create_task(ota_server.start())
|
||||
|
||||
logger.bind(tag=TAG).info(
|
||||
"OTA接口是\t\thttp://{}:{}/xiaozhi/ota/",
|
||||
get_local_ip(),
|
||||
config["server"]["ota_port"],
|
||||
)
|
||||
|
||||
# 获取WebSocket配置,使用安全的默认值
|
||||
websocket_port = 8000
|
||||
server_config = config.get("server", {})
|
||||
if isinstance(server_config, dict):
|
||||
websocket_port = int(server_config.get("port", 8000))
|
||||
|
||||
logger.bind(tag=TAG).info(
|
||||
"Websocket地址是\tws://{}:{}/xiaozhi/v1/",
|
||||
get_local_ip(),
|
||||
websocket_port,
|
||||
)
|
||||
|
||||
logger.bind(tag=TAG).info(
|
||||
"=======上面的地址是websocket协议地址,请勿用浏览器访问======="
|
||||
)
|
||||
logger.bind(tag=TAG).info(
|
||||
"如想测试websocket请用谷歌浏览器打开test目录下的test_page.html"
|
||||
)
|
||||
logger.bind(tag=TAG).info(
|
||||
"=============================================================\n"
|
||||
)
|
||||
|
||||
try:
|
||||
await wait_for_exit() # 监听退出信号
|
||||
@@ -41,8 +80,12 @@ async def main():
|
||||
print("任务被取消,清理资源中...")
|
||||
finally:
|
||||
ws_task.cancel()
|
||||
if ota_task:
|
||||
ota_task.cancel()
|
||||
try:
|
||||
await ws_task
|
||||
if ota_task:
|
||||
await ota_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
print("服务器已关闭,程序退出。")
|
||||
|
||||
@@ -9,6 +9,15 @@ server:
|
||||
# 服务器监听地址和端口(Server listening address and port)
|
||||
ip: 0.0.0.0
|
||||
port: 8000
|
||||
# OTA接口的端口号
|
||||
ota_port: 8002
|
||||
# 这个websocket配置是指ota接口向设备发送的websocket地址
|
||||
# 如果按默认的写法,ota接口会自动生成websocket地址。这个地址你可以直接用浏览器访问ota接口确认一下
|
||||
# 当你使用docker部署或使用公网部署(使用ssl、域名)时,不一定准确
|
||||
# 所以如果你使用docker部署或使用公网部署时,请设置正确的websocket地址
|
||||
websocket: ws://你的ip或者域名:端口号/xiaozhi/v1/
|
||||
# OTA返回信息时区偏移量
|
||||
timezone_offset: +8
|
||||
# 认证配置
|
||||
auth:
|
||||
# 是否启用认证
|
||||
@@ -239,8 +248,8 @@ LLM:
|
||||
api_key: 你的deepseek web key
|
||||
temperature: 0.7 # 温度值
|
||||
max_tokens: 500 # 最大生成token数
|
||||
top_p: 1
|
||||
top_k: 50
|
||||
top_p: 1
|
||||
top_k: 50
|
||||
frequency_penalty: 0 # 频率惩罚
|
||||
AliAppLLM:
|
||||
# 定义LLM API类型
|
||||
@@ -249,7 +258,7 @@ LLM:
|
||||
app_id: 你的app_id
|
||||
# 可在这里找到你的 api_key https://bailian.console.aliyun.com/?apiKey=1#/api-key
|
||||
api_key: 你的api_key
|
||||
# 是否不使用本地prompt:true|false (默不用请在百练应用中设置prompt)
|
||||
# 是否不使用本地prompt:true|false (默不用请在百练应用中设置prompt)
|
||||
is_no_prompt: true
|
||||
# Ali_memory_id:false(不使用)|你的memory_id(请在百练应用中设置中获取)
|
||||
# Tips!:Ali_memory未实现多用户存储记忆(记忆按id调用)
|
||||
|
||||
@@ -3,7 +3,7 @@ import sys
|
||||
from loguru import logger
|
||||
from config.config_loader import load_config
|
||||
|
||||
SERVER_VERSION = "0.3.11"
|
||||
SERVER_VERSION = "0.3.12"
|
||||
|
||||
|
||||
def get_module_abbreviation(module_name, module_dict):
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
import json
|
||||
import time
|
||||
import asyncio
|
||||
from aiohttp import web
|
||||
from config.logger import setup_logging
|
||||
from core.connection import ConnectionHandler
|
||||
from core.utils.util import get_local_ip, initialize_modules
|
||||
|
||||
TAG = __name__
|
||||
|
||||
|
||||
class SimpleOtaServer:
|
||||
def __init__(self, config: dict):
|
||||
self.config = config
|
||||
self.logger = setup_logging()
|
||||
|
||||
def _get_websocket_url(self, local_ip: str, port: int) -> str:
|
||||
"""获取websocket地址
|
||||
|
||||
Args:
|
||||
local_ip: 本地IP地址
|
||||
port: 端口号
|
||||
|
||||
Returns:
|
||||
str: websocket地址
|
||||
"""
|
||||
server_config = self.config["server"]
|
||||
websocket_config = server_config.get("websocket")
|
||||
|
||||
if websocket_config and "你" not in websocket_config:
|
||||
return websocket_config
|
||||
else:
|
||||
return f"ws://{local_ip}:{port}/xiaozhi/v1/"
|
||||
|
||||
async def start(self):
|
||||
server_config = self.config["server"]
|
||||
host = server_config.get("ip", "0.0.0.0")
|
||||
port = int(server_config.get("ota_port"))
|
||||
|
||||
if port:
|
||||
app = web.Application()
|
||||
# 添加路由
|
||||
app.add_routes(
|
||||
[
|
||||
web.get("/xiaozhi/ota/", self._handle_ota_get_request),
|
||||
web.post("/xiaozhi/ota/", self._handle_ota_request),
|
||||
web.options("/xiaozhi/ota/", self._handle_ota_request),
|
||||
]
|
||||
)
|
||||
|
||||
# 运行服务
|
||||
runner = web.AppRunner(app)
|
||||
await runner.setup()
|
||||
site = web.TCPSite(runner, host, port)
|
||||
await site.start()
|
||||
|
||||
# 保持服务运行
|
||||
while True:
|
||||
await asyncio.sleep(3600) # 每隔 1 小时检查一次
|
||||
|
||||
async def _handle_ota_request(self, request):
|
||||
"""处理 /xiaozhi/ota/ 的 POST 请求"""
|
||||
try:
|
||||
data = await request.text()
|
||||
self.logger.bind(tag=TAG).debug(f"OTA请求方法: {request.method}")
|
||||
self.logger.bind(tag=TAG).debug(f"OTA请求头: {request.headers}")
|
||||
self.logger.bind(tag=TAG).debug(f"OTA请求数据: {data}")
|
||||
|
||||
device_id = request.headers.get("device-id", "")
|
||||
if device_id:
|
||||
self.logger.bind(tag=TAG).info(f"OTA请求设备ID: {device_id}")
|
||||
else:
|
||||
raise Exception("OTA请求设备ID为空")
|
||||
|
||||
data_json = json.loads(data)
|
||||
|
||||
server_config = self.config["server"]
|
||||
host = server_config.get("ip", "0.0.0.0")
|
||||
port = int(server_config.get("port", 8000))
|
||||
local_ip = get_local_ip()
|
||||
|
||||
# OTA基础信息
|
||||
return_json = {
|
||||
"server_time": {
|
||||
"timestamp": int(round(time.time() * 1000)),
|
||||
"timezone_offset": server_config.get("timezone_offset", 8) * 60,
|
||||
},
|
||||
"firmware": {
|
||||
"version": data_json["application"].get("version", "1.0.0"),
|
||||
"url": "",
|
||||
},
|
||||
"websocket": {
|
||||
"url": self._get_websocket_url(local_ip, port),
|
||||
},
|
||||
}
|
||||
response = web.Response(
|
||||
text=json.dumps(return_json, separators=(",", ":")),
|
||||
content_type="application/json",
|
||||
)
|
||||
except Exception as e:
|
||||
self.logger.bind(tag=TAG).error(f"OTA请求异常: {e}")
|
||||
return_json = {"success": False, "message": "request error."}
|
||||
response = web.Response(
|
||||
text=json.dumps(return_json, separators=(",", ":")),
|
||||
content_type="application/json",
|
||||
)
|
||||
finally:
|
||||
# 添加header,允许跨域访问
|
||||
response.headers["Access-Control-Allow-Headers"] = (
|
||||
"client-id, content-type, device-id"
|
||||
)
|
||||
response.headers["Access-Control-Allow-Credentials"] = "true"
|
||||
response.headers["Access-Control-Allow-Origin"] = "*"
|
||||
return response
|
||||
|
||||
async def _handle_ota_get_request(self, request):
|
||||
"""处理 /xiaozhi/ota/ 的 GET 请求"""
|
||||
try:
|
||||
server_config = self.config["server"]
|
||||
local_ip = get_local_ip()
|
||||
port = int(server_config.get("port", 8000))
|
||||
websocket_url = self._get_websocket_url(local_ip, port)
|
||||
message = f"OTA接口运行正常,向设备发送的websocket地址是:{websocket_url}"
|
||||
response = web.Response(text=message, content_type="text/plain")
|
||||
except Exception as e:
|
||||
self.logger.bind(tag=TAG).error(f"OTA GET请求异常: {e}")
|
||||
response = web.Response(text="OTA接口异常", content_type="text/plain")
|
||||
finally:
|
||||
# 添加header,允许跨域访问
|
||||
response.headers["Access-Control-Allow-Headers"] = (
|
||||
"client-id, content-type, device-id"
|
||||
)
|
||||
response.headers["Access-Control-Allow-Credentials"] = "true"
|
||||
response.headers["Access-Control-Allow-Origin"] = "*"
|
||||
return response
|
||||
@@ -27,18 +27,6 @@ class WebSocketServer:
|
||||
host = server_config.get("ip", "0.0.0.0")
|
||||
port = int(server_config.get("port", 8000))
|
||||
|
||||
self.logger.bind(tag=TAG).info(
|
||||
"Server is running at ws://{}:{}/xiaozhi/v1/", get_local_ip(), port
|
||||
)
|
||||
self.logger.bind(tag=TAG).info(
|
||||
"=======上面的地址是websocket协议地址,请勿用浏览器访问======="
|
||||
)
|
||||
self.logger.bind(tag=TAG).info(
|
||||
"如想测试websocket请用谷歌浏览器打开test目录下的test_page.html"
|
||||
)
|
||||
self.logger.bind(tag=TAG).info(
|
||||
"=============================================================\n"
|
||||
)
|
||||
async with websockets.serve(self._handle_connection, host, port):
|
||||
await asyncio.Future()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user