Skip to content

Commit

Permalink
Fix closing hangs (#131)
Browse files Browse the repository at this point in the history
A peer can make us wait forever when closing a connection.
This PR instead tries to be nice and wait for him, but kills the connection after a while
  • Loading branch information
Menduist committed Nov 22, 2022
1 parent cf8b8ce commit 691f069
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions websock/session.nim
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,10 @@ proc handleClose*(
if ws.readyState != ReadyState.Closing:
ws.readyState = ReadyState.Closing
trace "Sending close", code = ord(code), reason
await ws.send(prepareCloseBody(code, reason), Opcode.Close)
try:
await ws.send(prepareCloseBody(code, reason), Opcode.Close).wait(5.seconds)
except CatchableError as exc:
trace "Failed to send Close opcode", err=exc.msg

ws.readyState = ReadyState.Closed

Expand Down Expand Up @@ -502,18 +505,22 @@ proc close*(
if ws.readyState != ReadyState.Open:
return

try:
ws.readyState = ReadyState.Closing
proc gentleCloser(ws: WSSession, closeBody: seq[byte]) {.async.} =
await ws.send(
prepareCloseBody(code, reason),
closeBody,
opcode = Opcode.Close)

# read frames until closed
try:
while ws.readyState != ReadyState.Closed:
discard await ws.readFrame()
except CatchableError as exc:
ws.readyState = ReadyState.Closed
await ws.stream.closeWait()
discard # most likely EOF
try:
ws.readyState = ReadyState.Closing
await gentleCloser(ws, prepareCloseBody(code, reason)).wait(10.seconds)
except CatchableError as exc:
trace "Exception closing", exc = exc.msg
finally:
await ws.stream.closeWait()
ws.readyState = ReadyState.Closed

0 comments on commit 691f069

Please sign in to comment.