diff --git a/.gitignore b/.gitignore index 8df9393..9cd7b1b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ *.lai *.la *.a + +node_modules/ diff --git a/easywsclient.cpp b/easywsclient.cpp index b392574..22df14b 100644 --- a/easywsclient.cpp +++ b/easywsclient.cpp @@ -107,14 +107,17 @@ struct _RealWebSocket : public WebSocket std::vector txbuf; int sockfd; - bool closed; + /* I suppose we should add the other websocket status. + * Right now only this two are used, so, to avoid problems, + * I've added a dummy status that includes all the non "closing" ones */ + enum clientStatusValues { CLOSING, CLOSE, DUMMYSTATUS } clientStatus; - _RealWebSocket(int sockfd) : sockfd(sockfd), closed(false) { + _RealWebSocket(int sockfd) : sockfd(sockfd), clientStatus(DUMMYSTATUS) { } void poll() { - if (closed) { return; } + if(clientStatus==CLOSE) { return; } while (true) { // FD_ISSET(0, &rfds) will be true int N = rxbuf.size(); @@ -128,8 +131,8 @@ struct _RealWebSocket : public WebSocket } else if (ret == 0) { rxbuf.resize(N); - closed = true; ::close(sockfd); + clientStatus = CLOSE; break; } else { @@ -207,7 +210,12 @@ struct _RealWebSocket : public WebSocket } else if (ws.opcode == wsheader_type::PING) { } else if (ws.opcode == wsheader_type::PONG) { } - else if (ws.opcode == wsheader_type::CLOSE) { close(); } + else if (ws.opcode == wsheader_type::CLOSE) { + if(clientStatus!=CLOSING) { close(); } + ::close(sockfd); + clientStatus = CLOSE; + fprintf(stderr, "Connection closed!\n"); + } else { fprintf(stderr, "ERROR: Got unexpected WebSocket message.\n"); close(); } rxbuf.erase(rxbuf.begin(), rxbuf.begin() + ws.header_size+ws.N); @@ -216,7 +224,7 @@ struct _RealWebSocket : public WebSocket void send(std::string message) { // TODO: consider acquiring a lock on txbuf... - if (closed) { return; } + if(clientStatus==CLOSING || clientStatus==CLOSE) { fprintf(stderr, "closing"); return; } std::vector header; header.assign(2 + (message.size() >= 126 ? 2 : 0) + (message.size() >= 65536 ? 6 : 0), 0); header[0] = 0x80 | wsheader_type::TEXT_FRAME; @@ -245,9 +253,11 @@ struct _RealWebSocket : public WebSocket } void close() { - if (closed) { return; } - closed = true; - ::close(sockfd); + if(clientStatus==CLOSING || clientStatus==CLOSE) { return; } + clientStatus=CLOSING; + char closeFrame[4] = {0x88, 0x00, 0x00, 0x00}; + std::vector header(closeFrame, closeFrame+4); + txbuf.insert(txbuf.end(), header.begin(), header.end()); } }; diff --git a/example-client-cpp11.cpp b/example-client-cpp11.cpp index 6cd5e0f..54798b9 100644 --- a/example-client-cpp11.cpp +++ b/example-client-cpp11.cpp @@ -17,6 +17,7 @@ int main() ws->poll(); ws->dispatch([](const std::string & message) { printf(">>> %s\n", message.c_str()); + ws->close(); }); } return 0; diff --git a/example-client.cpp b/example-client.cpp index 9d89506..58e52ac 100644 --- a/example-client.cpp +++ b/example-client.cpp @@ -16,9 +16,11 @@ int main() assert(ws); ws->send("goodbye"); ws->send("hello"); - while (true) { - ws->poll(); - ws->dispatch(handle_message); + ws->close(); + while(true) { + ws->poll(); + ws->dispatch(handle_message); } + return 0; } diff --git a/example-server.js b/example-server.js index 4eb17f9..64e4603 100644 --- a/example-server.js +++ b/example-server.js @@ -28,6 +28,7 @@ wss.on('connection', function(ws) { if (data == 'hello') { ws.send('world'); } }); ws.on('close', function() { + console.log('Connection closed!'); }); ws.on('error', function(e) { });