Почему мое сообщение не отображается на странице, хотя журнал сервера показывает, что оно было успешно отправлено в CiveC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Почему мое сообщение не отображается на странице, хотя журнал сервера показывает, что оно было успешно отправлено в Cive

Сообщение Anonymous »

Я создаю функцию локального веб-чата, используя CivetWeb (C++), SQLite и интерфейс на простом HTML/JS.
При отправке сообщения в журнале сервера отображается следующее:

Код: Выделить всё

Attempting to send message: product_id=3, sender=1, receiver=Admin, message=1
Таким образом, конечная точка /send_message срабатывает правильно.
Однако новое сообщение не появляется на странице чата (

Код: Выделить всё

message_feature.html
), хотя я вижу, что оно было вставлено в журнал.
Вот что у меня есть:

Фронтенд (message_feature.html)

Код: Выделить всё

async function loadConversation() {
const res = await fetch(`/api/conversation?product_id=${productId}`);
if (!res.ok) return;
const msgs = await res.json();
const box = document.getElementById('messages');
box.innerHTML = '';
msgs.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
msgs.forEach(m => {
const div = document.createElement('div');
div.className = 'msg ' + (m.sender === 'Admin' ? 'received' : 'sent');
div.innerHTML = `${m.message}`;
box.appendChild(div);
});
}

Бэкенд (C++ с CivetWeb)

Код: Выделить всё

// POST /send_message
mg_set_request_handler(ctx, "/send_message", [](mg_connection *conn, void *) -> int {
if (strcmp(mg_get_request_info(conn)->request_method, "POST") != 0)
return 405;

const struct mg_request_info *ri = mg_get_request_info(conn);
int len = (int)ri->content_length;
if (len  4096) len = 4096;
std::vector post_data(len + 1);
int n = mg_read(conn, post_data.data(), len);
post_data[n] = '\0';

char product_id_str[32] = {0}, sender[128] = {0}, receiver[128] = {0}, message[1024] = {0};
mg_get_var(post_data.data(), n, "product_id", product_id_str, sizeof(product_id_str));
mg_get_var(post_data.data(), n, "sender", sender, sizeof(sender));
mg_get_var(post_data.data(), n, "receiver", receiver, sizeof(receiver));
mg_get_var(post_data.data(), n, "message", message, sizeof(message));

fprintf(stderr, "Attempting to send message: product_id=%s, sender=%s, receiver=%s, message=%s\n",
product_id_str, sender, receiver, message);

sqlite3 *db = safe_open("C:/Users/priva/OneDrive/Desktop/supplierbuyer/products.db");
const char *sql = "INSERT INTO messages (product_id, sender, receiver, message) VALUES (?, ?, ?, ?);";
sqlite3_stmt *stmt = nullptr;
sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
sqlite3_bind_int(stmt, 1, atoi(product_id_str));
sqlite3_bind_text(stmt, 2, sender, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 3, receiver, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 4, message, -1, SQLITE_TRANSIENT);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
sqlite3_close(db);

mg_printf(conn, "HTTP/1.1 201 Created\r\nContent-Length: 0\r\n\r\n");
return 201;
}, nullptr);

// GET /api/conversation
mg_set_request_handler(ctx, "/api/conversation", [](mg_connection *conn, void *) ->  int {
const mg_request_info *ri = mg_get_request_info(conn);
char product_id_str[32] = {0};
if (ri->query_string)
mg_get_var(ri->query_string, strlen(ri->query_string), "product_id", product_id_str, sizeof(product_id_str));
int product_id = atoi(product_id_str);

sqlite3 *db = safe_open("C:/Users/priva/OneDrive/Desktop/supplierbuyer/products.db");
const char *sql = R"(
SELECT sender, receiver, message, strftime('%Y-%m-%d %H:%M:%S', created_at)
FROM messages WHERE product_id = ? ORDER BY id ASC;
)";
sqlite3_stmt *stmt = nullptr;
sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
sqlite3_bind_int(stmt, 1, product_id);

std::string json = "[";
bool first = true;
while (sqlite3_step(stmt) == SQLITE_ROW) {
if (!first) json += ",";
first = false;
const char *sender = (const char *)sqlite3_column_text(stmt, 0);
const char *receiver = (const char *)sqlite3_column_text(stmt, 1);
const char *message = (const char *)sqlite3_column_text(stmt, 2);
const char *created_at = (const char *)sqlite3_column_text(stmt, 3);
char buf[512];
snprintf(buf, sizeof(buf),
R"({"sender":"%s","receiver":"%s","message":"%s","created_at":"%s"})",
sender, receiver, message, created_at);
json += buf;
}
json += "]";
sqlite3_finalize(stmt);
sqlite3_close(db);

mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n%s", json.c_str());
return 200;
}, nullptr);

Сообщения сохраняются в том же файле Products.db в таблице messages.
Я также проверил, что loadConversation() запускается после отправки сообщения, но в окне чата ничего не отображается.
Вот соответствующая часть моего кода message_feature.html:

Код: Выделить всё

document.getElementById('chatForm').addEventListener('submit', async e => {
e.preventDefault();

const fd = new FormData(e.target);
const userRes = await fetch('/api/get_current_user');
const { username } = await userRes.json();
fd.append('sender', username);

const body = new URLSearchParams(fd);

// Send the message to the backend
const res = await fetch('/send_message', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body
});

// I wait for the response before refreshing messages
if (res.ok) {
document.getElementById('message').value = '';
loadConversation();   // ✅ Called right after successful response
} else {
alert('Failed to send message.');
}
});
Поэтому loadConversation() вызывается только после успешного возврата запроса POST (статус 201).
Однако даже в этом случае окно чата не обновляется — оно по-прежнему не показывает сообщений, хотя /send_message регистрирует вставку на сервере.
Я также попробовал добавить небольшую задержку перед вызовом loadConversation() (используя setTimeout(loadConversation, 1000)), но это не имело значения — сообщения по-прежнему не отображаются.

Вопрос:
Даже несмотря на то, что сообщения вставлены (в журнале показано, что они отправлены), они не появляются при получении из /api/conversation.
Что может вызвать интерфейс не отображает их — проблема с запросом, ответом JSON или рендерингом DOM?

Что я пробовал
  • Я проверил, что конечная точка /send_message работает — она регистрируется

    Код: Выделить всё

    Attempting to send message: product_id=3, sender=1, receiver=Admin, message=1
    
    каждый раз, когда я нажимаю Отправить.
  • Я проверил, что сообщение вставлено в базу данных SQLite (

    Код: Выделить всё

    messages
    таблица) вручную с помощью браузера БД.
  • Я подтвердил, что /api/conversation?product_id=3 возвращает массив JSON, но иногда он пустой или отсутствует новое сообщение.
  • Я также добавил console.log(msgs) внутри loadConversation() в message_feature.html — в консоли отображается пустой массив [], хотя сообщение существует в БД.
  • Я пробовал вызывать loadConversation() сразу после отправки (и тоже с 3-секундным интервалом), но окно чата по-прежнему не обновляется.
Чего я ожидал
Я ожидал, что после отправки сообщения новое сообщение:
  • Будет вставлено в таблицу сообщений.
  • Появится сразу же в окно чата под правильной стороной ( или получено).
  • Также отображается в представлении администратора (

    Код: Выделить всё

    messageadmin.html
    ) через несколько секунд (поскольку он обновляется автоматически).


Подробнее здесь: https://stackoverflow.com/questions/797 ... shows-it-w
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»