@@ -52,14 +52,22 @@ private static async Task PumpWebSocket(WebSocket source, WebSocket destination,
52
52
}
53
53
catch ( OperationCanceledException )
54
54
{
55
- await destination . CloseOutputAsync ( WebSocketCloseStatus . EndpointUnavailable , null , cancellationToken ) ;
55
+ await TryCloseWebSocket (
56
+ destination ,
57
+ WebSocketCloseStatus . EndpointUnavailable ,
58
+ null ,
59
+ cancellationToken ) ;
56
60
return ;
57
61
}
58
62
catch ( WebSocketException e )
59
63
{
60
64
if ( e . WebSocketErrorCode == WebSocketError . ConnectionClosedPrematurely )
61
65
{
62
- await destination . CloseOutputAsync ( WebSocketCloseStatus . EndpointUnavailable , null , cancellationToken ) ;
66
+ await TryCloseWebSocket (
67
+ destination ,
68
+ WebSocketCloseStatus . EndpointUnavailable ,
69
+ null ,
70
+ cancellationToken ) ;
63
71
return ;
64
72
}
65
73
@@ -68,11 +76,18 @@ private static async Task PumpWebSocket(WebSocket source, WebSocket destination,
68
76
69
77
if ( result . MessageType == WebSocketMessageType . Close )
70
78
{
71
- await destination . CloseOutputAsync ( source . CloseStatus . Value , source . CloseStatusDescription , cancellationToken ) ;
79
+ await TryCloseWebSocket (
80
+ destination ,
81
+ source . CloseStatus . Value ,
82
+ source . CloseStatusDescription ,
83
+ cancellationToken ) ;
72
84
return ;
73
85
}
74
86
75
- await destination . SendAsync ( new ArraySegment < byte > ( buffer , 0 , result . Count ) , result . MessageType , result . EndOfMessage , cancellationToken ) ;
87
+ if ( destination . State == WebSocketState . Open )
88
+ {
89
+ await destination . SendAsync ( new ArraySegment < byte > ( buffer , 0 , result . Count ) , result . MessageType , result . EndOfMessage , cancellationToken ) ;
90
+ }
76
91
}
77
92
}
78
93
@@ -154,5 +169,20 @@ await Task.WhenAll(
154
169
PumpWebSocket ( server , client . ToWebSocket ( ) , DefaultWebSocketBufferSize , context . RequestAborted ) ) ;
155
170
}
156
171
}
172
+
173
+ private static async Task < bool > TryCloseWebSocket (
174
+ WebSocket webSocket ,
175
+ WebSocketCloseStatus closeStatus ,
176
+ string statusDescription ,
177
+ CancellationToken cancellationToken )
178
+ {
179
+ if ( webSocket . State == WebSocketState . Open || webSocket . State == WebSocketState . CloseReceived )
180
+ {
181
+ await webSocket . CloseOutputAsync ( closeStatus , statusDescription , cancellationToken ) ;
182
+ return true ;
183
+ }
184
+
185
+ return false ;
186
+ }
157
187
}
158
188
}
0 commit comments