在某些特殊的场合之下,比如没有网络的大兴安岭,克拉玛利,比如不允许上网的某些研究所,比如在飞机上。那么我们能否连接热点,上网做一款线上简易群聊呢 
基于Firebeete试用的ESP32-C5开发板以及其强大的wifi功能,我们基于其作为一个简单的服务器,提供热点连接,然后可以访问群留言聊天功能。 
  
废话不说,结果展示如下 
  
首先需要访问Esp32的热点,然后输入密码12345678,就可以使用啦,默认30秒更新一次,因为esp32能力有限,需要快速更新可以点击更新,多人使用也是可以的,这样可以聊起天来,哈哈哈哈哈,相当于一个简单群聊 
 
 
手机端也可以使用,代码展示如下: 
			
			
			- // 针对ESP32-C5优化的包含部分
 - #include <WiFi.h>
 - #include <WebServer.h>
 - #include <SPIFFS.h>
 - // 使用ArduinoJson 6.x并进行内存优化
 - #include <ArduinoJson.h>
 - 
 - /* WiFi设置 */
 - const char* ssid     = "ESP32-MessageBoard";
 - const char* password = "12345678";
 - 
 - /* IP地址设置 */
 - IPAddress local_ip(192,168,1,1);
 - IPAddress gateway(192,168,1,1);
 - IPAddress subnet(255,255,255,0);
 - 
 - // 创建Web服务器实例,使用标准HTTP端口80以便于浏览器访问
 - WebServer msgServer(80);
 - 
 - // 最多存储的留言数量 - 为ESP32-C5内存限制而减少
 - #define MAX_MESSAGES 30
 - 
 - // 留言结构体 - 优化字符串存储
 - struct Message {
 -   char author[32];  // 使用固定大小缓冲区替代String
 -   char content[256];
 -   char timestamp[16];
 - };
 - 
 - // 留言数组
 - Message messages[MAX_MESSAGES];
 - int messageCount = 0;
 - 
 - // 函数声明
 - void loadMessages();
 - void saveMessages();
 - String sendMessageBoardHTML();
 - 
 - void setup() {
 -   Serial.begin(115200);
 -   
 -   // 初始化SPIFFS,针对ESP32-C5进行错误处理
 -   if(!SPIFFS.begin(true)){
 -     Serial.println("SPIFFS挂载失败");
 -     // 尝试替代初始化方法
 -     if(!SPIFFS.begin(false)) {
 -       Serial.println("SPIFFS挂载再次失败,继续执行但功能可能受限");
 -     }
 -   }
 -   
 -   // 从文件加载留言
 -   loadMessages();
 -   
 -   // 设置WiFi接入点
 -   WiFi.softAP(ssid, password);
 -   WiFi.softAPConfig(local_ip, gateway, subnet);
 -   delay(100);
 -   
 -   // 设置Web服务器路由
 -   msgServer.on("/", HTTP_GET, handleRoot);
 -   msgServer.on("/messages", HTTP_GET, handleGetMessages);
 -   msgServer.on("/post", HTTP_POST, handlePostMessage);
 -   msgServer.onNotFound(handleNotFound);
 -   
 -   // 启动服务器
 -   msgServer.begin();
 -   Serial.println("留言板HTTP服务器已启动在端口80");
 -   Serial.print("IP地址: ");
 -   Serial.println(WiFi.softAPIP());
 - }
 - 
 - void loop() {
 -   msgServer.handleClient();
 - }
 - 
 - // 处理根路径请求
 - void handleRoot() {
 -   Serial.println("客户端已连接到留言板");
 -   msgServer.send(200, "text/html", sendMessageBoardHTML());
 - }
 - 
 - void handleNotFound() {
 -   msgServer.send(404, "text/plain", "找不到页面");
 - }
 - 
 - // 为ESP32-C5内存限制而减小JSON文档大小
 - void handleGetMessages() {
 -   // 使用StaticJsonDocument以获得更好的内存管理
 -   StaticJsonDocument<3072> doc;
 -   JsonArray array = doc.to<JsonArray>();
 -   
 -   for (int i = 0; i < messageCount; i++) {
 -     JsonObject obj = array.createNestedObject();
 -     obj["author"] = messages[i].author;
 -     obj["content"] = messages[i].content;
 -     obj["timestamp"] = messages[i].timestamp;
 -   }
 -   
 -   String response;
 -   serializeJson(doc, response);
 -   msgServer.send(200, "application/json", response);
 - }
 - 
 - void handlePostMessage() {
 -   if (msgServer.hasArg("plain")) {
 -     String message = msgServer.arg("plain");
 -     StaticJsonDocument<512> doc;
 -     DeserializationError error = deserializeJson(doc, message);
 -     
 -     if (!error) {
 -       const char* author = doc["author"];
 -       const char* content = doc["content"];
 -       
 -       // 获取当前时间(由于ESP32没有实时时钟,这里使用运行时间)
 -       unsigned long currentMillis = millis();
 -       int seconds = currentMillis / 1000;
 -       int minutes = seconds / 60;
 -       int hours = minutes / 60;
 -       
 -       minutes = minutes % 60;
 -       seconds = seconds % 60;
 -       
 -       char timestamp[16];
 -       sprintf(timestamp, "%02d:%02d:%02d", hours, minutes, seconds);
 -       
 -       // 添加新留言 - 使用strncpy处理固定缓冲区
 -       if (messageCount < MAX_MESSAGES) {
 -         strncpy(messages[messageCount].author, author, sizeof(messages[messageCount].author) - 1);
 -         messages[messageCount].author[sizeof(messages[messageCount].author) - 1] = '\0';
 -         
 -         strncpy(messages[messageCount].content, content, sizeof(messages[messageCount].content) - 1);
 -         messages[messageCount].content[sizeof(messages[messageCount].content) - 1] = '\0';
 -         
 -         strncpy(messages[messageCount].timestamp, timestamp, sizeof(messages[messageCount].timestamp) - 1);
 -         messages[messageCount].timestamp[sizeof(messages[messageCount].timestamp) - 1] = '\0';
 -         
 -         messageCount++;
 -       } else {
 -         // 如果留言已满,移除最旧的留言
 -         for (int i = 0; i < MAX_MESSAGES - 1; i++) {
 -           memcpy(&messages[i], &messages[i + 1], sizeof(Message));
 -         }
 -         
 -         strncpy(messages[MAX_MESSAGES - 1].author, author, sizeof(messages[MAX_MESSAGES - 1].author) - 1);
 -         messages[MAX_MESSAGES - 1].author[sizeof(messages[MAX_MESSAGES - 1].author) - 1] = '\0';
 -         
 -         strncpy(messages[MAX_MESSAGES - 1].content, content, sizeof(messages[MAX_MESSAGES - 1].content) - 1);
 -         messages[MAX_MESSAGES - 1].content[sizeof(messages[MAX_MESSAGES - 1].content) - 1] = '\0';
 -         
 -         strncpy(messages[MAX_MESSAGES - 1].timestamp, timestamp, sizeof(messages[MAX_MESSAGES - 1].timestamp) - 1);
 -         messages[MAX_MESSAGES - 1].timestamp[sizeof(messages[MAX_MESSAGES - 1].timestamp) - 1] = '\0';
 -       }
 -       
 -       // 保存留言到文件
 -       saveMessages();
 -       
 -       msgServer.send(200, "application/json", "{"status":"success"}");
 -     } else {
 -       msgServer.send(400, "application/json", "{"status":"error","message":"无效的JSON格式"}");
 -     }
 -   } else {
 -     msgServer.send(400, "application/json", "{"status":"error","message":"没有提供数据"}");
 -   }
 - }
 - 
 - // 保存留言到SPIFFS文件系统 - 针对ESP32-C5优化
 - void saveMessages() {
 -   File file = SPIFFS.open("/messages.json", FILE_WRITE);
 -   if (!file) {
 -     Serial.println("无法打开文件进行写入");
 -     return;
 -   }
 -   
 -   // 使用更小的JSON文档
 -   StaticJsonDocument<3072> doc;
 -   JsonArray array = doc.to<JsonArray>();
 -   
 -   // 分批处理
 -   const int batchSize = 5;
 -   int totalBatches = (messageCount + batchSize - 1) / batchSize;
 -   
 -   file.print("[");
 -   
 -   for (int batch = 0; batch < totalBatches; batch++) {
 -     int startIdx = batch * batchSize;
 -     int endIdx = min(startIdx + batchSize, messageCount);
 -     
 -     for (int i = startIdx; i < endIdx; i++) {
 -       JsonObject obj = array.createNestedObject();
 -       obj["author"] = messages[i].author;
 -       obj["content"] = messages[i].content;
 -       obj["timestamp"] = messages[i].timestamp;
 -       
 -       String jsonStr;
 -       serializeJson(obj, jsonStr);
 -       file.print(jsonStr);
 -       
 -       if (i < messageCount - 1) {
 -         file.print(",");
 -       }
 -       
 -       // 清除对象以便下次使用
 -       array.clear();
 -     }
 -     
 -     // 给ESP32一些时间处理
 -     yield();
 -   }
 -   
 -   file.print("]");
 -   file.close();
 -   Serial.println("留言保存完成");
 - }
 - 
 - // 从SPIFFS文件系统加载留言 - 针对ESP32-C5优化
 - void loadMessages() {
 -   if (!SPIFFS.exists("/messages.json")) {
 -     Serial.println("留言文件不存在,将创建新文件");
 -     return;
 -   }
 -   
 -   File file = SPIFFS.open("/messages.json", FILE_READ);
 -   if (!file) {
 -     Serial.println("无法打开文件进行读取");
 -     return;
 -   }
 -   
 -   // 流式解析以减少内存使用
 -   messageCount = 0;
 -   
 -   // 检查文件是否为空或不是有效的JSON
 -   if (file.size() < 2) {
 -     file.close();
 -     return;
 -   }
 -   
 -   // 使用JsonStreamingParser处理大文件
 -   DynamicJsonDocument doc(512);
 -   DeserializationError error;
 -   
 -   // 读取开始括号
 -   char c = file.read();
 -   if (c != '[') {
 -     Serial.println("文件格式错误");
 -     file.close();
 -     return;
 -   }
 -   
 -   // 读取每个留言对象
 -   while (file.available() && messageCount < MAX_MESSAGES) {
 -     // 查找对象的开始
 -     while (file.available() && file.peek() != '{') {
 -       file.read();
 -     }
 -     
 -     if (!file.available()) break;
 -     
 -     // 读取对象
 -     String jsonStr = "";
 -     int braceCount = 0;
 -     bool inString = false;
 -     char prevChar = 0;
 -     
 -     do {
 -       c = file.read();
 -       jsonStr += c;
 -       
 -       if (c == '"' && prevChar != '\\') {
 -         inString = !inString;
 -       }
 -       
 -       if (!inString) {
 -         if (c == '{') braceCount++;
 -         if (c == '}') braceCount--;
 -       }
 -       
 -       prevChar = c;
 -     } while (file.available() && (braceCount > 0 || c != '}'));
 -     
 -     // 解析对象
 -     error = deserializeJson(doc, jsonStr);
 -     
 -     if (!error) {
 -       const char* author = doc["author"];
 -       const char* content = doc["content"];
 -       const char* timestamp = doc["timestamp"];
 -       
 -       if (author && content && timestamp) {
 -         strncpy(messages[messageCount].author, author, sizeof(messages[messageCount].author) - 1);
 -         messages[messageCount].author[sizeof(messages[messageCount].author) - 1] = '\0';
 -         
 -         strncpy(messages[messageCount].content, content, sizeof(messages[messageCount].content) - 1);
 -         messages[messageCount].content[sizeof(messages[messageCount].content) - 1] = '\0';
 -         
 -         strncpy(messages[messageCount].timestamp, timestamp, sizeof(messages[messageCount].timestamp) - 1);
 -         messages[messageCount].timestamp[sizeof(messages[messageCount].timestamp) - 1] = '\0';
 -         
 -         messageCount++;
 -       }
 -     }
 -     
 -     // 清除以便下一个对象
 -     doc.clear();
 -     
 -     // 给ESP32一些时间处理
 -     yield();
 -   }
 -   
 -   file.close();
 -   Serial.println("留言加载完成,共 " + String(messageCount) + " 条");
 - }
 - 
 - // 生成留言板HTML页面
 - String sendMessageBoardHTML() {
 -   String ptr = "<!DOCTYPE html>\n";
 -   ptr += "<html lang='zh'>\n";
 -   ptr += "<head>\n";
 -   ptr += "  <meta charset='UTF-8'>\n";
 -   ptr += "  <meta name='viewport' content='width=device-width, initial-scale=1.0'>\n";
 -   ptr += "  <title>ESP32在线群聊</title>\n";
 -   ptr += "  <style>\n";
 -   ptr += "    body {\n";
 -   ptr += "      font-family: Arial, sans-serif;\n";
 -   ptr += "      max-width: 800px;\n";
 -   ptr += "      margin: 0 auto;\n";
 -   ptr += "      padding: 20px;\n";
 -   ptr += "      background-color: #f5f5f5;\n";
 -   ptr += "    }\n";
 -   ptr += "    h1 {\n";
 -   ptr += "      color: #333;\n";
 -   ptr += "      text-align: center;\n";
 -   ptr += "      margin-bottom: 30px;\n";
 -   ptr += "    }\n";
 -   ptr += "    .message-form {\n";
 -   ptr += "      background-color: white;\n";
 -   ptr += "      padding: 20px;\n";
 -   ptr += "      border-radius: 8px;\n";
 -   ptr += "      box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n";
 -   ptr += "      margin-bottom: 30px;\n";
 -   ptr += "    }\n";
 -   ptr += "    .form-group {\n";
 -   ptr += "      margin-bottom: 15px;\n";
 -   ptr += "    }\n";
 -   ptr += "    label {\n";
 -   ptr += "      display: block;\n";
 -   ptr += "      margin-bottom: 5px;\n";
 -   ptr += "      font-weight: bold;\n";
 -   ptr += "    }\n";
 -   ptr += "    input, textarea {\n";
 -   ptr += "      width: 100%;\n";
 -   ptr += "      padding: 10px;\n";
 -   ptr += "      border: 1px solid #ddd;\n";
 -   ptr += "      border-radius: 4px;\n";
 -   ptr += "      box-sizing: border-box;\n";
 -   ptr += "    }\n";
 -   ptr += "    textarea {\n";
 -   ptr += "      height: 100px;\n";
 -   ptr += "      resize: vertical;\n";
 -   ptr += "    }\n";
 -   ptr += "    button {\n";
 -   ptr += "      background-color: #4CAF50;\n";
 -   ptr += "      color: white;\n";
 -   ptr += "      border: none;\n";
 -   ptr += "      padding: 10px 15px;\n";
 -   ptr += "      border-radius: 4px;\n";
 -   ptr += "      cursor: pointer;\n";
 -   ptr += "      font-size: 16px;\n";
 -   ptr += "    }\n";
 -   ptr += "    button:hover {\n";
 -   ptr += "      background-color: #45a049;\n";
 -   ptr += "    }\n";
 -   ptr += "    .message-list {\n";
 -   ptr += "      background-color: white;\n";
 -   ptr += "      border-radius: 8px;\n";
 -   ptr += "      box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n";
 -   ptr += "      overflow: hidden;\n";
 -   ptr += "    }\n";
 -   ptr += "    .message-item {\n";
 -   ptr += "      padding: 15px 20px;\n";
 -   ptr += "      border-bottom: 1px solid #eee;\n";
 -   ptr += "    }\n";
 -   ptr += "    .message-item:last-child {\n";
 -   ptr += "      border-bottom: none;\n";
 -   ptr += "    }\n";
 -   ptr += "    .message-header {\n";
 -   ptr += "      display: flex;\n";
 -   ptr += "      justify-content: space-between;\n";
 -   ptr += "      margin-bottom: 10px;\n";
 -   ptr += "      font-size: 14px;\n";
 -   ptr += "      color: #666;\n";
 -   ptr += "    }\n";
 -   ptr += "    .message-author {\n";
 -   ptr += "      font-weight: bold;\n";
 -   ptr += "      color: #333;\n";
 -   ptr += "    }\n";
 -   ptr += "    .message-time {\n";
 -   ptr += "      color: #999;\n";
 -   ptr += "    }\n";
 -   ptr += "    .message-content {\n";
 -   ptr += "      line-height: 1.5;\n";
 -   ptr += "    }\n";
 -   ptr += "    .refresh-btn {\n";
 -   ptr += "      background-color: #2196F3;\n";
 -   ptr += "      margin-bottom: 15px;\n";
 -   ptr += "    }\n";
 -   ptr += "    .refresh-btn:hover {\n";
 -   ptr += "      background-color: #0b7dda;\n";
 -   ptr += "    }\n";
 -   ptr += "    .status {\n";
 -   ptr += "      text-align: center;\n";
 -   ptr += "      padding: 10px;\n";
 -   ptr += "      margin-top: 10px;\n";
 -   ptr += "      border-radius: 4px;\n";
 -   ptr += "      display: none;\n";
 -   ptr += "    }\n";
 -   ptr += "    .status.success {\n";
 -   ptr += "      background-color: #dff0d8;\n";
 -   ptr += "      color: #3c763d;\n";
 -   ptr += "    }\n";
 -   ptr += "    .status.error {\n";
 -   ptr += "      background-color: #f2dede;\n";
 -   ptr += "      color: #a94442;\n";
 -   ptr += "    }\n";
 -   ptr += "    @media (max-width: 600px) {\n";
 -   ptr += "      body {\n";
 -   ptr += "        padding: 10px;\n";
 -   ptr += "      }\n";
 -   ptr += "      .message-form, .message-list {\n";
 -   ptr += "        border-radius: 0;\n";
 -   ptr += "      }\n";
 -   ptr += "    }\n";
 -   ptr += "  </style>\n";
 -   ptr += "</head>\n";
 -   ptr += "<body>\n";
 -   ptr += "  <h1>ESP32在线群聊</h1>\n";
 -   
 -   ptr += "  <div class='message-form'>\n";
 -   ptr += "    <div class='form-group'>\n";
 -   ptr += "      <label for='author'>您的名字:</label>\n";
 -   ptr += "      <input type='text' id='author' name='author' required>\n";
 -   ptr += "    </div>\n";
 -   ptr += "    <div class='form-group'>\n";
 -   ptr += "      <label for='content'>群聊内容:</label>\n";
 -   ptr += "      <textarea id='content' name='content' required></textarea>\n";
 -   ptr += "    </div>\n";
 -   ptr += "    <button type='button' id='submit-btn'>发布</button>\n";
 -   ptr += "    <div id='status' class='status'></div>\n";
 -   ptr += "  </div>\n";
 -   
 -   ptr += "  <button type='button' id='refresh-btn' class='refresh-btn'>刷新</button>\n";
 -   
 -   ptr += "  <div id='message-list' class='message-list'>\n";
 -   ptr += "    <div class='message-item' style='text-align:center;color:#999;'>加载中...</div>\n";
 -   ptr += "  </div>\n";
 -   
 -   ptr += "  <script>\n";
 -   ptr += "    // DOM元素\n";
 -   ptr += "    const authorInput = document.getElementById('author');\n";
 -   ptr += "    const contentInput = document.getElementById('content');\n";
 -   ptr += "    const submitBtn = document.getElementById('submit-btn');\n";
 -   ptr += "    const refreshBtn = document.getElementById('refresh-btn');\n";
 -   ptr += "    const messageList = document.getElementById('message-list');\n";
 -   ptr += "    const statusDiv = document.getElementById('status');\n";
 -   
 -   ptr += "    // 保存用户名到本地存储\n";
 -   ptr += "    if (localStorage.getItem('author')) {\n";
 -   ptr += "      authorInput.value = localStorage.getItem('author');\n";
 -   ptr += "    }\n";
 -   
 -   ptr += "    // 加载留言\n";
 -   ptr += "    function loadMessages() {\n";
 -   ptr += "      fetch('/messages')\n";
 -   ptr += "        .then(response => response.json())\n";
 -   ptr += "        .then(data => {\n";
 -   ptr += "          messageList.innerHTML = '';\n";
 -   ptr += "          \n";
 -   ptr += "          if (data.length === 0) {\n";
 -   ptr += "            messageList.innerHTML = '<div class="message-item" style="text-align:center;color:#999;">暂无留言</div>';\n";
 -   ptr += "            return;\n";
 -   ptr += "          }\n";
 -   ptr += "          \n";
 -   ptr += "          // 按时间倒序排列留言\n";
 -   ptr += "          data.reverse().forEach(message => {\n";
 -   ptr += "            const messageItem = document.createElement('div');\n";
 -   ptr += "            messageItem.className = 'message-item';\n";
 -   ptr += "            \n";
 -   ptr += "            const messageHeader = document.createElement('div');\n";
 -   ptr += "            messageHeader.className = 'message-header';\n";
 -   ptr += "            \n";
 -   ptr += "            const messageAuthor = document.createElement('span');\n";
 -   ptr += "            messageAuthor.className = 'message-author';\n";
 -   ptr += "            messageAuthor.textContent = message.author;\n";
 -   ptr += "            \n";
 -   ptr += "            const messageTime = document.createElement('span');\n";
 -   ptr += "            messageTime.className = 'message-time';\n";
 -   ptr += "            messageTime.textContent = message.timestamp;\n";
 -   ptr += "            \n";
 -   ptr += "            messageHeader.appendChild(messageAuthor);\n";
 -   ptr += "            messageHeader.appendChild(messageTime);\n";
 -   ptr += "            \n";
 -   ptr += "            const messageContent = document.createElement('div');\n";
 -   ptr += "            messageContent.className = 'message-content';\n";
 -   ptr += "            messageContent.textContent = message.content;\n";
 -   ptr += "            \n";
 -   ptr += "            messageItem.appendChild(messageHeader);\n";
 -   ptr += "            messageItem.appendChild(messageContent);\n";
 -   ptr += "            \n";
 -   ptr += "            messageList.appendChild(messageItem);\n";
 -   ptr += "          });\n";
 -   ptr += "        })\n";
 -   ptr += "        .catch(error => {\n";
 -   ptr += "          console.error('获取留言失败:', error);\n";
 -   ptr += "          messageList.innerHTML = '<div class="message-item" style="text-align:center;color:#999;">获取留言失败</div>';\n";
 -   ptr += "        });\n";
 -   ptr += "    }\n";
 -   
 -   ptr += "    // 提交新留言\n";
 -   ptr += "    function submitMessage() {\n";
 -   ptr += "      const author = authorInput.value.trim();\n";
 -   ptr += "      const content = contentInput.value.trim();\n";
 -   ptr += "      \n";
 -   ptr += "      if (!author) {\n";
 -   ptr += "        showStatus('请输入您的名字', 'error');\n";
 -   ptr += "        return;\n";
 -   ptr += "      }\n";
 -   ptr += "      \n";
 -   ptr += "      if (!content) {\n";
 -   ptr += "        showStatus('请输入消息内容', 'error');\n";
 -   ptr += "        return;\n";
 -   ptr += "      }\n";
 -   ptr += "      \n";
 -   ptr += "      // 保存用户名到本地存储\n";
 -   ptr += "      localStorage.setItem('author', author);\n";
 -   ptr += "      \n";
 -   ptr += "      // 禁用提交按钮\n";
 -   ptr += "      submitBtn.disabled = true;\n";
 -   ptr += "      \n";
 -   ptr += "      fetch('/post', {\n";
 -   ptr += "        method: 'POST',\n";
 -   ptr += "        headers: {\n";
 -   ptr += "          'Content-Type': 'application/json',\n";
 -   ptr += "        },\n";
 -   ptr += "        body: JSON.stringify({ author, content })\n";
 -   ptr += "      })\n";
 -   ptr += "      .then(response => response.json())\n";
 -   ptr += "      .then(data => {\n";
 -   ptr += "        if (data.status === 'success') {\n";
 -   ptr += "          showStatus('留言发布成功!', 'success');\n";
 -   ptr += "          contentInput.value = '';\n";
 -   ptr += "          loadMessages();\n";
 -   ptr += "        } else {\n";
 -   ptr += "          showStatus('留言发布失败: ' + (data.message || '未知错误'), 'error');\n";
 -   ptr += "        }\n";
 -   ptr += "      })\n";
 -   ptr += "      .catch(error => {\n";
 -   ptr += "        console.error('提交留言失败:', error);\n";
 -   ptr += "        showStatus('提交留言失败,请稍后再试', 'error');\n";
 -   ptr += "      })\n";
 -   ptr += "      .finally(() => {\n";
 -   ptr += "        submitBtn.disabled = false;\n";
 -   ptr += "      });\n";
 -   ptr += "    }\n";
 -   
 -   ptr += "    // 显示状态消息\n";
 -   ptr += "    function showStatus(message, type) {\n";
 -   ptr += "      statusDiv.textContent = message;\n";
 -   ptr += "      statusDiv.className = 'status ' + type;\n";
 -   ptr += "      statusDiv.style.display = 'block';\n";
 -   ptr += "      \n";
 -   ptr += "      setTimeout(() => {\n";
 -   ptr += "        statusDiv.style.display = 'none';\n";
 -   ptr += "      }, 3000);\n";
 -   ptr += "    }\n";
 -   
 -   ptr += "    // 事件***\n";
 -   ptr += "    submitBtn.addEventListener('click', submitMessage);\n";
 -   ptr += "    refreshBtn.addEventListener('click', loadMessages);\n";
 -   ptr += "    \n";
 -   ptr += "    // 回车键提交\n";
 -   ptr += "    contentInput.addEventListener('keypress', function(e) {\n";
 -   ptr += "      if (e.key === 'Enter' && !e.shiftKey) {\n";
 -   ptr += "        e.preventDefault();\n";
 -   ptr += "        submitMessage();\n";
 -   ptr += "      }\n";
 -   ptr += "    });\n";
 -   
 -   ptr += "    // 初始加载留言\n";
 -   ptr += "    loadMessages();\n";
 -   
 -   ptr += "    // 定时刷新留言(每30秒)\n";
 -   ptr += "    setInterval(loadMessages, 30000);\n";
 -   ptr += "  </script>\n";
 -   ptr += "</body>\n";
 -   ptr += "</html>\n";
 -   
 -   return ptr;
 - }
 
  复制代码 具体的arduino的配置可以看我的上一篇内容 
 
 
 |