added clean close method

This commit is contained in:
Pasquale Boemio
2013-04-29 17:20:36 +02:00
parent e6fd1fc30e
commit 2b9575c434
5 changed files with 28 additions and 12 deletions
+2
View File
@@ -10,3 +10,5 @@
*.lai *.lai
*.la *.la
*.a *.a
node_modules/
+19 -9
View File
@@ -107,14 +107,17 @@ struct _RealWebSocket : public WebSocket
std::vector<char> txbuf; std::vector<char> txbuf;
int sockfd; 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() { void poll() {
if (closed) { return; } if(clientStatus==CLOSE) { return; }
while (true) { while (true) {
// FD_ISSET(0, &rfds) will be true // FD_ISSET(0, &rfds) will be true
int N = rxbuf.size(); int N = rxbuf.size();
@@ -128,8 +131,8 @@ struct _RealWebSocket : public WebSocket
} }
else if (ret == 0) { else if (ret == 0) {
rxbuf.resize(N); rxbuf.resize(N);
closed = true;
::close(sockfd); ::close(sockfd);
clientStatus = CLOSE;
break; break;
} }
else { else {
@@ -207,7 +210,12 @@ 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) { 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(); } else { fprintf(stderr, "ERROR: Got unexpected WebSocket message.\n"); close(); }
rxbuf.erase(rxbuf.begin(), rxbuf.begin() + ws.header_size+ws.N); rxbuf.erase(rxbuf.begin(), rxbuf.begin() + ws.header_size+ws.N);
@@ -216,7 +224,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; } if(clientStatus==CLOSING || clientStatus==CLOSE) { fprintf(stderr, "closing"); 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;
@@ -245,9 +253,11 @@ struct _RealWebSocket : public WebSocket
} }
void close() { void close() {
if (closed) { return; } if(clientStatus==CLOSING || clientStatus==CLOSE) { return; }
closed = true; clientStatus=CLOSING;
::close(sockfd); char closeFrame[4] = {0x88, 0x00, 0x00, 0x00};
std::vector<char> header(closeFrame, closeFrame+4);
txbuf.insert(txbuf.end(), header.begin(), header.end());
} }
}; };
+1
View File
@@ -17,6 +17,7 @@ int main()
ws->poll(); ws->poll();
ws->dispatch([](const std::string & message) { ws->dispatch([](const std::string & message) {
printf(">>> %s\n", message.c_str()); printf(">>> %s\n", message.c_str());
ws->close();
}); });
} }
return 0; return 0;
+5 -3
View File
@@ -16,9 +16,11 @@ int main()
assert(ws); assert(ws);
ws->send("goodbye"); ws->send("goodbye");
ws->send("hello"); ws->send("hello");
while (true) { ws->close();
ws->poll(); while(true) {
ws->dispatch(handle_message); ws->poll();
ws->dispatch(handle_message);
} }
return 0; return 0;
} }
+1
View File
@@ -28,6 +28,7 @@ wss.on('connection', function(ws) {
if (data == 'hello') { ws.send('world'); } if (data == 'hello') { ws.send('world'); }
}); });
ws.on('close', function() { ws.on('close', function() {
console.log('Connection closed!');
}); });
ws.on('error', function(e) { ws.on('error', function(e) {
}); });