void WebSocket::onSubThreadStarted() { std::lock_guard<std::mutex> lk(_websocketsMutex); struct lws_context_creation_info info; memset(&info, 0, sizeof info); /* * create the websocket context. This tracks open connections and * knows how to route any traffic and which protocol version to use, * and if each connection is client or server side. * * For this client-only demo, we tell it to not listen on any port. */ info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = _wsProtocols; #ifndef LWS_NO_EXTENSIONS info.extensions = libwebsocket_get_internal_extensions(); #endif info.gid = -1; info.uid = -1; info.user = (void*)this; _wsContext = libwebsocket_create_context(&info); if(nullptr != _wsContext) { _readyState = State::kStateConnecting; std::string name; for (int i = 0; _wsProtocols[i].callback != nullptr; ++i) { name += (_wsProtocols[i].name); if (_wsProtocols[i+1].callback != nullptr) name += ", "; } _wsInstance = libwebsocket_client_connect(_wsContext, _host.c_str(), _port, _SSLConnection, _path.c_str(), _host.c_str(), _host.c_str(), name.c_str(), -1); if(NULL == _wsInstance) { WsMessage* msg = new WsMessage(); msg->what = WS_MSG_TO_UITHREAD_ERROR; _readyState = State::kStateClosing; _wsHelper->sendMessageToUIThread(msg); } } }
void WebSocketSource::setConfiguration(map<string, string> config) { //printf("WebSocketSource::setConfiguration has been called\n"); std::string ip; int port; configuration = config; if(config.find("binaryProtocol") != config.end()) { doBinary = config["binaryProtocol"] == "true"; } for (map<string,string>::iterator i=configuration.begin();i!=configuration.end();i++) { DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Incoming setting for WebSocketSource:" << (*i).first << ":" << (*i).second << "\n"; //printf("Incoming setting: %s:%s\n",(*i).first.c_str(),(*i).second.c_str()); if ((*i).first == "ip") { ip = (*i).second; } if ((*i).first == "port") { port = boost::lexical_cast<int>((*i).second); } if ((*i).first == "ssl") { if ((*i).second == "true") { m_sslEnabled = true; } else { m_sslEnabled = false; } } } //printf("Connecting to websocket server at %s port %i\n",ip.c_str(),port); DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Connecting to websocket server at" << ip << ":" << port << "\n"; int sslval = 0; if (m_sslEnabled) { DebugOut(5) << "SSL ENABLED" << endl; sslval = 2; } clientsocket = libwebsocket_client_connect(context, ip.c_str(), port, sslval,"/", "localhost", "websocket", protocols[0].name, -1); }
static std::unique_ptr<Connection> createConnection(const netadr_t &to) { assert(wsState); char addrBuf[3 * 4 + 5]; snprintf(addrBuf, sizeof(addrBuf), "%u.%u.%u.%u", to.ip[0], to.ip[1], to.ip[2], to.ip[3]); struct libwebsocket *newWsi = libwebsocket_client_connect(wsState->websocketContext, addrBuf, ntohs(to.port), 0, "/", addrBuf, addrBuf, "quake2", -1); if (newWsi == NULL) { STUBBED("TODO: log connection create failure"); return std::unique_ptr<Connection>(); } libwebsocket_callback_on_writable(wsState->websocketContext, newWsi); STUBBED("TODO: unnecessary(?) libwebsocket_service"); libwebsocket_service(wsState->websocketContext, 0); std::unique_ptr<Connection> conn(new Connection(to, newWsi)); wsState->wsiLookup.emplace(newWsi, conn.get()); return conn; }
void WebSocket::onSubThreadStarted() { struct lws_context_creation_info info; memset(&info, 0, sizeof info); /* * create the websocket context. This tracks open connections and * knows how to route any traffic and which protocol version to use, * and if each connection is client or server side. * * For this client-only demo, we tell it to not listen on any port. */ info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = _wsProtocols; #ifndef LWS_NO_EXTENSIONS info.extensions = libwebsocket_get_internal_extensions(); #endif info.gid = -1; info.uid = -1; info.user = (void*)this; _wsContext = libwebsocket_create_context(&info); if(NULL != _wsContext){ _readyState = kStateConnecting; std::string name; for (int i = 0; _wsProtocols[i].callback != NULL; ++i) { name += (_wsProtocols[i].name); if (_wsProtocols[i+1].callback != NULL) { name += ", "; } } _wsInstance = libwebsocket_client_connect(_wsContext, _host.c_str(), _port, _SSLConnection, _path.c_str(), _host.c_str(), _host.c_str(), name.c_str(), -1); } }
LWS_VISIBLE struct libwebsocket * libwebsocket_client_connect_extended(struct libwebsocket_context *context, const char *address, int port, int ssl_connection, const char *path, const char *host, const char *origin, const char *protocol, int ietf_version_or_minus_one, void *userdata) { struct libwebsocket *ws = libwebsocket_client_connect(context, address, port, ssl_connection, path, host, origin, protocol, ietf_version_or_minus_one); if (ws && !ws->user_space && userdata) ws->user_space = userdata ; return ws ; }
int main(int argc, char **argv) { int n = 0; int ret = 0; // int port = 8543; int port = 9000; int use_ssl = 0; struct libwebsocket_context *context; // const char *address="192.168.6.176"; const char *address="192.168.6.114"; struct libwebsocket *wsi_dumb; int ietf_version = -1; /* latest */ struct lws_context_creation_info info; memset(&info, 0, sizeof info); fprintf(stderr, "DTS2B websockets client\n" "(C) Copyright 2014-2015 Mleaf_HEXI <*****@*****.**> " "licensed under LGPL2.1\n"); /* * create the websockets context. This tracks open connections and * knows how to route any traffic and which protocol version to use, * and if each connection is client or server side. * * For this client-only demo, we tell it to not listen on any port. */ info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS info.extensions = libwebsocket_get_internal_extensions(); #endif info.gid = -1; info.uid = -1; context = libwebsocket_create_context(&info); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); return 1; } /* create a client websocket using dumb increment protocol */ /* TITLE: libwebsocket_client_connect - Connect to another websocket server struct libwebsocket * libwebsocket_client_connect (struct libwebsocket_context * context, const char * address, int port, int ssl_connection, const char * path, const char * host, const char * origin, const char * protocol, int ietf_version_or_minus_one) Arguments context Websocket context address Remote server address, eg, "myserver.com" port Port to connect to on the remote server, eg, 80 ssl_connection 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self signed certs path Websocket path on server host Hostname on server origin Socket origin name protocol Comma-separated list of protocols being asked for from the server, or just one. The server will pick the one it likes best. ietf_version_or_minus_one -1 to ask to connect using the default, latest protocol supported, or the specific protocol ordinal Description This function creates a connection to a remote server */ fprintf(stderr, "Connecting to %s:%u\n", address, port); wsi_dumb = libwebsocket_client_connect(context, address, port, use_ssl, "/websocket/uclient/MOCK_DTS2B_ACCESS_CODE_1234567890", address,"origin", protocols[0].name, ietf_version); if (wsi_dumb == NULL) { fprintf(stderr, "libwebsocket connect failed\n"); ret = 1; goto bail; } fprintf(stderr, "Waiting for connect...\n"); sqlite3_test();//sqlite3数据库测试 /* * sit there servicing the websocket context to handle incoming * packets, and drawing random circles on the mirror protocol websocket * nothing happens until the client websocket connection is * asynchronously established */ n = 0; while (n >= 0 && !was_closed && !force_exit) { n = libwebsocket_service(context, 10); if (n < 0) continue; if (wsi_mirror) continue; } bail: fprintf(stderr, "Exiting\n"); libwebsocket_context_destroy(context); return 1; }
int main(int argc, char **argv) { int n = 0; int port = 7681; int use_ssl = 0; struct libwebsocket_context *context; int opts = 0; char interface_name[128] = ""; const char *_interface = NULL; char ssl_cert[256] = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem"; char ssl_key[256] = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem"; #ifndef _WIN32 int syslog_options = LOG_PID | LOG_PERROR; #endif int client = 0; int listen_port = 80; struct lws_context_creation_info info; char passphrase[256]; char uri[256] = "/"; #ifndef LWS_NO_CLIENT char address[256], ads_port[256 + 30]; int rate_us = 250000; unsigned int oldus = 0; struct libwebsocket *wsi; int disallow_selfsigned = 0; #endif int debug_level = 7; #ifndef LWS_NO_DAEMONIZE int daemonize = 0; #endif memset(&info, 0, sizeof info); #ifndef LWS_NO_CLIENT lwsl_notice("Built to support client operations\n"); #endif #ifndef LWS_NO_SERVER lwsl_notice("Built to support server operations\n"); #endif while (n >= 0) { n = getopt_long(argc, argv, "i:hsp:d:DC:k:P:vu:" #ifndef LWS_NO_CLIENT "c:r:" #endif , options, NULL); if (n < 0) continue; switch (n) { case 'P': strncpy(passphrase, optarg, sizeof(passphrase)); passphrase[sizeof(passphrase) - 1] = '\0'; info.ssl_private_key_password = passphrase; break; case 'C': strncpy(ssl_cert, optarg, sizeof(ssl_cert)); ssl_cert[sizeof(ssl_cert) - 1] = '\0'; disallow_selfsigned = 1; break; case 'k': strncpy(ssl_key, optarg, sizeof(ssl_key)); ssl_key[sizeof(ssl_key) - 1] = '\0'; break; case 'u': strncpy(uri, optarg, sizeof(uri)); uri[sizeof(uri) - 1] = '\0'; break; #ifndef LWS_NO_DAEMONIZE case 'D': daemonize = 1; #ifndef _WIN32 syslog_options &= ~LOG_PERROR; #endif break; #endif #ifndef LWS_NO_CLIENT case 'c': client = 1; strncpy(address, optarg, sizeof(address) - 1); address[sizeof(address) - 1] = '\0'; port = 80; break; case 'r': rate_us = atoi(optarg) * 1000; break; #endif case 'd': debug_level = atoi(optarg); break; case 's': use_ssl = 1; /* 1 = take care about cert verification, 2 = allow anything */ break; case 'p': port = atoi(optarg); break; case 'v': versa = 1; break; case 'i': strncpy(interface_name, optarg, sizeof interface_name); interface_name[(sizeof interface_name) - 1] = '\0'; _interface = interface_name; break; case '?': case 'h': fprintf(stderr, "Usage: libwebsockets-test-echo\n" " --debug / -d <debug bitfield>\n" " --port / -p <port>\n" " --ssl-cert / -C <cert path>\n" " --ssl-key / -k <key path>\n" #ifndef LWS_NO_CLIENT " --client / -c <server IP>\n" " --ratems / -r <rate in ms>\n" #endif " --ssl / -s\n" " --passphrase / -P <passphrase>\n" " --interface / -i <interface>\n" #ifndef LWS_NO_DAEMONIZE " --daemonize / -D\n" #endif ); exit(1); } } #ifndef LWS_NO_DAEMONIZE /* * normally lock path would be /var/lock/lwsts or similar, to * simplify getting started without having to take care about * permissions or running as root, set to /tmp/.lwsts-lock */ #if defined(WIN32) || defined(_WIN32) #else if (!client && daemonize && lws_daemonize("/tmp/.lwstecho-lock")) { fprintf(stderr, "Failed to daemonize\n"); return 1; } #endif #endif #ifndef _WIN32 /* we will only try to log things according to our debug_level */ setlogmask(LOG_UPTO (LOG_DEBUG)); openlog("lwsts", syslog_options, LOG_DAEMON); #endif /* tell the library what debug level to emit and to send it to syslog */ lws_set_log_level(debug_level, lwsl_emit_syslog); lwsl_notice("libwebsockets echo test - " "(C) Copyright 2010-2015 Andy Green <*****@*****.**> - " "licensed under LGPL2.1\n"); #ifndef LWS_NO_CLIENT if (client) { lwsl_notice("Running in client mode\n"); listen_port = CONTEXT_PORT_NO_LISTEN; if (use_ssl && !disallow_selfsigned) { lwsl_info("allowing selfsigned\n"); use_ssl = 2; } else { lwsl_info("requiring server cert validation againts %s\n", ssl_cert); info.ssl_ca_filepath = ssl_cert; } } else { #endif #ifndef LWS_NO_SERVER lwsl_notice("Running in server mode\n"); listen_port = port; #endif #ifndef LWS_NO_CLIENT } #endif info.port = listen_port; info.iface = _interface; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS info.extensions = libwebsocket_get_internal_extensions(); #endif if (use_ssl && !client) { info.ssl_cert_filepath = ssl_cert; info.ssl_private_key_filepath = ssl_key; } else if (use_ssl && client) { info.ssl_cert_filepath = NULL; info.ssl_private_key_filepath = NULL; } info.gid = -1; info.uid = -1; info.options = opts; context = libwebsocket_create_context(&info); if (context == NULL) { lwsl_err("libwebsocket init failed\n"); return -1; } signal(SIGINT, sighandler); n = 0; while (n >= 0 && !force_exit) { #ifndef LWS_NO_CLIENT struct timeval tv; if (client && !state) { state = 1; lwsl_notice("Client connecting to %s:%u....\n", address, port); /* we are in client mode */ address[sizeof(address) - 1] = '\0'; sprintf(ads_port, "%s:%u", address, port & 65535); wsi = libwebsocket_client_connect(context, address, port, use_ssl, uri, ads_port, ads_port, NULL, -1); if (!wsi) { lwsl_err("Client failed to connect to %s:%u\n", address, port); goto bail; } } if (client && !versa) { gettimeofday(&tv, NULL); if (((unsigned int)tv.tv_usec - oldus) > (unsigned int)rate_us) { libwebsocket_callback_on_writable_all_protocol(&protocols[0]); oldus = tv.tv_usec; } } #endif n = libwebsocket_service(context, 10); } #ifndef LWS_NO_CLIENT bail: #endif libwebsocket_context_destroy(context); lwsl_notice("libwebsockets-test-echo exited cleanly\n"); #ifndef _WIN32 closelog(); #endif return 0; }
//-------------------------------------------------------------- bool Client::connect ( ClientOptions options ){ ofLog( OF_LOG_VERBOSE, "[ofxLibwebsockets] connect: "+options.host+":"+ofToString(options.port)+options.channel+":"+ofToString(options.bUseSSL) ); address = options.host; port = options.port; channel = options.channel; defaultOptions = options; bShouldReconnect = defaultOptions.reconnect; /* enum lws_log_levels { LLL_ERR = 1 << 0, LLL_WARN = 1 << 1, LLL_NOTICE = 1 << 2, LLL_INFO = 1 << 3, LLL_DEBUG = 1 << 4, LLL_PARSER = 1 << 5, LLL_HEADER = 1 << 6, LLL_EXT = 1 << 7, LLL_CLIENT = 1 << 8, LLL_LATENCY = 1 << 9, LLL_COUNT = 10 }; */ lws_set_log_level(LLL_ERR, NULL); // set up default protocols struct libwebsocket_protocols null_protocol = { NULL, NULL, 0 }; // setup the default protocol (the one that works when you do addListener()) registerProtocol( options.protocol, clientProtocol ); lws_protocols.clear(); for (int i=0; i<protocols.size(); ++i) { struct libwebsocket_protocols lws_protocol = { ( protocols[i].first == "NULL" ? NULL : protocols[i].first.c_str() ), lws_client_callback, protocols[i].second->rx_buffer_size, protocols[i].second->rx_buffer_size }; lws_protocols.push_back(lws_protocol); } lws_protocols.push_back(null_protocol); struct lws_context_creation_info info; memset(&info, 0, sizeof info); info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = &lws_protocols[0]; info.extensions = libwebsocket_get_internal_extensions(); info.gid = -1; info.uid = -1; if ( options.ka_time != 0 ){ ofLogVerbose()<<"[ofxLibwebsockets] Setting timeout "<<options.ka_time; info.ka_time = options.ka_time; info.ka_probes = options.ka_probes; info.ka_interval = options.ka_interval; } context = libwebsocket_create_context(&info); //context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL, // &lws_protocols[0], libwebsocket_internal_extensions, // NULL, NULL, /*NULL,*/ -1, -1, 0, NULL); if (context == NULL){ ofLogError() << "[ofxLibwebsockets] libwebsocket init failed"; return false; } else { ofLogVerbose() << "[ofxLibwebsockets] libwebsocket init success"; string host = options.host +":"+ ofToString( options.port ); // register with or without a protocol if ( options.protocol == "NULL"){ lwsconnection = libwebsocket_client_connect( context, options.host.c_str(), options.port, (options.bUseSSL ? 2 : 0 ), options.channel.c_str(), host.c_str(), host.c_str(), NULL, options.version); } else { lwsconnection = libwebsocket_client_connect( context, options.host.c_str(), options.port, (options.bUseSSL ? 2 : 0 ), options.channel.c_str(), host.c_str(), host.c_str(), options.protocol.c_str(), options.version); } if ( lwsconnection == NULL ){ ofLogError() << "[ofxLibwebsockets] client connection failed"; return false; } else { connection = new Connection( (Reactor*) &context, &clientProtocol ); connection->ws = lwsconnection; ofLogVerbose() << "[ofxLibwebsockets] Connection successfully created. Connecting."; startThread(); return true; } } }
int main(int argc, char **argv) { int n = 0; int port = 7681; int use_ssl = 0; struct libwebsocket_context *context; int opts = 0; char interface_name[128] = ""; const char *interface = NULL; int syslog_options = LOG_PID | LOG_PERROR; int client = 0; int listen_port; struct lws_context_creation_info info; #ifndef LWS_NO_CLIENT char address[256]; int rate_us = 250000; unsigned int oldus = 0; struct libwebsocket *wsi; #endif int debug_level = 7; #ifndef LWS_NO_DAEMONIZE int daemonize = 0; #endif memset(&info, 0, sizeof info); #ifndef LWS_NO_CLIENT lwsl_notice("Built to support client operations\n"); #endif #ifndef LWS_NO_SERVER lwsl_notice("Built to support server operations\n"); #endif while (n >= 0) { n = getopt_long(argc, argv, "i:hsp:d:D" #ifndef LWS_NO_CLIENT "c:r:" #endif , options, NULL); if (n < 0) continue; switch (n) { #ifndef LWS_NO_DAEMONIZE case 'D': daemonize = 1; syslog_options &= ~LOG_PERROR; break; #endif #ifndef LWS_NO_CLIENT case 'c': client = 1; strcpy(address, optarg); port = 80; break; case 'r': rate_us = atoi(optarg) * 1000; break; #endif case 'd': debug_level = atoi(optarg); break; case 's': use_ssl = 1; /* 1 = take care about cert verification, 2 = allow anything */ break; case 'p': port = atoi(optarg); break; case 'i': strncpy(interface_name, optarg, sizeof interface_name); interface_name[(sizeof interface_name) - 1] = '\0'; interface = interface_name; break; case '?': case 'h': fprintf(stderr, "Usage: libwebsockets-test-echo " "[--ssl] " #ifndef LWS_NO_CLIENT "[--client <remote ads>] " "[--ratems <ms>] " #endif "[--port=<p>] " "[-d <log bitfield>]\n"); exit(1); } } #ifndef LWS_NO_DAEMONIZE /* * normally lock path would be /var/lock/lwsts or similar, to * simplify getting started without having to take care about * permissions or running as root, set to /tmp/.lwsts-lock */ if (!client && daemonize && lws_daemonize("/tmp/.lwstecho-lock")) { fprintf(stderr, "Failed to daemonize\n"); return 1; } #endif /* we will only try to log things according to our debug_level */ setlogmask(LOG_UPTO (LOG_DEBUG)); openlog("lwsts", syslog_options, LOG_DAEMON); /* tell the library what debug level to emit and to send it to syslog */ lws_set_log_level(debug_level, lwsl_emit_syslog); lwsl_notice("libwebsockets echo test - " "(C) Copyright 2010-2013 Andy Green <*****@*****.**> - " "licensed under LGPL2.1\n"); #ifndef LWS_NO_CLIENT if (client) { lwsl_notice("Running in client mode\n"); listen_port = CONTEXT_PORT_NO_LISTEN; if (use_ssl) use_ssl = 2; } else { #endif #ifndef LWS_NO_SERVER lwsl_notice("Running in server mode\n"); listen_port = port; #endif #ifndef LWS_NO_CLIENT } #endif info.port = listen_port; info.iface = interface; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS info.extensions = libwebsocket_get_internal_extensions(); #endif if (use_ssl && !client) { info.ssl_cert_filepath = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem"; info.ssl_private_key_filepath = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem"; } info.gid = -1; info.uid = -1; info.options = opts; context = libwebsocket_create_context(&info); if (context == NULL) { lwsl_err("libwebsocket init failed\n"); return -1; } #ifndef LWS_NO_CLIENT if (client) { lwsl_notice("Client connecting to %s:%u....\n", address, port); /* we are in client mode */ wsi = libwebsocket_client_connect(context, address, port, use_ssl, "/", address, "origin", NULL, -1); if (!wsi) { lwsl_err("Client failed to connect to %s:%u\n", address, port); goto bail; } lwsl_notice("Client connected to %s:%u\n", address, port); } #endif signal(SIGINT, sighandler); n = 0; while (n >= 0 && !force_exit) { #ifndef LWS_NO_CLIENT struct timeval tv; if (client) { gettimeofday(&tv, NULL); if (((unsigned int)tv.tv_usec - oldus) > rate_us) { libwebsocket_callback_on_writable_all_protocol(&protocols[0]); oldus = tv.tv_usec; } } #endif n = libwebsocket_service(context, 10); } #ifndef LWS_NO_CLIENT bail: #endif libwebsocket_context_destroy(context); lwsl_notice("libwebsockets-test-echo exited cleanly\n"); closelog(); return 0; }
bool WebSocketClient2::on_wsctx_inited() { QUrl mu(this->m_uri); qLogx()<<mu; unsigned short port = mu.port(18080); QString host = mu.host(); QString path = mu.path(); // 默认为1,最安全 int ssl_mode = 1; // 0,ws://, 1,wss://encrypt, 2,wss://self signed if (mu.scheme().toLower() == "ws") { ssl_mode = 0; } else if (mu.scheme().toLower() == "wss") { ssl_mode = 2; } else { Q_ASSERT(1==2); } int conn_retry = 3; while (conn_retry -- > 0) { // 需要关注测试一下,这个调用是否是阻塞式的,如果是非阻塞式,则可以这么用 // 否则,还需要考虑其他解决方式。 qLogx()<<this->m_uri<<host<<path<<port; qLogx()<<"Before libwss clint connect..."<<QDateTime::currentDateTime(); this->m_wsi = libwebsocket_client_connect(this->m_lws_ctx, host.toAscii().data(), port, ssl_mode, path.toAscii().data(), host.toAscii().data(), host.toAscii().data(), vopp_client_protocols[0].name, -1); // this->m_wsi = libwebsocket_client_connect(this->m_lws_ctx, host.toAscii().data(), port, 0, // path.toAscii().data(), // host.toAscii().data(), host.toAscii().data(), // vopp_client_protocols[0].name, -1); if (this->m_wsi == NULL) { qLogx()<<"libwebsocket dumb connect failed."; return false; } // here the conn state is 4, but when run to CALLBACK_ESTABLISH, the state will be 3 ok qLogx()<<"After libwss client connect..."<<QDateTime::currentDateTime() <<libwebsockets_remaining_packet_payload(this->m_wsi) <<libwebsocket_get_socket_fd(this->m_wsi) <<libwebsocket_get_connect_state(this->m_wsi); qLogx()<<"client wsi:"<<this->m_wsi; if (libwebsocket_client_is_connected(this->m_wsi)) { break; } else { break; this->m_wsi = NULL; qLogx()<<"Invalid client wsi state, retry.. "<<conn_retry; if (conn_retry == 0) { Q_ASSERT(1==2); return false; } } } return true; }
int main (int argc, char **argv) { char *address = DEFAULT_ADDRESS; int port = DEFAULT_PORT; char *cert_path = NULL; char *key_path = NULL; int use_ssl = 0; char *host = NULL; char *origin = NULL; int watch = 0; char *arg, *msg = NULL; json_t *json = NULL; int json_flags = JSON_COMPACT|JSON_ENCODE_ANY|JSON_PRESERVE_ORDER|JSON_ENSURE_ASCII; char *web = NULL, *suffix = NULL; char path[PATH_MAX]; char *str = NULL; #ifdef HAVE_WATCH watcher_t *watcher; #endif struct libwebsocket_context *context; struct libwebsocket *wsi; struct lws_context_creation_info info; int opt; const struct option long_options[] = { { "address", 1, NULL, 'a' }, { "port", 1, NULL, 'p' }, #ifdef HAVE_WATCH { "watch", 0, NULL, 'W' }, #endif { "suffix", 1, NULL, 's' }, { "host", 1, NULL, 'H' }, { "certpath", 1, NULL, 'c' }, { "keypath", 1, NULL, 'k' }, { "verbose", 1, NULL, 'v' }, { "quiet", 0, NULL, 'q' }, { "help", 0, NULL, 0 }, { NULL, 0, NULL, 0 } }; while ((opt = getopt_long(argc, argv, "a:p:Ws:H:c:k:vs", long_options, NULL)) != -1) { switch (opt) { case 'a': address = optarg; break; case 'p': port = atoi(optarg); break; case 'W': watch = 1; break; case 's': suffix = optarg; break; case 'H': web = optarg; break; case 'c': cert_path = optarg; break; case 'k': key_path = optarg; break; case 'v': if (optarg) { verbose = atoi(optarg); } else { verbose = 1; } break; case 'q': quiet = 1; break; default: usage(argv[0], NULL); return -1; } } if (argc <= optind) { usage(argv[0], "required args to PATH"); return -1; } arg = argv[optind]; if (!address || strlen(address) <= 0) { usage(argv[0], "invalid server address"); return -1; } if (port < 0) { usage(argv[0], "invalid server port"); return -1; } #ifdef HAVE_SSL if (cert_path || key_path) { use_ssl = 1; } #else use_ssl = 0; cert_path = NULL; key_path = NULL; #endif if (quiet) { lws_set_log_level(-1, NULL); } else if (verbose == 0 || verbose == 1) { lws_set_log_level(LLL_WARN, NULL); } else if (verbose == 2) { lws_set_log_level(LLL_NOTICE, NULL); } #ifdef HAVE_WATCH if (watch) { watcher = watcher_init(); if (!watcher) { _ERR("%s\n", watcher_error()); return -1; } if (watcher_recursively(watcher, arg) != 0) { _ERR("%s\n", watcher_error()); watcher_destroy(watcher); return -1; } signals(); _debug(1, "Starting watching [%s] ...\n", arg); } else { interrupted = 1; } #else interrupted = 1; #endif do { char *filename = NULL; #ifdef HAVE_WATCH if (watch) { if (watcher_next_event(watcher) != 0 || interrupted) { break; } if (watcher_in_event(watcher) != 0) { continue; } filename = watcher_get_filename(watcher); if (!filename) { _ERR("Memory allocate\n"); watcher_destroy(watcher); return -1; } arg = filename; } #endif memset(path, 0, sizeof(path)); str = path; if (web) { if (use_ssl) { str = strcat(str, "https://"); } else { str = strcat(str, "http://"); } str = strcat(str, web); } else { str = strcat(str, "file://"); } #ifdef HAVE_SUFFIX if (suffix) { regex_t preg; regmatch_t pmatch[1]; char *regex = (char *)malloc((strlen(suffix) + 4) * sizeof(char)); if (!regex) { _ERR("Memory allocate\n"); return -1; } sprintf(regex, "(%s)$", suffix); if (regcomp(&preg, suffix, REG_EXTENDED|REG_NEWLINE) == 0) { if (regexec(&preg, arg, 1, pmatch, 0) == 0) { str = strncat(str, arg, (int)pmatch[0].rm_so); } else { str = strcat(str, arg); } regfree(&preg); } else { str = strcat(str, arg); } free(regex); } else { str = strcat(str, arg); } #else str = strcat(str, arg); #endif json = json_object(); if (!json) { _ERR("Creating json object failed\n"); break; } json_object_set_new(json, "command", json_string("reload")); json_object_set_new(json, "path", json_string(path)); msg = json_dumps(json, json_flags); json_delete(json); _debug(1, "Send Message=[%s]\n", msg); memset(&info, 0, sizeof info); info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = protocols; #ifndef LWS_NO_EXTENSIONS info.extensions = libwebsocket_get_internal_extensions(); #endif /* TODO: ssl */ info.ssl_cert_filepath = cert_path; info.ssl_private_key_filepath = key_path; info.gid = -1; info.uid = -1; context = libwebsocket_create_context(&info); if (context == NULL) { _ERR("Creating libwebsocket context failed\n"); } else { host = address; wsi = libwebsocket_client_connect(context, address, port, use_ssl, "/", host, origin, "livereload", -1); if (wsi == NULL) { _ERR("libwebsocket dumb connect failed\n"); } else if (msg) { libwebsocket_service(context, 30); libwebsocket_write(wsi, msg, strlen(msg), LWS_WRITE_TEXT); } libwebsocket_context_destroy(context); } if (msg) { free(msg); } if (filename) { free(filename); filename = NULL; } } while (!interrupted); #ifdef HAVE_WATCH if (watch) { watcher_destroy(watcher); } #endif _debug(1, "\nFinished\n"); return 0; }