@@ -55,15 +55,40 @@ namespace {
5555 fflush (logfile.file );
5656 }
5757 }
58+
59+ std::string GetExePath ()
60+ {
61+ #ifdef _WIN32
62+ wchar_t result[MAX_PATH] = { 0 };
63+ GetModuleFileNameW (NULL , result, MAX_PATH);
64+ std::wstring wsPath (result);
65+ std::string path (wsPath.begin (), wsPath.end ());
66+ auto pos = path.rfind (" \\ " );
67+ #else
68+ char result[PATH_MAX];
69+ ssize_t count = readlink (" /proc/self/exe" , result, PATH_MAX);
70+ std::string path (result, (count > 0 ) ? count : 0 );
71+ auto pos = path.rfind (" /" );
72+ #endif
73+ return path.substr (0 , pos);
74+ }
5875}
5976
60- ZorroWebsocketProxy::ZorroWebsocketProxy (uint32_t ws_queue_size)
77+ ZorroWebsocketProxy::ZorroWebsocketProxy (uint32_t server_queue_size, int32_t logLevel)
6178 : client_queue_(1 << 16 , CLIENT_TO_SERVER_QUEUE)
62- , server_queue_(ws_queue_size , SERVER_TO_CLIENT_QUEUE)
79+ , server_queue_(server_queue_size , SERVER_TO_CLIENT_QUEUE)
6380 , client_index_(client_queue_.initial_reading_index())
64- , pid_(GetCurrentProcessId())
81+ , pid_(GetCurrentProcessId())
82+ , exec_path_(GetExePath())
6583 , closed_sockets_(256 ) {
66-
84+
85+ if (!logLevel || !logfile.file ) {
86+ lws_set_log_level (LLL_ERR, nullptr );
87+ }
88+ else {
89+ lws_set_log_level (logLevel, log);
90+ }
91+
6792 hMapFile_ = CreateFileMapping (
6893 INVALID_HANDLE_VALUE, // use paging file
6994 NULL , // default security
@@ -115,20 +140,7 @@ ZorroWebsocketProxy::~ZorroWebsocketProxy() {
115140 lwsl_user (" WebosocketsProsy destroyed\n " );
116141}
117142
118- void ZorroWebsocketProxy::run (const char * executable_path, int32_t logLevel) {
119- if (!logLevel || !logfile.file ) {
120- lws_set_log_level (LLL_ERR, nullptr );
121- }
122- else {
123- lws_set_log_level (logLevel, log);
124- }
125-
126- std::string path (executable_path);
127- auto pos = path.rfind (" zorro_websocket_proxy.exe" );
128- if (pos != std::string::npos) {
129- exec_path_ = path.substr (0 , pos - 1 );
130- }
131-
143+ void ZorroWebsocketProxy::run () {
132144 if (!own_shm_) {
133145 auto owner = owner_pid_->load (std::memory_order_relaxed);
134146 if (owner) {
@@ -164,7 +176,7 @@ void ZorroWebsocketProxy::run(const char* executable_path, int32_t logLevel) {
164176 std::this_thread::yield ();
165177 }
166178
167- if (shutdown_time_ && (get_timestamp () - shutdown_time_) >= 15000 ) {
179+ if (shutdown_time_ && (get_timestamp () - shutdown_time_) >= 10000 ) {
168180 run_.store (false , std::memory_order_release);
169181 break ;
170182 }
@@ -216,7 +228,6 @@ void ZorroWebsocketProxy::handleClientRegistration(Message& msg) {
216228 auto reg = reinterpret_cast <RegisterMessage*>(msg.data );
217229 lwsl_user (" Register client %d connected, name: %s\n " , msg.pid , reg->name );
218230 reg->server_pid = pid_;
219- clientSeen_ = true ;
220231 shutdown_time_ = 0 ;
221232
222233 auto it = clients_.find (msg.pid );
@@ -250,6 +261,7 @@ void ZorroWebsocketProxy::unregisterClient(uint32_t pid) {
250261
251262 if (clients_.empty ()) {
252263 lwsl_user (" Last client disconnected. Shuting down...\n " );
264+ shutdown_time_ = get_timestamp ();
253265 }
254266 }
255267}
@@ -275,27 +287,31 @@ void ZorroWebsocketProxy::openWs(Message& msg) {
275287 lwsl_user (" Websocket %s already opened. id=%d, new=%d\n " , req->url , id, req->new_connection );
276288 msg.status .store (Message::Status::SUCCESS, std::memory_order_release);
277289 return ;
278- }
290+ }
279291 }
280292
281- lwsl_user (" Opening ws %s\n " , req->url );
282- req->new_connection = true ;
283- auto websocket = std::make_shared<Websocket>(this , pid_ * 10000 + (++websocket_id_), req->url );
284- auto b = websocket->open (msg.pid );
285- if (b) {
286- req->id = websocket->id ();
287- websocket->clients ().emplace (msg.pid );
288- websocketsByUrl_.emplace (req->url , websocket);
289- websocketsById_.emplace (websocket->id (), std::move (websocket));
290- }
291- msg.status .store (b ? Message::Status::SUCCESS : Message::Status::FAILED, std::memory_order_release);
293+ openNewWs (msg, req);
292294 }
293295 else {
294296 snprintf (req->err , 256 , " Client %d not found" , msg.pid );
295297 msg.status .store (Message::Status::FAILED, std::memory_order_release);
296298 }
297299}
298300
301+ void ZorroWebsocketProxy::openNewWs (Message& msg, WsOpen* req) {
302+ lwsl_user (" Opening ws %s\n " , req->url );
303+ req->new_connection = true ;
304+ auto websocket = std::make_shared<Websocket>(this , pid_ * 10000 + (++websocket_id_), req->url );
305+ auto b = websocket->open (msg.pid );
306+ if (b) {
307+ req->id = websocket->id ();
308+ websocket->clients ().emplace (msg.pid );
309+ websocketsByUrl_.emplace (req->url , websocket);
310+ websocketsById_.emplace (websocket->id (), std::move (websocket));
311+ }
312+ msg.status .store (b ? Message::Status::SUCCESS : Message::Status::FAILED, std::memory_order_release);
313+ }
314+
299315void ZorroWebsocketProxy::closeWs (Message& msg) {
300316 auto req = reinterpret_cast <WsClose*>(msg.data );
301317 auto client = getClient (msg.pid );
@@ -316,6 +332,7 @@ void ZorroWebsocketProxy::closeWs(uint32_t id, DWORD pid) {
316332 lwsl_user (" WS client %d removed from ws id=%d\n " , pid, id);
317333 if (websocket->clients_ .empty ()) {
318334 lwsl_user (" Close ws %s\n " , it->second ->url ().c_str ());
335+ it->second ->status_ = Websocket::Status::DISCONNECTING;
319336 it->second ->stop ();
320337 websocketsByUrl_.erase (it->second ->url ());
321338 websocketsById_.erase (it);
@@ -363,10 +380,6 @@ void ZorroWebsocketProxy::sendMessage(uint64_t index, uint32_t size, uint64_t no
363380
364381bool ZorroWebsocketProxy::checkHeartbeats () {
365382 if (clients_.empty ()) {
366- if (clientSeen_ && !isProcessRunning (L" Zorro.exe" ) && !shutdown_time_) {
367- lwsl_user (" No Zorro running. Shuting down...\n " );
368- shutdown_time_ = get_timestamp ();
369- }
370383 return false ;
371384 }
372385 auto now = get_timestamp ();
@@ -381,6 +394,7 @@ bool ZorroWebsocketProxy::checkHeartbeats() {
381394
382395 if (clients_.empty ()) {
383396 lwsl_user (" Last client disconnected. Stop heartbeating...\n " );
397+ shutdown_time_ = get_timestamp ();
384398 }
385399 }
386400 else {
@@ -428,7 +442,6 @@ void ZorroWebsocketProxy::onWsOpened(uint32_t id, DWORD initiator) {
428442 open->initiator = initiator;
429443 open->new_connection = true ;
430444 sendMessage (index, size);
431- lwsl_user (" send ws opened to client\n " );
432445}
433446
434447void ZorroWebsocketProxy::onWsClosed (uint32_t id) {
@@ -441,6 +454,8 @@ void ZorroWebsocketProxy::onWsClosed(uint32_t id) {
441454 auto idx = closed_sockets_.reserve ();
442455 (*closed_sockets_[idx]) = id;
443456 closed_sockets_.publish (idx);
457+
458+ lwsl_user (" ws %d closed\n " , id);
444459}
445460
446461void ZorroWebsocketProxy::onWsError (uint32_t id, const char * err, size_t len) {
0 commit comments