Adding close() method. It abruptly closes the socket (does not bother to send a

CLOSE message prior to actually closing the socket).
This commit is contained in:
David Baird
2013-04-27 23:26:19 -06:00
parent f75e79b1ff
commit f7d998481c
3 changed files with 16 additions and 5 deletions
+4
View File
@@ -50,6 +50,10 @@ void dispatch(Callable callable);
// Sends a TEXT type message (gets put into a buffer for poll() to send // Sends a TEXT type message (gets put into a buffer for poll() to send
// later): // later):
void send(std::string message); void send(std::string message);
// Close the WebSocket (N.B. - this is an abrupt/rude message at the moment, as
// it simply closes the socket without sending an official CLOSE message.)
void close();
``` ```
Put together, the usage looks like this: Put together, the usage looks like this:
+11 -5
View File
@@ -57,7 +57,7 @@ struct _DummyWebSocket : public WebSocket
{ {
void poll() { } void poll() { }
void send(std::string message) { } void send(std::string message) { }
void _dispatch(Callback & callable) { } void close() { } void _dispatch(Callback & callable) { }
}; };
@@ -129,7 +129,7 @@ struct _RealWebSocket : public WebSocket
else if (ret == 0) { else if (ret == 0) {
rxbuf.resize(N); rxbuf.resize(N);
closed = true; closed = true;
close(sockfd); ::close(sockfd);
break; break;
} }
else { else {
@@ -148,7 +148,7 @@ struct _RealWebSocket : public WebSocket
// Should work with C functions, C++ functors, and C++11 std::function and // Should work with C functions, C++ functors, and C++11 std::function and
// lambda: // lambda:
//template<class Callable> //template<class Callable>
//void dispatch(Callable callable) { //void dispatch(Callable callable)
virtual void _dispatch(WebSocket::Callback & callable) { virtual void _dispatch(WebSocket::Callback & callable) {
// TODO: consider acquiring a lock on rxbuf... // TODO: consider acquiring a lock on rxbuf...
while (true) { while (true) {
@@ -207,8 +207,8 @@ struct _RealWebSocket : public WebSocket
} }
else if (ws.opcode == wsheader_type::PING) { } else if (ws.opcode == wsheader_type::PING) { }
else if (ws.opcode == wsheader_type::PONG) { } else if (ws.opcode == wsheader_type::PONG) { }
else if (ws.opcode == wsheader_type::CLOSE) { closed = true; close(sockfd); } else if (ws.opcode == wsheader_type::CLOSE) { closed = true; ::close(sockfd); }
else { fprintf(stderr, "ERROR: Got unexpected WebSocket message.\n"); closed = true; close(sockfd); } else { fprintf(stderr, "ERROR: Got unexpected WebSocket message.\n"); closed = true; ::close(sockfd); }
rxbuf.erase(rxbuf.begin(), rxbuf.begin() + ws.header_size+ws.N); rxbuf.erase(rxbuf.begin(), rxbuf.begin() + ws.header_size+ws.N);
} }
@@ -216,6 +216,7 @@ struct _RealWebSocket : public WebSocket
void send(std::string message) { void send(std::string message) {
// TODO: consider acquiring a lock on txbuf... // TODO: consider acquiring a lock on txbuf...
if (closed) { return; }
std::vector<uint8_t> header; std::vector<uint8_t> header;
header.assign(2 + (message.size() >= 126 ? 2 : 0) + (message.size() >= 65536 ? 6 : 0), 0); header.assign(2 + (message.size() >= 126 ? 2 : 0) + (message.size() >= 65536 ? 6 : 0), 0);
header[0] = 0x80 | wsheader_type::TEXT_FRAME; header[0] = 0x80 | wsheader_type::TEXT_FRAME;
@@ -243,6 +244,11 @@ struct _RealWebSocket : public WebSocket
txbuf.insert(txbuf.end(), message.begin(), message.end()); txbuf.insert(txbuf.end(), message.begin(), message.end());
} }
void close() {
closed = true;
::close(sockfd);
}
}; };
+1
View File
@@ -23,6 +23,7 @@ struct WebSocket {
virtual ~WebSocket() { } virtual ~WebSocket() { }
virtual void poll() = 0; virtual void poll() = 0;
virtual void send(std::string message) = 0; virtual void send(std::string message) = 0;
virtual void close() = 0;
template<class Callable> template<class Callable>
void dispatch(Callable callable) { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers void dispatch(Callable callable) { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers
struct _Callback : public Callback { struct _Callback : public Callback {