Managers/WebServer.cs

Managers/WebServer.cs
using nanoFramework.WebServer;using System;using System.Diagnostics;using System.IO;using System.Text;namespace YeFanIoTTest.Managers{// Web服务器控制器// 处理AP配网的HTTP请求// 【重要】必须是public类否则WebServer无法实例化public class WebServerController{// 静态APConfigManager实例引用private static APConfigManager _apConfigManager;// 设置APConfigManager实例internal因为APConfigManager是internalinternal static void SetAPConfigManager(APConfigManager apConfigManager){_apConfigManager apConfigManager;}// 配网页面路由 // GET / - 配网主页[Route()][Method(GET)]public void GetIndex(WebServerEventArgs e){Debug.WriteLine([WebServer] Received GET request );Debug.WriteLine($[WebServer] Remote endpoint: {e.Context.Request.RemoteEndPoint});Debug.WriteLine($[WebServer] Request URL: {e.Context.Request.RawUrl});// 直接输出HTML不进行任何检查string html GetConfigPageHtml();e.Context.Response.ContentType text/html;WebServer.OutputAsStream(e.Context.Response, html);Debug.WriteLine([WebServer] Response sent successfully);}// POST /config - 处理配网表单提交[Route(config)][Method(POST)]public void PostConfig(WebServerEventArgs e){try{// 解析表单数据string body GetRequestBody(e);// 解析SSID和密码string ssid ParseFormField(body, ssid);string password ParseFormField(body, password);if (string.IsNullOrEmpty(ssid) || string.IsNullOrEmpty(password)){string errorHtml GetErrorPageHtml(SSID和密码不能为空);e.Context.Response.ContentType text/html;WebServer.OutputAsStream(e.Context.Response, errorHtml);return;}// 调用APConfigManager处理配网 if (_apConfigManager null){string errorHtml GetErrorPageHtml(系统错误APConfigManager未初始化);e.Context.Response.ContentType text/html;WebServer.OutputAsStream(e.Context.Response, errorHtml);return;}// 调用HandleConfigSubmit方法处理配网// 该方法会连接WiFi、检查网络可达性、触发OnConfigCompleted事件_apConfigManager.HandleConfigSubmit(ssid, password);// 根据配网结果显示页面// 注意HandleConfigSubmit已经处理了所有逻辑这里只需要显示结果页面// 由于HandleConfigSubmit是同步的我们可以直接检查CurrentState// 等待配网完成最多等待10秒int waitCount 0;while (_apConfigManager.CurrentState APConfigState.Connecting waitCount 100){System.Threading.Thread.Sleep(100);waitCount;}// 根据配网结果显示页面if (_apConfigManager.CurrentState APConfigState.Configured){// 配网成功string successHtml GetSuccessPageHtml(ssid);e.Context.Response.ContentType text/html;WebServer.OutputAsStream(e.Context.Response, successHtml);}else if (_apConfigManager.CurrentState APConfigState.Failed){// 配网失败string errorHtml GetErrorPageHtml(WiFi连接失败请检查SSID和密码是否正确);e.Context.Response.ContentType text/html;WebServer.OutputAsStream(e.Context.Response, errorHtml);}else{// 其他状态超时等string errorHtml GetErrorPageHtml(配网超时请重试);e.Context.Response.ContentType text/html;WebServer.OutputAsStream(e.Context.Response, errorHtml);}}catch (Exception ex){string errorHtml GetErrorPageHtml(配网失败 ex.Message);e.Context.Response.ContentType text/html;WebServer.OutputAsStream(e.Context.Response, errorHtml);}}// GET /scan - 扫描WiFi网络AP模式下不支持[Route(scan)][Method(GET)]public void GetScan(WebServerEventArgs e){// AP模式下无法扫描WiFi网络string jsonResult {\success\:false,\message\:\AP模式下不支持WiFi扫描请手动输入WiFi名称\};e.Context.Response.ContentType application/json;WebServer.OutputAsStream(e.Context.Response, jsonResult);}// 辅助方法 // 获取请求体private string GetRequestBody(WebServerEventArgs e){try{var request e.Context.Request;// 获取请求体长度long contentLength request.ContentLength64;if (contentLength 0){return string.Empty;}// 读取请求体byte[] buffer new byte[(int)contentLength];request.InputStream.Read(buffer, 0, (int)contentLength);return Encoding.UTF8.GetString(buffer, 0, (int)contentLength);}catch (Exception){return string.Empty;}}// 解析表单字段private static string ParseFormField(string body, string fieldName){try{// 格式: ssidMyWiFipassword12345678string searchPattern fieldName ;int startIndex body.IndexOf(searchPattern);if (startIndex 0){return string.Empty;}startIndex searchPattern.Length;int endIndex body.IndexOf(, startIndex);if (endIndex 0){endIndex body.Length;}string value body.Substring(startIndex, endIndex - startIndex);// URL解码return UrlDecode(value);}catch{return string.Empty;}}// URL解码private static string UrlDecode(string value){// 处理 %XX 格式的编码和 号StringBuilder result new StringBuilder();for (int i 0; i value.Length; i){if (value[i] ){// 号转换为空格result.Append( );}else if (value[i] % i 2 value.Length){// 解析十六进制值string hex value.Substring(i 1, 2);byte b HexToByte(hex);if (b 0){result.Append((char)b);i 2;}else{result.Append(value[i]);}}else{result.Append(value[i]);}}return result.ToString();}// 十六进制字符串转字节private static byte HexToByte(string hex){try{byte high HexCharToValue(hex[0]);byte low HexCharToValue(hex[1]);return (byte)((high 4) | low);}catch{return 0;}}// 十六进制字符转数值private static byte HexCharToValue(char c){if (c 0 c 9){return (byte)(c - 0);}else if (c A c F){return (byte)(c - A 10);}else if (c a c f){return (byte)(c - a 10);}return 0;}// HTML页面模板 // 配网主页HTMLprivate static string GetConfigPageHtml(){string html !DOCTYPE html;html htmlhead;html meta charset\UTF-8\;html meta name\viewport\ content\widthdevice-width, initial-scale1.0\;html titleYF3300-ESP32S3 WiFi配网/title;html style;html body{font-family:Arial;margin:20px;background:#f0f0f0;};html .container{max-width:400px;margin:0 auto;background:white;padding:20px;border-radius:10px;};html h1{color:#333;text-align:center;};html .form-group{margin-bottom:15px;};html label{display:block;margin-bottom:5px;color:#666;};html input{width:100%;padding:10px;border:1px solid #ddd;border-radius:5px;box-sizing:border-box;};html button{width:100%;padding:12px;background:#007bff;color:white;border:none;border-radius:5px;font-size:16px;cursor:pointer;};html .footer{text-align:center;margin-top:20px;color:#999;font-size:12px;};html .tip{background:#fff3cd;border:1px solid #ffc107;padding:10px;border-radius:5px;margin-bottom:15px;font-size:14px;};html /style/headbody;html div class\container\;html h1YF3300-ESP32S3 WiFi配网/h1;html div class\tip\请输入您要连接的WiFi名称和密码/div;html form action\/config\ method\POST\;html div class\form-group\;html labelWiFi名称 (SSID)/label;html input type\text\ name\ssid\ placeholder\请输入WiFi名称\ required;html /div;html div class\form-group\;html labelWiFi密码/label;html input type\password\ name\password\ placeholder\请输入WiFi密码\ required;html /div;html button type\submit\开始配网/button;html /form;html div class\footer\YF3300-ESP32S3 v1.0/div;html /div/body/html