Рабочий процесс:
- POST в /turns/start с токеном JWT → получение сетки судоку
Код: Выделить всё
POST /turns/start Authorization: Bearer - Решите головоломку локально
- ОТПРАВЬТЕ решение каждой ячейки в /turns/submit → сервер отвечает {"correct":true,"status":"next" или {"correct":true,"status":"completed","time":470
Код: Выделить всё
POST /turns/submit Authorization: Bearer Content-Type: application/json {"answer":{"row":x,"col":y,"value":z}} - Повторять бесконечно
Сейчас я использую простой интерфейс Curl + pthreads, один поток на отправку.
Это работает. Однако я наблюдаю странное поведение, когда ячейки, кажется, не сохраняются между rounds:
Пример: в первом судоку 24 пустые ячейки → я отправляю 24 запроса
но на следующей итерации сервер снова выдает мне ту же доску, но теперь с меньшим количеством пустых ячеек (например, 18).
Похоже, что сервер не принял некоторые отправленные данные, хотя во всех ответах, которые я читаю, говорится: «правильно»: true, «статус»: "следующий", и я могу это подтвердить, потому что серверы дают баллы только за решенное судоку и дают 20-30 пустых ячеек для отправки, а мои баллы не пропорциональны количеству итераций.
Вот код:
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
#include
struct Response
{
char data[4096];
size_t size;
};
struct Cell{
int row;
int col;
int value;
};
struct Thread_data{
pthread_t thread;
CURL* handle;
struct Response received_data;
struct Cell cell;
};
CURL *main_handle;
struct Response receive_board;
int sudoku[9][9];
///////////////////////////////////////////////////////////////////////
// Check if a number can be placed at a given position
bool is_valid(int sudoku[9][9], int row, int col, int num) {
// Check the row
for (int i = 0; i < 9; i++) {
if (sudoku[row][i] == num) {
return false;
}
}
// Check the column
for (int i = 0; i < 9; i++) {
if (sudoku[i][col] == num) {
return false;
}
}
// Check the 3x3 box
int start_row = (row / 3) * 3;
int start_col = (col / 3) * 3;
for (int i = start_row; i < start_row + 3; i++) {
for (int j = start_col; j < start_col + 3; j++) {
if (sudoku[i][j] == num) {
return false;
}
}
}
return true;
}
// Recursive function to solve the sudoku (backtracking)
bool solve_recursive(int sudoku[9][9]) {
// Find an empty cell (represented by 0)
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
if (sudoku[row][col] == 0) {
// Try digits from 1 to 9
for (int num = 1; num received_data.size = 0;
char post_data[50];
snprintf(post_data, 50, "{\"answer\":{\"row\":%d,\"col\":%d,\"value\":%d}}", thread->cell.row, thread->cell.col, thread->cell.value);
curl_easy_setopt(thread->handle, CURLOPT_POSTFIELDS, post_data);
curl_easy_perform(thread->handle);
}
int main()
{
struct curl_slist *list = NULL;
struct Thread_data threads[32];
curl_global_init(CURL_GLOBAL_DEFAULT);
main_handle = curl_easy_init();
list = curl_slist_append(list, "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwaG9uZU51bWJlciI6IjY0MjMyMDMwIiwiYm9vc3RUaW1lcyI6MCwiY3JlYXRlZEF0IjoiMjAyNS0wNy0wMlQxNDo1MjoxOC45MzJaIiwiaXNTdWJzY3JpYmUiOnRydWUsImlzU3Vic2NyaWJlSW5EYXkiOmZhbHNlLCJtb250aFNjb3JlIjowLCJuYW1lIjoiU29waGlhMjM0IiwicGxheVRpbWVzIjowLCJzdWJzY3JpYmVGcm9tIjoid2ViIiwidG9kYXlTY29yZSI6MCwidXBkYXRlZEF0IjoiMjAyNS0wNy0wMlQxNDo1MjoxOC45MzJaIiwid2luRGF5IjowLCJ3aW5Nb250aCI6IjAiLCJ3aW5XZWVrIjowLCJmYXN0ZXN0RHVyYXRpb24iOjIxNywiaWF0IjoxNzYzNDE3MjM3LCJleHAiOjE3NjYwMDkyMzd9.pxfbyCrr3lgU-rQN_NWv5zqUinsBX8BoCo8vIzj_euU");
curl_easy_setopt(main_handle, CURLOPT_URL, "https://sudoku.lumitelburundi.com:8083/turns/start");
curl_easy_setopt(main_handle, CURLOPT_POST, 1L);
curl_easy_setopt(main_handle, CURLOPT_POSTFIELDS, "");
curl_easy_setopt(main_handle, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(main_handle, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(main_handle, CURLOPT_WRITEDATA, &receive_board);
list = curl_slist_append(list, "Content-Type: application/json"); // adding this header for submitting in json
for(int i = 0; i < 32; i++)
{
threads[i].handle = curl_easy_init();
curl_easy_setopt(threads[i].handle, CURLOPT_URL, "https://sudoku.lumitelburundi.com:8083/turns/submit");
curl_easy_setopt(threads[i].handle, CURLOPT_POST, 1L);
curl_easy_setopt(threads[i].handle, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(threads[i].handle, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(threads[i].handle, CURLOPT_WRITEDATA, &threads[i].received_data);
}
while(1)
{
if(get_board() != 0)
{
fprintf(stderr, "Error while fetching the board\n");
return -1;
}
int solved_sudoku[9][9];
memcpy(solved_sudoku, sudoku, sizeof(int) * 81);
if(solve_sudoku(solved_sudoku) != 0)
{
fprintf(stderr, "Error while fetching the board\n");
return -1;
}
int thread_count = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if(sudoku[i][j] == 0)
{
threads[thread_count].cell.row = i;
threads[thread_count].cell.col = j;
threads[thread_count].cell.value = solved_sudoku[i][j];
pthread_create(&threads[thread_count].thread, NULL, submit_threaded, &threads[thread_count]);
thread_count++;
}
}
}
for(int i = 0; i < thread_count; i++)
{
pthread_join(threads[i].thread, NULL); // wait for every thread to finish
//printf("sent: %s\n", threads[i].received_data.data);
}
printf("\033[31mSolved cell submitted: %d\033[0m\n", thread_count);
}
curl_global_cleanup();
return 0;
}
Код: Выделить всё
Solved cell submitted: 23
Solved cell submitted: 8
Solved cell submitted: 3
Solved cell submitted: 1
Solved cell submitted: 27
Solved cell submitted: 17
Solved cell submitted: 9
Solved cell submitted: 3
Solved cell submitted: 28
Solved cell submitted: 16
Solved cell submitted: 12
Solved cell submitted: 7
Solved cell submitted: 4
Solved cell submitted: 1
Solved cell submitted: 29
Solved cell submitted: 14
Solved cell submitted: 7
Solved cell submitted: 2
Solved cell submitted: 1
Solved cell submitted: 22
Solved cell submitted: 19
Solved cell submitted: 12
Solved cell submitted: 5
Solved cell submitted: 2
Solved cell submitted: 1
Solved cell submitted: 24
Solved cell submitted: 18
Solved cell submitted: 11
Solved cell submitted: 4
Solved cell submitted: 1
Решит ли это создание нескольких учетных записей пользователей (таким образом, несколько токенов JWT) и распределение моих потоков между ними? Или есть лучший подход для обработки высокочастотных одновременных отправок с аутентификацией JWT?
Если нет, то каков правильный способ максимизировать пропускную способность запросов на C (или любом другом языке) для такого рода задач?
Вот заголовок сервера, если это поможет:
Код: Выделить всё
HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Keep-Alive: timeout=5
Его значение выглядит примерно так: rs1|aSBDB, но оно меняется при каждой перезагрузке и не включается ни в один из запросов, сделанных клиентом.
>
Подробнее здесь: https://stackoverflow.com/questions/798 ... sessions-f
Мобильная версия