Skip to content

Commit

Permalink
Add automatic ping on websockets
Browse files Browse the repository at this point in the history
Signed-off-by: Luca Niccoli <l.niccoli@awtech.it>
  • Loading branch information
lniccoli committed Dec 31, 2014
1 parent ad5f912 commit 562954b
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions source/vibe/http/websockets.d
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ final class WebSocket {
Task m_reader;
TaskMutex m_readMutex, m_writeMutex;
TaskCondition m_readCondition;
Timer m_pingTimer;
uint m_lastPingIndex;
bool m_pongReceived;
}

this(ConnectionStream conn, in HTTPServerRequest request)
Expand All @@ -204,6 +207,8 @@ final class WebSocket {
m_writeMutex = new TaskMutex;
m_readMutex = new TaskMutex;
m_readCondition = new TaskCondition(m_readMutex);
m_pingTimer = setTimer(dur!"seconds"(60), &sendPing, true);
m_pongReceived = true;
}

/**
Expand Down Expand Up @@ -310,7 +315,7 @@ final class WebSocket {
frame.writeFrame(m_conn);
}
}

if (m_pingTimer) m_pingTimer.stop();
if (Task.getThis() != m_reader) m_reader.join();
}

Expand Down Expand Up @@ -368,6 +373,12 @@ final class WebSocket {
while (!m_conn.empty) {
assert(!m_nextMessage);
scope msg = new IncomingWebSocketMessage(m_conn);
if (msg.frameOpcode == FrameOpcode.pong) {
enforce(msg.peek().length == uint.sizeof, "Pong payload has wrong length");
enforce(m_lastPingIndex == littleEndianToNative!uint(msg.peek()[0..uint.sizeof]), "Pong payload has wrong value");
m_pongReceived = true;
continue;
}
if(msg.frameOpcode == FrameOpcode.close) {
logDebug("Got closing frame (%s)", m_sentCloseFrame);
if(!m_sentCloseFrame) close();
Expand All @@ -387,8 +398,24 @@ final class WebSocket {
}
m_conn.close();
}
}

private void sendPing() {
if (!m_pongReceived) {
logDebug("Pong not received");
m_conn.close();
if (m_pingTimer) m_pingTimer.stop();
return;
}
m_pongReceived = false;
Frame ping;
ping.opcode = FrameOpcode.ping;
ping.fin = true;
ping.payload = nativeToLittleEndian(++m_lastPingIndex);

ping.writeFrame(m_conn);
logDebug("Ping sent");
}
}

/**
Represents a single outgoing _WebSocket message as an OutputStream.
Expand Down Expand Up @@ -500,6 +527,7 @@ final class IncomingWebSocketMessage : InputStream {
case FrameOpcode.text:
case FrameOpcode.binary:
case FrameOpcode.close:
case FrameOpcode.pong:
m_currentFrame = frame;
break;
case FrameOpcode.ping:
Expand Down

0 comments on commit 562954b

Please sign in to comment.