Skip to content

Commit aa8056f

Browse files
committed
修复WebSocket连接断开后没有释放资源的BUG
1 parent 2c1ad77 commit aa8056f

File tree

2 files changed

+32
-18
lines changed

2 files changed

+32
-18
lines changed

Quick.Protocol.WebSocket.Server.AspNetCore/QpWebSocketServer.cs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Microsoft.AspNetCore.Http;
22
using Quick.Protocol.Utils;
33
using System;
4-
using System.Collections;
54
using System.Collections.Generic;
65
using System.Threading;
76
using System.Threading.Tasks;
@@ -17,29 +16,38 @@ private class WebSocketContext
1716
{
1817
public string ConnectionInfo { get; set; }
1918
public System.Net.WebSockets.WebSocket WebSocket { get; set; }
19+
public CancellationTokenSource Cts { get; set; }
2020

2121
public WebSocketContext(string connectionInfo, System.Net.WebSockets.WebSocket webSocket, CancellationTokenSource cts)
2222
{
2323
ConnectionInfo = connectionInfo;
2424
WebSocket = webSocket;
25+
Cts = cts;
2526
}
2627
}
2728

2829
public QpWebSocketServer(QpWebSocketServerOptions options) : base(options) { }
2930

3031
public override void Start()
3132
{
32-
isStarted=true;
33+
isStarted = true;
3334
lock (webSocketContextQueue)
35+
{
36+
foreach (var webSocket in webSocketContextQueue)
37+
webSocket.Cts.Cancel();
3438
webSocketContextQueue.Clear();
39+
}
3540
base.Start();
3641
}
3742

38-
public Task OnNewConnection(System.Net.WebSockets.WebSocket webSocket, ConnectionInfo connectionInfo)
43+
public async Task OnNewConnection(System.Net.WebSockets.WebSocket webSocket, ConnectionInfo connectionInfo)
3944
{
4045
//如果还没有开始接收,则直接关闭
4146
if (!isStarted)
42-
return webSocket.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
47+
{
48+
await webSocket.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
49+
return;
50+
}
4351

4452
var connectionInfoStr = $"WebSocket:{connectionInfo.RemoteIpAddress}:{connectionInfo.RemotePort}";
4553
var cts = new CancellationTokenSource();
@@ -49,7 +57,7 @@ public Task OnNewConnection(System.Net.WebSockets.WebSocket webSocket, Connectio
4957
connectionInfoStr,
5058
webSocket,
5159
cts));
52-
return Task.Delay(-1, cts.Token).ContinueWith(t =>
60+
await Task.Delay(-1, cts.Token).ContinueWith(t =>
5361
{
5462
if (LogUtils.LogConnection)
5563
LogUtils.Log("[Connection]{0} disconnected.", connectionInfoStr);
@@ -58,9 +66,13 @@ public Task OnNewConnection(System.Net.WebSockets.WebSocket webSocket, Connectio
5866

5967
public override void Stop()
6068
{
61-
isStarted=false;
69+
isStarted = false;
6270
lock (webSocketContextQueue)
71+
{
72+
foreach (var webSocket in webSocketContextQueue)
73+
webSocket.Cts.Cancel();
6374
webSocketContextQueue.Clear();
75+
}
6476
base.Stop();
6577
}
6678

@@ -73,7 +85,7 @@ protected override async Task InnerAcceptAsync(CancellationToken token)
7385
webSocketContextQueue.Clear();
7486
}
7587
//如果当前没有WebSocket连接,则等待0.1秒后再返回
76-
if (webSocketContexts == null || webSocketContexts.Length==0)
88+
if (webSocketContexts == null || webSocketContexts.Length == 0)
7789
{
7890
await Task.Delay(100).ConfigureAwait(false);
7991
return;
@@ -84,15 +96,19 @@ protected override async Task InnerAcceptAsync(CancellationToken token)
8496
{
8597
if (LogUtils.LogConnection)
8698
LogUtils.Log("[Connection]{0} connected.", context.ConnectionInfo);
87-
OnNewChannelConnected(new WebSocketServerStream(context.WebSocket, token), context.ConnectionInfo, token);
99+
OnNewChannelConnected(new WebSocketServerStream(context.WebSocket, context.Cts), context.ConnectionInfo, token);
88100
}
89101
catch (Exception ex)
90102
{
103+
context.Cts.Cancel();
91104
if (LogUtils.LogConnection)
92105
LogUtils.Log("[Connection]Init&Start Channel error,reason:{0}", ex.ToString());
93-
try { await context.WebSocket
106+
try
107+
{
108+
await context.WebSocket
94109
.CloseAsync(System.Net.WebSockets.WebSocketCloseStatus.InternalServerError, ex.Message, CancellationToken.None)
95-
.ConfigureAwait(false); }
110+
.ConfigureAwait(false);
111+
}
96112
catch { }
97113
}
98114
}

Quick.Protocol.WebSocket.Server.AspNetCore/WebSocketServerStream.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.IO;
4-
using System.Linq;
5-
using System.Text;
63
using System.Threading;
74
using System.Threading.Tasks;
85

@@ -11,12 +8,12 @@ namespace Quick.Protocol.WebSocket.Server.AspNetCore
118
internal class WebSocketServerStream : Stream
129
{
1310
private System.Net.WebSockets.WebSocket webSocket;
14-
private CancellationToken cancellationToken;
11+
private CancellationTokenSource cts;
1512

16-
public WebSocketServerStream(System.Net.WebSockets.WebSocket webSocket, CancellationToken cancellationToken)
13+
public WebSocketServerStream(System.Net.WebSockets.WebSocket webSocket, CancellationTokenSource cts)
1714
{
1815
this.webSocket = webSocket;
19-
this.cancellationToken = cancellationToken;
16+
this.cts = cts;
2017
}
2118

2219
public override bool CanSeek => throw new NotImplementedException();
@@ -33,7 +30,7 @@ public override void Flush() { }
3330

3431
public override int Read(byte[] buffer, int offset, int count)
3532
{
36-
var result = webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count), cancellationToken).Result;
33+
var result = webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count), CancellationToken.None).Result;
3734
return result.Count;
3835
}
3936

@@ -50,7 +47,7 @@ public override void Write(byte[] buffer, int offset, int count)
5047
new ArraySegment<byte>(buffer, offset, count),
5148
System.Net.WebSockets.WebSocketMessageType.Binary,
5249
true,
53-
cancellationToken)
50+
CancellationToken.None)
5451
.Wait();
5552
}
5653

@@ -66,6 +63,7 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati
6663

6764
protected override void Dispose(bool disposing)
6865
{
66+
cts.Dispose();
6967
webSocket.Dispose();
7068
base.Dispose(disposing);
7169
}

0 commit comments

Comments
 (0)