Files

143 lines
4.7 KiB
C

/*
* test_ws_raw.c — Minimal raw WebSocket test using nostr_core_lib.
* Directly calls nostr_ws_connect + nostr_ws_receive to bypass
* synchronous_query_relays_with_progress and see exactly what the
* WebSocket client returns.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "nostr_websocket_tls.h"
#include "cjson/cJSON.h"
int main(int argc, char* argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s <relay_url> <pubkey_hex> [limit]\n", argv[0]);
return 1;
}
const char* relay_url = argv[1];
const char* pubkey = argv[2];
int limit = (argc >= 4) ? atoi(argv[3]) : 10;
printf("Connecting to %s ...\n", relay_url);
fflush(stdout);
nostr_ws_client_t* ws = nostr_ws_connect(relay_url);
if (!ws) {
printf("FAILED to connect\n");
return 1;
}
printf("Connected!\n");
fflush(stdout);
/* Build REQ message */
cJSON* filter = cJSON_CreateObject();
cJSON* authors = cJSON_CreateArray();
cJSON_AddItemToArray(authors, cJSON_CreateString(pubkey));
cJSON_AddItemToObject(filter, "authors", authors);
cJSON* kinds = cJSON_CreateArray();
int kind_list[] = {0, 1, 3, 6, 10000, 10002, 30023};
for (int i = 0; i < 7; i++) {
cJSON_AddItemToArray(kinds, cJSON_CreateNumber((double)kind_list[i]));
}
cJSON_AddItemToObject(filter, "kinds", kinds);
cJSON_AddItemToObject(filter, "limit", cJSON_CreateNumber((double)limit));
long now = (long)time(NULL);
cJSON_AddItemToObject(filter, "until", cJSON_CreateNumber((double)now));
cJSON* req = cJSON_CreateArray();
cJSON_AddItemToArray(req, cJSON_CreateString("REQ"));
cJSON_AddItemToArray(req, cJSON_CreateString("test_raw"));
cJSON_AddItemToArray(req, filter);
char* req_str = cJSON_PrintUnformatted(req);
printf("Sending REQ: %.200s...\n", req_str);
fflush(stdout);
int send_ret = nostr_ws_send_text(ws, req_str);
printf("send_text returned: %d\n", send_ret);
fflush(stdout);
free(req_str);
cJSON_Delete(req);
/* Receive loop */
char buffer[262144];
int event_count = 0;
int eose_received = 0;
time_t start = time(NULL);
printf("\n--- Receiving messages ---\n");
fflush(stdout);
while (1) {
double elapsed = difftime(time(NULL), start);
if (elapsed > 35) {
printf("[%.0fs] *** 35s total timeout reached ***\n", elapsed);
break;
}
printf("[%.0fs] calling nostr_ws_receive (timeout=2000ms)...\n", elapsed);
fflush(stdout);
int len = nostr_ws_receive(ws, buffer, sizeof(buffer) - 1, 2000);
elapsed = difftime(time(NULL), start);
if (len < 0) {
printf("[%.0fs] nostr_ws_receive returned %d (error/timeout)\n", elapsed, len);
fflush(stdout);
/* Keep trying — the relay might send data later */
continue;
}
if (len == 0) {
printf("[%.0fs] nostr_ws_receive returned 0 (connection closed)\n", elapsed);
break;
}
buffer[len] = '\0';
printf("[%.0fs] received %d bytes: %.200s\n", elapsed, len, buffer);
fflush(stdout);
/* Parse the message */
cJSON* msg = cJSON_Parse(buffer);
if (msg && cJSON_IsArray(msg)) {
cJSON* type = cJSON_GetArrayItem(msg, 0);
if (type && cJSON_IsString(type)) {
if (strcmp(type->valuestring, "EVENT") == 0) {
event_count++;
if (event_count % 50 == 0) {
printf(" >>> %d events so far\n", event_count);
}
} else if (strcmp(type->valuestring, "EOSE") == 0) {
eose_received = 1;
printf(" >>> EOSE received! total events=%d\n", event_count);
break;
} else if (strcmp(type->valuestring, "NOTICE") == 0) {
cJSON* notice = cJSON_GetArrayItem(msg, 1);
printf(" >>> NOTICE: %s\n", notice ? notice->valuestring : "?");
} else if (strcmp(type->valuestring, "CLOSED") == 0) {
printf(" >>> CLOSED\n");
break;
} else if (strcmp(type->valuestring, "AUTH") == 0) {
printf(" >>> AUTH challenge received\n");
}
}
}
if (msg) cJSON_Delete(msg);
}
printf("\n=== RESULTS ===\n");
printf("Events: %d\n", event_count);
printf("EOSE: %s\n", eose_received ? "YES" : "NO");
printf("Elapsed: %.0fs\n", difftime(time(NULL), start));
nostr_ws_close(ws);
return eose_received ? 0 : 1;
}