diff --git a/easywsclient.cpp b/easywsclient.cpp index 6516193..0e47a69 100644 --- a/easywsclient.cpp +++ b/easywsclient.cpp @@ -57,7 +57,10 @@ struct _DummyWebSocket : public WebSocket { void poll() { } void send(std::string message) { } - void close() { } void _dispatch(Callback & callable) { } + void close() { } + void _dispatch(Callback & callable) { } + const readyStateValues getReadyState() {} + }; @@ -107,17 +110,17 @@ struct _RealWebSocket : public WebSocket std::vector txbuf; int sockfd; - /* I suppose we should add the others 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; + readyStateValues readyState; + _RealWebSocket(int sockfd) : sockfd(sockfd), readyState(OPEN) { + } - _RealWebSocket(int sockfd) : sockfd(sockfd), clientStatus(DUMMYSTATUS) { + const readyStateValues getReadyState() { + return readyState; } void poll() { - if(clientStatus==CLOSE) { return; } + if(readyState==CLOSED) { return; } while (true) { // FD_ISSET(0, &rfds) will be true int N = rxbuf.size(); @@ -132,7 +135,8 @@ struct _RealWebSocket : public WebSocket else if (ret == 0) { rxbuf.resize(N); ::close(sockfd); - clientStatus = CLOSE; + readyState = CLOSED; + fprintf(stderr, "Connection closed!\n"); break; } else { @@ -211,10 +215,7 @@ 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) { - if(clientStatus != CLOSING) { close(); } - ::close(sockfd); - clientStatus = CLOSE; - fprintf(stderr, "Connection closed!\n"); + if(readyState != CLOSING) { close(); } } else { fprintf(stderr, "ERROR: Got unexpected WebSocket message.\n"); close(); } @@ -224,7 +225,7 @@ struct _RealWebSocket : public WebSocket void send(std::string message) { // TODO: consider acquiring a lock on txbuf... - if(clientStatus == CLOSING || clientStatus == CLOSE) { return; } + if(readyState == CLOSING || readyState == CLOSED) { 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; @@ -253,8 +254,8 @@ struct _RealWebSocket : public WebSocket } void close() { - if(clientStatus == CLOSING || clientStatus == CLOSE) { return; } - clientStatus = CLOSING; + if(readyState == CLOSING || readyState == CLOSED) { return; } + readyState = 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/easywsclient.hpp b/easywsclient.hpp index f62ca28..799c648 100644 --- a/easywsclient.hpp +++ b/easywsclient.hpp @@ -14,6 +14,7 @@ namespace easywsclient { struct WebSocket { typedef WebSocket * pointer; + typedef enum readyStateValues { CLOSING, CLOSED, CONNECTING, OPEN } readyStateValues; // Factories: static pointer create_dummy(); @@ -24,6 +25,7 @@ struct WebSocket { virtual void poll() = 0; virtual void send(std::string message) = 0; virtual void close() = 0; + virtual const readyStateValues getReadyState() = 0; template void dispatch(Callable callable) { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers struct _Callback : public Callback { diff --git a/example-client.cpp b/example-client.cpp index 58e52ac..5de4d71 100644 --- a/example-client.cpp +++ b/example-client.cpp @@ -17,7 +17,8 @@ int main() ws->send("goodbye"); ws->send("hello"); ws->close(); - while(true) { + while(ws->getReadyState() != WebSocket::CLOSED) + { ws->poll(); ws->dispatch(handle_message); }