static void spawn_handling_thread(struct ns_connection *nc) { struct ns_mgr dummy = {}; sock_t sp[2]; struct ns_connection *c[2]; /* * Create a socket pair, and wrap each socket into the connection with * dummy event manager. * c[0] stays in this thread, c[1] goes to another thread. */ ns_socketpair(sp, SOCK_STREAM); c[0] = ns_add_sock(&dummy, sp[0], forwarder_ev_handler); c[1] = ns_add_sock(&dummy, sp[1], nc->listener->priv_1); /* Interlink client connection with c[0] */ link_conns(c[0], nc); /* * Switch c[0] manager from the dummy one to the real one. c[1] manager * will be set in another thread, allocated on stack of that thread. */ ns_add_conn(nc->mgr, c[0]); /* * Dress c[1] as nc. * TODO(lsm): code in accept_conn() looks similar. Refactor. */ c[1]->listener = nc->listener; c[1]->proto_handler = nc->proto_handler; c[1]->proto_data = nc->proto_data; c[1]->user_data = nc->user_data; ns_start_thread(per_connection_thread_function, c[1]); }
void sj_prompt_init_hal() { int fds[2]; if (!ns_socketpair(fds, SOCK_STREAM)) { printf("cannot create a socketpair\n"); exit(1); } ns_start_thread(stdin_thread, (void *) (uintptr_t) fds[1]); ns_add_sock(&sj_mgr, fds[0], prompt_handler); }
static const char *test_thread(void) { struct ns_mgr mgr; struct ns_connection *nc; sock_t sp[2]; char buf[20]; ASSERT(ns_socketpair(sp) == 1); ns_start_thread(thread_func, &sp[1]); ns_mgr_init(&mgr, NULL); ASSERT((nc = ns_add_sock(&mgr, sp[0], eh2)) != NULL); nc->user_data = buf; poll_mgr(&mgr, 50); ASSERT(strcmp(buf, ":-)") == 0); ns_mgr_free(&mgr); closesocket(sp[1]); return NULL; }
int main(int argc, char *argv[]) { struct ns_mgr mgr; if (argc != 3) { fprintf(stderr, "Usage: %s <port> <client|server>\n", argv[0]); exit(EXIT_FAILURE); } else if (strcmp(argv[2], "client") == 0) { int fds[2]; struct ns_connection *ioconn, *server_conn; ns_mgr_init(&mgr, NULL, client_handler); // Connect to the pubsub server server_conn = ns_connect(&mgr, argv[1], NULL); if (server_conn == NULL) { fprintf(stderr, "Cannot connect to port %s\n", argv[1]); exit(EXIT_FAILURE); } // Create a socketpair and give one end to the thread that reads stdin ns_socketpair(fds); ns_start_thread(stdin_thread, &fds[1]); // The other end of a pair goes inside the server ioconn = ns_add_sock(&mgr, fds[0], NULL); ioconn->flags |= NSF_USER_1; // Mark this so we know this is a stdin ioconn->user_data = server_conn; } else { // Server code path ns_mgr_init(&mgr, NULL, server_handler); ns_bind(&mgr, argv[1], NULL); printf("Starting pubsub server on port %s\n", argv[1]); } for (;;) { ns_mgr_poll(&mgr, 1000); } ns_mgr_free(&mgr); return EXIT_SUCCESS; }
int main(void) { struct mg_server *proxy_server = mg_create_server(NULL, ev_handler); struct mg_server *ws1_server = mg_create_server(NULL, ws_handler); struct mg_server *ws2_server = mg_create_server(NULL, ws_handler); size_t i; // Configure proxy server to listen on port 2014 mg_set_option(proxy_server, "listening_port", "2014"); //mg_set_option(proxy_server, "enable_proxy", "yes"); // Configure two websocket echo servers: // ws1 is WS, listening on 9001 // ws2 is WSS, listening on 9002 // Note that HTML page thinks that ws1 is WSS, and ws2 is WS, // where in reality it is vice versa and proxy server makes the decision. mg_set_option(ws1_server, "listening_port", "9001"); mg_set_option(ws2_server, "listening_port", "9002"); mg_set_option(ws2_server, "ssl_certificate", "certs/ws2_server.pem"); // Setup signal handlers signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); // Start SSL wrappers, each in it's own thread for (i = 0; i < ARRAY_SIZE(s_wrappers); i++) { ns_start_thread(wrapper_thread_func, &s_wrappers[i]); } // Start websocket servers in separate threads mg_start_thread(serve_thread_func, ws1_server); mg_start_thread(serve_thread_func, ws2_server); // Finally, start proxy server in this thread: this call blocks serve_thread_func(proxy_server); printf("Existing on signal %d\n", s_received_signal); return EXIT_SUCCESS; }