完整代码
using CyberWin_TradeTest_NET8Sensvoice2026.CyberWin.UIinteract;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
namespace CyberWin_TradeTest_NET8Sensvoice2026.CyberWin.CyberIntent
{
/// <summary>
/// CyberWin ASR 音频接收服务类 (2026版本)
/// </summary>
///
/// <summary>
/// CyberWin ASR 音频接收服务类 (2026版本) - 纯.NET 8控制台版
/// </summary>
public class CyberWin_Net_Server_ASR2026 : IDisposable
{
#region 私有字段
private HttpListener _httpListener;
private CancellationTokenSource _cts;
private Thread _listenerThread;
private readonly int _port;
private readonly string _saveDirectory;
private bool _isRunning;
#endregion
#region 托管处理委托(文件和文本处理)
/// <summary>
/// 文件保存后执行的托管处理委托
/// </summary>
/// <param name="filePath">保存的文件路径</param>
/// <param name="fileName">文件名</param>
public delegate void FileProcessDelegate(string filePath, string fileName);
/// <summary>
/// 文本处理托管委托
/// </summary>
/// <param name="text">需要处理的文本内容</param>
public delegate void TextProcessDelegate(string text);
/// <summary>
/// 文件处理托管事件
/// </summary>
public event FileProcessDelegate OnFileProcess;
/// <summary>
/// 文本处理托管事件
/// </summary>
public event TextProcessDelegate OnTextProcess;
#endregion
#region 构造函数
/// <summary>
/// 初始化音频接收服务
/// </summary>
/// <param name="port">服务端口(默认20362)</param>
/// <param name="saveDirectory">文件保存目录(默认wavtemp)</param>
public CyberWin_Net_Server_ASR2026(int port = 20362, string saveDirectory = "wavtemp")
{
_port = port;
_saveDirectory = saveDirectory;
_cts = new CancellationTokenSource();
// 确保保存目录存在
if (!Directory.Exists(_saveDirectory))
{
Directory.CreateDirectory(_saveDirectory);
GlobalLogManagerV12.WriteGlobalLog($"创建文件保存目录:{Path.GetFullPath(_saveDirectory)}");
}
// 检查HttpListener是否可用(Windows需要管理员权限,Linux/Mac无需)
if (!HttpListener.IsSupported)
{
throw new PlatformNotSupportedException("当前系统不支持HttpListener,请使用Windows系统或升级.NET版本");
}
}
#endregion
#region 核心方法
/// <summary>
/// 启动音频接收服务
/// </summary>
public async Task StartAsync作废()
{
if (_isRunning)
{
GlobalLogManagerV12.WriteGlobalLog("服务已在运行中,无需重复启动");
return;
}
try
{
// 初始化HttpListener
_httpListener = new HttpListener();
// _httpListener.Prefixes.Add($"http://0.0.0.0:{_port}/");
// 修复1:替换0.0.0.0为localhost + 本机IP,兼容Windows系统
var prefixes = new List<string>
{
// 优先绑定localhost
$"http://localhost:{_port}/",
// 绑定本机所有IP(Windows兼容写法)
$"http://127.0.0.1:{_port}/"
};
_httpListener.Prefixes.Add($"http://*:{_port}/");
// 启动监听
GlobalLogManagerV12.WriteGlobalLog($"正在启动音频接收服务,端口:{_port}");
_httpListener.Start();
// 启动监听线程(异步处理请求)
_listenerThread = new Thread(async () => await ListenForRequests())
{
IsBackground = true,
Name = "AudioServerListenerThread"
};
_listenerThread.Start();
_isRunning = true;
GlobalLogManagerV12.WriteGlobalLog($"服务启动成功!地址:http://0.0.0.0:{_port}");
GlobalLogManagerV12.WriteGlobalLog($"文件保存目录:{Path.GetFullPath(_saveDirectory)}");
}
catch (Exception ex)
{
GlobalLogManagerV12.WriteGlobalLog($"服务启动失败:{ex.Message}");
if (ex is HttpListenerException && ex.Message.Contains("拒绝访问"))
{
GlobalLogManagerV12.WriteGlobalLog("提示:Windows系统下运行HttpListener需要管理员权限,请以管理员身份启动程序");
}
throw;
}
}
/// <summary>
/// 停止音频接收服务
/// </summary>
public Task StopAsync()
{
if (!_isRunning)
{
GlobalLogManagerV12.WriteGlobalLog("服务未运行,无需停止");
return Task.CompletedTask;
}
try
{
GlobalLogManagerV12.WriteGlobalLog("正在停止音频接收服务...");
// 取消令牌
_cts.Cancel();
// 停止监听
if (_httpListener != null && _httpListener.IsListening)
{
_httpListener.Stop();
_httpListener.Close();
_httpListener = null;
}
// 等待线程退出
if (_listenerThread != null && _listenerThread.IsAlive)
{
_listenerThread.Join(1000);
}
_isRunning = false;
// GlobalLogManagerV12.WriteGlobalLog("服务已成功停止");
}
catch (Exception ex)
{
GlobalLogManagerV12.WriteGlobalLog($"服务停止失败:{ex.Message}");
throw;
}
return Task.CompletedTask;
}
/// <summary>
/// 托管运行服务(阻塞主线程)
/// </summary>
public void Run()
{
if (_isRunning)
{
GlobalLogManagerV12.WriteGlobalLog("服务已在运行中");
return;
}
// 同步启动
// StartAsync().Wait();
//StartAsyncV3();
StartAsyncV6();
// 阻塞主线程
GlobalLogManagerV12.WriteGlobalLog("服务已进入托管运行模式,按 ESC 键停止...");
/*
while (true)
{
var key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Escape)
{
break;
}
}
*/
// 停止服务
// StopAsync().Wait();
}
/// <summary>
/// 监听并处理HTTP请求
/// </summary>
private async Task ListenForRequests()
{
while (!_cts.Token.IsCancellationRequested && _httpListener != null && _httpListener.IsListening)
{
try
{
// 异步获取请求(可取消)
var context = await _httpListener.GetContextAsync().WaitAsync(_cts.Token);
// 处理请求(异步,避免阻塞监听)
_ = Task.Run(async () => await HandleRequest(context), _cts.Token);
}
catch (OperationCanceledException)
{
// 正常取消,无需处理
break;
}
catch (Exception ex)
{
if (!_cts.Token.IsCancellationRequested)
{
GlobalLogManagerV12.WriteGlobalLog($"请求监听异常:{ex.Message}");
}
}
}
}
/// <summary>
/// 处理单个HTTP请求
/// </summary>
private async Task HandleRequest(HttpListenerContext context)
{
var response = context.Response;
try
{
var request = context.Request;
// 处理OPTIONS预检请求(跨域)
if (request.HttpMethod == "OPTIONS")
{
response.StatusCode = (int)HttpStatusCode.OK;
SetCorsHeaders(response);
response.Close();
return;
}
// 只处理POST /upload-audio请求
if (request.HttpMethod != "POST" || !request.Url.AbsolutePath.Equals("/upload-audio", StringComparison.OrdinalIgnoreCase))
{
// 健康检查
if (request.HttpMethod == "GET" && request.Url.AbsolutePath == "/")
{
response.StatusCode = (int)HttpStatusCode.OK;
response.ContentType = "text/plain; charset=utf-8";
var welcomeMsg = Encoding.UTF8.GetBytes("CyberWin ASR 音频接收服务已启动 (2026)\n上传接口:POST /upload-audio");
response.ContentLength64 = welcomeMsg.Length;
await response.OutputStream.WriteAsync(welcomeMsg);
response.Close();
return;
}
// 无效请求
response.StatusCode = (int)HttpStatusCode.NotFound;
var notFoundMsg = Encoding.UTF8.GetBytes("404 Not Found");
response.ContentLength64 = notFoundMsg.Length;
await response.OutputStream.WriteAsync(notFoundMsg);
response.Close();
return;
}
// 处理音频上传
await HandleAudioUpload(request, response);
}
catch (Exception ex)
{
GlobalLogManagerV12.WriteGlobalLog($"请求处理异常:{ex.Message} | 堆栈:{ex.StackTrace}");
// 返回错误响应
response.StatusCode = (int)HttpStatusCode.InternalServerError;
response.ContentType = "application/json; charset=utf-8";
SetCorsHeaders(response);
var errorJson = Encoding.UTF8.GetBytes($"{{\"success\":false,\"message\":\"{ex.Message}\"}}");
response.ContentLength64 = errorJson.Length;
await response.OutputStream.WriteAsync(errorJson);
}
finally
{
response.Close();
}
}
/// <summary>
/// 处理音频文件上传
/// </summary>
private async Task HandleAudioUpload(HttpListenerRequest request, HttpListenerResponse response)
{
// 验证Content-Type
if (!request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase))
{
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.ContentType = "application/json; charset=utf-8";
SetCorsHeaders(response);
var errorMsg = Encoding.UTF8.GetBytes("{\"success\":false,\"message\":\"请求格式错误,请使用multipart/form-data格式\"}");
response.ContentLength64 = errorMsg.Length;
await response.OutputStream.WriteAsync(errorMsg);
GlobalLogManagerV12.WriteGlobalLog("上传失败:请求格式错误,非multipart/form-data");
return;
}
try
{
// 解析multipart/form-data
var boundary = request.ContentType.Split('=')[1];
var boundaryBytes = Encoding.ASCII.GetBytes($"--{boundary}");
var buffer = new byte[4096];
var ms = new MemoryStream();
// 读取请求体
int bytesRead;
while ((bytesRead = await request.InputStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await ms.WriteAsync(buffer, 0, bytesRead);
}
ms.Position = 0;
// 查找音频文件部分
var audioData = ExtractAudioFromMultipart(ms, boundary);
if (audioData == null || audioData.Length == 0)
{
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.ContentType = "application/json; charset=utf-8";
SetCorsHeaders(response);
var errorMsg = Encoding.UTF8.GetBytes("{\"success\":false,\"message\":\"未找到有效的音频文件\"}");
response.ContentLength64 = errorMsg.Length;
await response.OutputStream.WriteAsync(errorMsg);
GlobalLogManagerV12.WriteGlobalLog("上传失败:未找到有效的音频文件");
return;
}
// 生成文件名:8位随机字符串 + 年月日时分秒 + .wav
var randomStr = Guid.NewGuid().ToString("N").Substring(0, 8);
var timeStr = DateTime.Now.ToString("yyyyMMddHHmmss");
var fileName = $"{randomStr}{timeStr}.wav";
var savePath = Path.Combine(_saveDirectory, fileName);
// 保存文件
await File.WriteAllBytesAsync(savePath, audioData);
GlobalLogManagerV12.WriteGlobalLog($"文件上传成功:{fileName} | 保存路径:{Path.GetFullPath(savePath)} | 大小:{FormatFileSize(audioData.Length)}");
// 执行托管的文件处理逻辑
OnFileProcess?.Invoke(savePath, fileName);
// 触发文本处理事件
var textContent = $"音频文件 {fileName} 已保存,大小:{FormatFileSize(audioData.Length)}";
OnTextProcess?.Invoke(textContent);
// 返回成功响应
response.StatusCode = (int)HttpStatusCode.OK;
response.ContentType = "application/json; charset=utf-8";
SetCorsHeaders(response);
var successJson = Encoding.UTF8.GetBytes($"{{\"success\":true,\"message\":\"文件上传成功\",\"fileName\":\"{fileName}\",\"savePath\":\"{Path.GetFullPath(savePath)}\"}}");
response.ContentLength64 = successJson.Length;
await response.OutputStream.WriteAsync(successJson);
}
catch (Exception ex)
{
throw new Exception($"文件解析/保存失败:{ex.Message}", ex);
}
}
#endregion
#region 辅助方法
/// <summary>
/// 从multipart/form-data中提取音频数据
/// </summary>
private byte[] ExtractAudioFromMultipart(MemoryStream ms, string boundary)
{
ms.Position = 0;
var reader = new StreamReader(ms, Encoding.UTF8);
var boundaryLine = $"--{boundary}";
string line;
// 跳过边界行
while ((line = reader.ReadLine()) != null)
{
if (line == boundaryLine)
{
break;
}
}
// 查找音频文件部分
while ((line = reader.ReadLine()) != null)
{
if (line.Contains("Content-Type: audio/"))
{
// 跳过空行,到达数据部分
reader.ReadLine();
// 读取音频数据
var dataStart = (int)ms.Position;
var buffer = new List<byte>();
var boundaryBytes = Encoding.ASCII.GetBytes(boundaryLine);
var tempBuffer = new byte[1];
// 读取直到下一个边界
while (ms.Read(tempBuffer, 0, 1) > 0)
{
// 检查是否到达边界
if (tempBuffer[0] == '-' && ms.Position + boundaryBytes.Length - 1 <= ms.Length)
{
var pos = ms.Position;
var checkBuffer = new byte[boundaryBytes.Length];
ms.Read(checkBuffer, 0, boundaryBytes.Length);
if (checkBuffer.SequenceEqual(boundaryBytes))
{
ms.Position = pos - 1;
break;
}
ms.Position = pos;
}
buffer.Add(tempBuffer[0]);
}
// 移除最后几个多余的字节(--\r\n)
if (buffer.Count > 4)
{
buffer.RemoveRange(buffer.Count - 4, 4);
}
return buffer.ToArray();
}
}
return null;
}
/// <summary>
/// 设置跨域响应头
/// </summary>
private void SetCorsHeaders(HttpListenerResponse response)
{
response.Headers.Add("Access-Control-Allow-Origin", "*");
response.Headers.Add("Access-Control-Allow-Methods", "POST, OPTIONS");
response.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
}
/// <summary>
/// 格式化文件大小
/// </summary>
private string FormatFileSize(long bytes)
{
string[] sizes = { "B", "KB", "MB", "GB" };
double len = bytes;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1)
{
order++;
len /= 1024;
}
return $"{len:0.##} {sizes[order]}";
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
if (_isRunning)
{
StopAsync().Wait();
}
_cts?.Dispose();
_httpListener?.Close();
}
public async Task StartAsync作废2()
{
if (_isRunning)
{
GlobalLogManagerV12.WriteGlobalLog("服务已在运行中,无需重复启动");
return;
}
try
{
// 初始化HttpListener
_httpListener = new HttpListener();
// 清空原有前缀,避免重复绑定导致的异常
_httpListener.Prefixes.Clear();
// 仅保留*绑定(Windows需先授权端口),移除多余的prefixes列表
_httpListener.Prefixes.Add($"http://*:{_port}/");
GlobalLogManagerV12.WriteGlobalLog($"正在启动音频接收服务,端口:{_port}");
// 启动监听(核心修复:添加错误码判断,精准提示权限/端口问题)
try
{
_httpListener.Start();
}
catch (HttpListenerException ex)
{
// 错误码5=权限不足,10048=端口占用
if (ex.ErrorCode == 5)
{
GlobalLogManagerV12.WriteGlobalLog("错误:Windows需要管理员权限!请执行命令授权端口:netsh http add urlacl url=http://*:" + _port + "/ user=Everyone");
throw;
}
else if (ex.ErrorCode == 10048)
{
GlobalLogManagerV12.WriteGlobalLog("错误:端口" + _port + "已被占用!");
throw;
}
else
{
throw;
}
}
/*
// 启动监听线程(核心修复:移除IsBackground=true,避免线程随主线程退出)
_listenerThread = new Thread(async () => await ListenForRequests())
{
// 关键修复:设为前台线程,防止服务启动后被关闭
IsBackground = false,
Name = "AudioServerListenerThread"
};
*/
// _listenerThread.Start();
_isRunning = true;
GlobalLogManagerV12.WriteGlobalLog($"服务启动成功!地址:http://localhost:{_port}");
GlobalLogManagerV12.WriteGlobalLog($"文件保存目录:{Path.GetFullPath(_saveDirectory)}");
GlobalLogManagerV12.WriteGlobalLog($"IsListening:{_httpListener.IsListening.ToString()}");
_listenerThread = new Thread(() =>
{
while (_isRunning && _httpListener.IsListening)
{
try
{
// 异步获取请求(非阻塞)
var context = _httpListener.GetContext();
// 异步处理单个请求(避免阻塞监听循环)
_ = Task.Run(async () => await HandleRequest(context));
}
catch (HttpListenerException ex)
{
// 仅在非停止状态下记录异常
if (_httpListener != null && _httpListener.IsListening)
{
GlobalLogManagerV12.WriteGlobalLog($"监听请求异常:{ex.Message}");
}
break;
}
catch (Exception ex)
{
GlobalLogManagerV12.WriteGlobalLog($"请求接收异常:{ex.Message}");
}
}
})
{
IsBackground = true, // 改回匿名后台线程,不阻塞主线程
Name = "AudioServerListenerThread",
Priority = ThreadPriority.Normal // 提高线程优先级,避免被系统挂起
};
_listenerThread.Start();
//_listenerThread.Start();
}
catch (Exception ex)
{
GlobalLogManagerV12.WriteGlobalLog($"服务启动失败:{ex.Message}"+ex.InnerException+ex.StackTrace+ex.Source);
// 启动失败时清理资源,避免内存泄漏
if (_httpListener != null)
{
try { _httpListener.Close(); } catch { }
}
throw;
}
}
public void StartAsyncV3()
{
if (_isRunning)
{
GlobalLogManagerV12.WriteGlobalLog("服务已在运行中,无需重复启动");
return;
}
// 先初始化线程变量,避免空引用
_listenerThread = null;
try
{
// 1. 初始化HttpListener(基础配置)
_httpListener = new HttpListener();
_httpListener.Prefixes.Clear();
// 兼容写法:同时绑定localhost和*(解决部分系统*绑定失败问题)
// _httpListener.Prefixes.Add($"http://localhost:{_port}/");
// _httpListener.Prefixes.Add($"http://127.0.0.1:{_port}/");
_httpListener.Prefixes.Add($"http://*:{_port}/");
GlobalLogManagerV12.WriteGlobalLog($"正在启动音频接收服务,端口:{_port}");
// 2. 启动监听(带精准错误处理)
try
{
_httpListener.Start();
}
catch (HttpListenerException ex)
{
string errorMsg = ex.ErrorCode switch
{
5 => $"权限不足!请以管理员身份运行CMD执行:netsh http add urlacl url=http://localhost:{_port}/ user=Everyone",
10048 => $"端口{_port}已被占用!执行 netstat -ano | findstr :{_port} 查看占用程序",
_ => $"启动失败(错误码{ex.ErrorCode}):{ex.Message}"
};
GlobalLogManagerV12.WriteGlobalLog("错误:" + errorMsg);
throw new Exception(errorMsg, ex);
}
// 3. 启动监听线程(最简稳定版)
_listenerThread = new Thread(ListenForRequests_新的3) // 直接绑定方法,避免匿名委托坑
{
IsBackground = true,
Name = "AudioServerListenerThread",
Priority = ThreadPriority.AboveNormal // 提高优先级,防止被系统挂起
};
_listenerThread.Start();
// 4. 标记运行状态
_isRunning = true;
// 输出启动成功日志
GlobalLogManagerV12.WriteGlobalLog($"✅ 服务启动成功!");
GlobalLogManagerV12.WriteGlobalLog($"🔗 访问地址:http://localhost:{_port}");
GlobalLogManagerV12.WriteGlobalLog($"📁 保存目录:{Path.GetFullPath(_saveDirectory)}");
GlobalLogManagerV12.WriteGlobalLog($"📌 监听状态:{_httpListener.IsListening}");
}
catch (Exception ex)
{
// 启动失败清理资源
GlobalLogManagerV12.WriteGlobalLog($"❌ 服务启动失败:{ex.Message}\n堆栈:{ex.StackTrace}\n内部异常:{ex.InnerException?.Message}");
if (_httpListener != null)
{
try { _httpListener.Stop(); } catch { }
try { _httpListener.Close(); } catch { }
}
_isRunning = false;
throw;
}
}
public void StartAsyncV6()
{
if (_isRunning)
{
GlobalLogManagerV12.WriteGlobalLog("服务已在运行中,无需重复启动");
return;
}
// 先初始化线程变量,避免空引用
_listenerThread = null;
try
{
// 1. 初始化HttpListener(基础配置)
_httpListener = new HttpListener();
_httpListener.Prefixes.Clear();
// 兼容写法:同时绑定localhost和*(解决部分系统*绑定失败问题)
// _httpListener.Prefixes.Add($"http://localhost:{_port}/");
// _httpListener.Prefixes.Add($"http://127.0.0.1:{_port}/");
_httpListener.Prefixes.Add($"http://*:{_port}/");
GlobalLogManagerV12.WriteGlobalLog($"正在启动音频接收服务,端口:{_port}");
// 2. 启动监听(带精准错误处理)
try
{
_httpListener.Start();
}
catch (HttpListenerException ex)
{
string errorMsg = ex.ErrorCode switch
{
5 => $"权限不足!请以管理员身份运行CMD执行:netsh http add urlacl url=http://localhost:{_port}/ user=Everyone",
10048 => $"端口{_port}已被占用!执行 netstat -ano | findstr :{_port} 查看占用程序",
_ => $"启动失败(错误码{ex.ErrorCode}):{ex.Message}"
};
GlobalLogManagerV12.WriteGlobalLog("错误:" + errorMsg);
throw new Exception(errorMsg, ex);
}
// 3. 启动监听线程(最简稳定版)
_listenerThread = new Thread(ListenForRequests_新的3) // 直接绑定方法,避免匿名委托坑
{
IsBackground = true,
Name = "AudioServerListenerThread",
Priority = ThreadPriority.AboveNormal // 提高优先级,防止被系统挂起
};
_listenerThread.Start();
// 4. 标记运行状态
_isRunning = true;
// 输出启动成功日志
GlobalLogManagerV12.WriteGlobalLog($"✅ 服务启动成功!");
GlobalLogManagerV12.WriteGlobalLog($"🔗 访问地址:http://localhost:{_port}");
GlobalLogManagerV12.WriteGlobalLog($"📁 保存目录:{Path.GetFullPath(_saveDirectory)}");
GlobalLogManagerV12.WriteGlobalLog($"📌 监听状态:{_httpListener.IsListening}");
}
catch (Exception ex)
{
// 启动失败清理资源
GlobalLogManagerV12.WriteGlobalLog($"❌ 服务启动失败:{ex.Message}\n堆栈:{ex.StackTrace}\n内部异常:{ex.InnerException?.Message}");
if (_httpListener != null)
{
try { _httpListener.Stop(); } catch { }
try { _httpListener.Close(); } catch { }
}
_isRunning = false;
throw;
}
}
// ===================== 必须配套的 ListenForRequests 方法(核心监听逻辑) =====================
private void ListenForRequests_新的3()
{
// 循环监听:只要服务运行且监听状态正常,就一直等请求
while (_isRunning && _httpListener != null && _httpListener.IsListening)
{
try
{
// 阻塞等待请求(这是HttpListener的标准用法,不会占用高CPU)
var context = _httpListener.GetContext();
// 异步处理请求(不阻塞监听循环)
_ = Task.Run(() => HandleRequest(context));
}
catch (HttpListenerException ex)
{
// 只有监听被主动停止时的异常才忽略,其他异常记录
if (_isRunning)
{
GlobalLogManagerV12.WriteGlobalLog($"监听异常:{ex.Message}(错误码{ex.ErrorCode})");
}
break;
}
catch (Exception ex)
{
GlobalLogManagerV12.WriteGlobalLog($"请求接收异常:{ex.Message}");
}
}
GlobalLogManagerV12.WriteGlobalLog($"监听线程退出(运行状态:{_isRunning} | 监听状态:{_httpListener?.IsListening})");
}
// ===================== 必须配套的 HandleRequest 方法(最小化请求处理) =====================
private async Task HandleRequest_新的3(HttpListenerContext context)
{
var response = context.Response;
try
{
// 最简处理:先返回成功,证明请求能收到
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
response.ContentType = "text/plain; charset=utf-8";
var responseBytes = System.Text.Encoding.UTF8.GetBytes("服务已收到请求!");
response.ContentLength64 = responseBytes.Length;
await response.OutputStream.WriteAsync(responseBytes);
GlobalLogManagerV12.WriteGlobalLog($"收到请求:{context.Request.HttpMethod} {context.Request.Url}");
}
catch (Exception ex)
{
GlobalLogManagerV12.WriteGlobalLog($"请求处理异常:{ex.Message}");
response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
var errorBytes = System.Text.Encoding.UTF8.GetBytes($"处理失败:{ex.Message}");
response.ContentLength64 = errorBytes.Length;
await response.OutputStream.WriteAsync(errorBytes);
}
finally
{
// 必须关闭响应,否则连接会泄漏
response.Close();
}
}
#endregion
#region 属性
/// <summary>
/// 服务是否正在运行
/// </summary>
public bool IsRunning => _isRunning;
/// <summary>
/// 服务端口
/// </summary>
public int Port => _port;
/// <summary>
/// 文件保存目录
/// </summary>
public string SaveDirectory => _saveDirectory;
#endregion
}
}

前后写了10次没有一次可以启动httpserver

有条件最好别做智能硬件交互用AI写
东方仙盟:拥抱知识开源,共筑数字新生态
在全球化与数字化浪潮中,东方仙盟始终秉持开放协作、知识共享的理念,积极拥抱开源技术与开放标准。我们相信,唯有打破技术壁垒、汇聚全球智慧,才能真正推动行业的可持续发展。
开源赋能中小商户:通过将前端异常检测、跨系统数据互联等核心能力开源化,东方仙盟为全球中小商户提供了低成本、高可靠的技术解决方案,让更多商家能够平等享受数字转型的红利。
共建行业标准:我们积极参与国际技术社区,与全球开发者、合作伙伴共同制定开放协议与技术规范,推动跨境零售、文旅、餐饮等多业态的系统互联互通,构建更加公平、高效的数字生态。
知识普惠,共促发展:通过开源社区、技术文档与培训体系,东方仙盟致力于将前沿技术转化为可落地的行业实践,赋能全球合作伙伴,共同培育创新人才,推动数字经济的普惠式增长
阿雪技术观
在科技发展浪潮中,我们不妨积极投身技术共享。不满足于做受益者,更要主动担当贡献者。无论是分享代码、撰写技术博客,还是参与开源项目维护改进,每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地,我们携手在此探索硅基生命,为科技进步添砖加瓦。
Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Don't just be the one reaping all the benefits; step up and be a contributor too. Whether you're tossing out your code snippets, hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. We're gonna team up and explore the whole silicon - based life thing, and in the process, we'll be fueling the growth of technology.