This commit is contained in:
zpc 2025-03-28 20:03:52 +08:00
parent ee18fd55a5
commit 5666bd3cc9
7 changed files with 177 additions and 49 deletions

View File

@ -1,9 +1,38 @@
@echo off
echo.
setlocal enabledelayedexpansion
:: 配置参数
set LOG_FILE=ShengShengBuXi.log
set MAX_LOG_SIZE=1048576 :: 最大日志大小1MB
set RESTART_DELAY=1 :: 重启延迟(秒)
set APP_NAME=ShengShengBuXi.ConsoleApp.exe
:: 初始化日志
if not exist "%LOG_FILE%" (
echo 日志创建时间: %date% %time% > "%LOG_FILE%"
echo ======================================= >> "%LOG_FILE%"
)
:restart
echo start - %date% %time%
start /wait /min ShengShengBuXi.ConsoleApp.exe
echo ext...
timeout /t 0 /nobreak > nul
:: 检查日志大小并轮转
for %%F in ("%LOG_FILE%") do set LOG_SIZE=%%~zF
if !LOG_SIZE! gtr %MAX_LOG_SIZE% (
echo 日志文件过大(!LOG_SIZE!字节),正在轮转... >> "%LOG_FILE%"
move /y "%LOG_FILE%" "ShengShengBuXi_%date:/=-%_%time::=-%.log" >nul
echo 新日志创建时间: %date% %time% > "%LOG_FILE%"
echo ======================================= >> "%LOG_FILE%"
)
:: 记录启动信息
echo [%date% %time%] 启动 %APP_NAME% >> "%LOG_FILE%"
:: 启动程序并重定向输出
start /b /wait "%APP_NAME%" >> "%LOG_FILE%" 2>&1
:: 记录退出信息
echo [%date% %time%] 程序退出,代码: !errorlevel! >> "%LOG_FILE%"
echo [%date% %time%] 将在 %RESTART_DELAY% 秒后重启... >> "%LOG_FILE%"
:: 延迟后重启
timeout /t %RESTART_DELAY% /nobreak >nul
goto restart

View File

@ -22,6 +22,11 @@ public class AppSettings
/// </summary>
public bool AutoConnectToServer { get; set; } = true;
/// <summary>
/// 是否允许离线启动
/// </summary>
public bool AllowOfflineStart { get; set; } = false;
/// <summary>
/// 从文件加载设置
/// </summary>

View File

@ -103,7 +103,42 @@ public class Program
if (appSettings.AutoConnectToServer)
{
Console.WriteLine($"正在连接到服务器: {appSettings.SignalRHubUrl}");
await signalRService.StartConnectionAsync(appSettings.SignalRHubUrl);
int retryCount = 0;
bool connected = false;
while (retryCount < 10)
{
try
{
await signalRService.StartConnectionAsync(appSettings.SignalRHubUrl);
connected = true;
break;
}
catch (Exception ex)
{
retryCount++;
Console.WriteLine($"连接失败 (第{retryCount}次): {ex.Message}");
if (retryCount >= 10)
{
if (!appSettings.AllowOfflineStart)
{
Console.WriteLine("达到最大重试次数,程序将退出");
return;
}
else
{
Console.WriteLine("达到最大重试次数,但配置允许离线启动,将继续运行");
break;
}
}
await Task.Delay(1000);
}
}
if (!connected && !appSettings.AllowOfflineStart)
{
Console.WriteLine("无法连接到服务器且不允许离线启动,程序将退出");
return;
}
}
// 启动电话亭服务

View File

@ -16,6 +16,9 @@ public class SignalRService : ISignalRService
private PhoneBoothConfig _currentConfig;
private readonly SemaphoreSlim _semaphore = new(1, 1);
private string? _clientId;
private bool _isInitialConnection = true;
private const int MAX_RETRY_COUNT = 10;
private const int RETRY_INTERVAL_MS = 1000;
/// <summary>
/// 连接状态改变事件
@ -57,7 +60,16 @@ public class SignalRService : ISignalRService
{
if (_hubConnection != null)
{
return;
try
{
await _hubConnection.StopAsync();
await _hubConnection.DisposeAsync();
_hubConnection = null;
}
catch (Exception ex)
{
Console.WriteLine($"停止旧连接失败: {ex.Message}");
}
}
_hubConnection = new HubConnectionBuilder()
@ -68,14 +80,47 @@ public class SignalRService : ISignalRService
// 注册连接关闭事件
_hubConnection.Closed += async (error) =>
{
await Task.Delay(new Random().Next(0, 5) * 1000);
ConnectionStateChanged?.Invoke(this, false);
await _hubConnection.StartAsync();
Console.WriteLine($"SignalR连接已关闭: {error?.Message ?? ""}");
if (_isInitialConnection)
{
// 初始连接失败,尝试重连
int retryCount = 0;
while (retryCount < MAX_RETRY_COUNT)
{
try
{
Console.WriteLine($"尝试重新连接服务器 (第{retryCount + 1}次)...");
await _hubConnection.StartAsync();
Console.WriteLine("重新连接成功");
ConnectionStateChanged?.Invoke(this, true);
return;
}
catch (Exception ex)
{
retryCount++;
Console.WriteLine($"重连失败: {ex.Message}");
if (retryCount >= MAX_RETRY_COUNT)
{
Console.WriteLine($"达到最大重试次数({MAX_RETRY_COUNT}),程序将退出");
Environment.Exit(1);
}
await Task.Delay(RETRY_INTERVAL_MS);
}
}
}
else
{
// 运行时的连接断开,直接退出程序
Console.WriteLine("SignalR连接断开程序将退出");
Environment.Exit(1);
}
};
// 注册连接恢复事件
_hubConnection.Reconnected += connectionId =>
{
_isInitialConnection = false;
ConnectionStateChanged?.Invoke(this, true);
return Task.CompletedTask;
};
@ -120,6 +165,7 @@ public class SignalRService : ISignalRService
try
{
await _hubConnection.StartAsync();
_isInitialConnection = false;
ConnectionStateChanged?.Invoke(this, true);
// 连接成功后,注册为控制器客户端
@ -132,6 +178,14 @@ public class SignalRService : ISignalRService
{
Console.WriteLine($"SignalR连接失败: {ex.Message}");
ConnectionStateChanged?.Invoke(this, false);
try
{
await _hubConnection.StopAsync();
await _hubConnection.DisposeAsync();
_hubConnection = null;
}
catch { /* 忽略清理时的错误 */ }
throw; // 抛出异常,让调用者处理
}
}

View File

@ -1,5 +1,6 @@
{
"SignalRHubUrl": "http://115.159.44.16/audiohub",
"SignalRHubUrl": "http://localhost:82/audiohub",
"ConfigBackupPath": "config.json",
"AutoConnectToServer": true
"AutoConnectToServer": true,
"AllowOfflineStart": false
}

View File

@ -14,6 +14,7 @@ using Newtonsoft.Json;
using ShengShengBuXi.Models;
using ShengShengBuXi.Services;
using System.Xml.Linq;
using static System.Net.Mime.MediaTypeNames;
namespace ShengShengBuXi.Hubs
{
@ -963,19 +964,33 @@ namespace ShengShengBuXi.Hubs
_presetSentences.Add("时光匆匆流逝,思念却越来越深。");
}
}
if (_presetSentencesIndex == -1)
//if (_presetSentencesIndex == -1)
//{
// _presetSentencesIndex = new Random().Next(_presetSentences.Count);
//}
//if (_presetSentencesIndex >= _presetSentences.Count)
//{
// _presetSentencesIndex = new Random().Next(_presetSentences.Count); ;
//}
_presetSentences.OrderBy(it => Guid.NewGuid()).ToList().ForEach(item =>
{
_presetSentencesIndex = new Random().Next(_presetSentences.Count);
}
if (_presetSentencesIndex >= _presetSentences.Count)
{
_presetSentencesIndex = new Random().Next(_presetSentences.Count); ;
}
var displayText = new DisplayText
{
Id = Guid.NewGuid(),
Text = item,
Timestamp = DateTime.Now,
IsRealUser = false,
RecognitionId = ""
};
//AddRecognizedTextToDisplay(item, false);
_displayTextQueue.TryAdd(displayText.Id, displayText);
//_logger.LogInformation($"添加预设文本到显示队列: {text}");
});
// 从未最近显示过的句子中随机选择一条
string randomText = _presetSentences[_presetSentencesIndex];
AddRecognizedTextToDisplay(randomText, false);
_presetSentencesIndex += new Random().Next(3);
//string randomText = _presetSentences[_presetSentencesIndex];
//_presetSentencesIndex += new Random().Next(3);
}
catch (Exception ex)
@ -1005,11 +1020,7 @@ namespace ShengShengBuXi.Hubs
// 写入默认的预设句子
File.WriteAllLines(_sentencesFilePath, new string[] {
"记得每到夏天傍晚,您就摇着蒲扇坐在藤椅里,把切好的西瓜最甜那块硬塞给我,自己却啃着靠近皮的白瓤,还笑着说:外公就爱这口,清爽。",
"女儿啊 花开了 你否到了吗?",
"外公,你在那边过的还好么大家都很想称,记得常回家看看",
"外公,今天窗台上的茉莉开了,白盈盈的,就像以前您总别在中山装口袋上的那朵。",
"外公,巷口那家老茶馆拆了,您最爱坐的靠窗位置再也找不到了,就像再也找不到您一样。"
});
}

View File

@ -228,7 +228,6 @@
* @@param {string} text - 要添加的文字
*/
function addToHistory(text, id) {
// 检查是否需要翻页
if (checkNeedTurnPage(id)) {
let currentPage = $("#magazine").turn("page");
@ -251,32 +250,25 @@
$('#l_container_' + (currentPage1 - 2)).html('');
$('#r_container_' + (currentPage1 - 1)).html('');
console.log('#r_container_' + (currentPage1 - 1), $('#r_container_' + (currentPage1 - 1)));
}, 300);
}, 600); // 增加延时以配合更慢的翻页速度
return false;
}
const container = $(id);
// 创建新的段落元素
const newP = $('<p class="vertical-text"></p>');
// 插入到容器的最前面
container.prepend(newP);
// 将新段落添加到容器的末尾(而不是开头)
container.append(newP);
// 使用打字机效果显示文字
let i = 0;
function typeHistoryText() {
if (i < text.length) {
// 创建字符 span 并设置初始透明度
const charSpan = $('<span></span>').text(text.charAt(i));
charSpan.css('opacity', 0);
newP.append(charSpan);
// 字符淡入效果
charSpan.animate({opacity: 1}, CONFIG.leftContainer.typewriterSpeed * 0.8, function() {
i++;
setTimeout(typeHistoryText, CONFIG.leftContainer.typewriterSpeed * 0.2);
});
}
}
typeHistoryText();
// 设置初始透明度为0
newP.css('opacity', 0);
// 设置文本内容
newP.text(text);
// 整条文字渐显效果
newP.animate(
{ opacity: 1 },
1500, // 设置动画时长为1.5秒
'swing'
);
return true;
}
@ -474,9 +466,10 @@
$('#magazine').turn({
display: 'double',
acceleration: true,
pages: numberOfPages, // 设置总页数
pages: numberOfPages,
gradients: !$.isTouch,
elevation: 50,
duration: 2000, // 增加翻页动画时长到2000毫秒原来的两倍
when: {
// 翻页过程中的回调函数
turning: function (e, page, view) {