c#检测ClientWebSocket何时断开(关闭)
c# Detect when ClientWebSocket is disconnected (closed)
经过长时间的搜索,我来找你帮助我。
我有一个 WPF 应用程序,使用 ClientWebSocket class(使用 System.Net.WebSockets)连接到 WebSocket 服务器(NodeJS)。我的应用程序是 运行 backgroung windows 应用程序,它第一次连接,然后在 1 分钟的计时器内尝试重新连接(如果尚未连接)。但是当我禁用连接(网络连接)时,我的应用程序没有检测到它,所以每 1 分钟告诉我它已连接。我知道我的代码有问题,我不知道如何实现一个事件处理程序,以便在连接丢失(websocket 关闭)时得到通知。
我注意到当我连接到服务器时,我必须创建一个会话,然后我收到一个 session_id,现在我连接到 websocket 服务器。
Class1 是我使用 WebSockets 的库 class class
class1
{
ClientWebSocket web_socket;
bool connected = false;
public async Task<bool> connect_socket()
{
Object result_object;
string session_id;
try
{
if (connected == false)
{
web_socket = new ClientWebSocket();
web_socket.Options.SetRequestHeader("headername", "headerValue");
await web_socket.ConnectAsync(new Uri(" ... uri....."), CancellationToken.None);
create_session();
ArraySegment<byte> byte_received = new ArraySegment<byte>(new byte[1024]);
WebSocketReceiveResult json_notify_result = await web_socket.ReceiveAsync(byte_received, CancellationToken.None);
string string_notify = Encoding.UTF8.GetString(byte_received.Array);
json_notify = JsonConvert.DeserializeObject<Dictionary<string, object>>(string_notify);
if (json_notify.TryGetValue("result", out result_object))
{
var result = JsonConvert.DeserializeObject<Dictionary<string, string>>((result_object).ToString());
if (result.TryGetValue("session_id", out session_id) && (string)session_id != null)
Debug.WriteLine("session_id = " + session_id);
}
connected = true;
}
}
catch (Exception ex)
{
throw ex;
}
return connected;
}
}
在我的 Class2 我使用 Class1
Class2
{
Class2()
{
InitializeComponent();
timer = new System.Threading.Timer(timer_callback, null, 0, 60000);
}
public void timer_callback()
{
if (Class1.connected == false)
{
Class1.connect_socket().Wait();
}
}
}
如有任何建议,我将不胜感激。
我真的卡在这一点上了
您正在使用线程池线程上的 System.Threading.Timer,即 运行 timer_callback。因此在计时器回调中抛出的任何异常 timer_callback 都将被吞没。因此,当您断开连接时 web_socket.ConnectAsync
抛出的异常也将被吞没。
同时尝试检查套接字关闭消息。
var res = await webSocket.ReceiveAsync(segment, cancellation);
if (res.MessageType == WebSocketMessageType.Close)
return false;
我解决了我的问题,所以我回答了自己的问题。通过将 "finaly" 添加到 "connect_socket" 方法的 try-catch 中:
finally
{
Debug.WriteLine("\n"+ "Dispose websocket");
if (web_socket != null)
web_socket.Dispose();
state = WebsocketState.closed;
session_id = null;
Debug.WriteLine("\n" + "state of websocket is : " + state);
}
"state" 是一个用于代替 "connected" 的变量,其取值:关闭、连接、连接。在第二个 class "Class2" 中,我尝试在状态为 "closed"
时连接
if (Class1.state == "closed")
{
Class1.connect_socket().Wait();
}
经过长时间的搜索,我来找你帮助我。
我有一个 WPF 应用程序,使用 ClientWebSocket class(使用 System.Net.WebSockets)连接到 WebSocket 服务器(NodeJS)。我的应用程序是 运行 backgroung windows 应用程序,它第一次连接,然后在 1 分钟的计时器内尝试重新连接(如果尚未连接)。但是当我禁用连接(网络连接)时,我的应用程序没有检测到它,所以每 1 分钟告诉我它已连接。我知道我的代码有问题,我不知道如何实现一个事件处理程序,以便在连接丢失(websocket 关闭)时得到通知。
我注意到当我连接到服务器时,我必须创建一个会话,然后我收到一个 session_id,现在我连接到 websocket 服务器。
Class1 是我使用 WebSockets 的库 class class
class1
{
ClientWebSocket web_socket;
bool connected = false;
public async Task<bool> connect_socket()
{
Object result_object;
string session_id;
try
{
if (connected == false)
{
web_socket = new ClientWebSocket();
web_socket.Options.SetRequestHeader("headername", "headerValue");
await web_socket.ConnectAsync(new Uri(" ... uri....."), CancellationToken.None);
create_session();
ArraySegment<byte> byte_received = new ArraySegment<byte>(new byte[1024]);
WebSocketReceiveResult json_notify_result = await web_socket.ReceiveAsync(byte_received, CancellationToken.None);
string string_notify = Encoding.UTF8.GetString(byte_received.Array);
json_notify = JsonConvert.DeserializeObject<Dictionary<string, object>>(string_notify);
if (json_notify.TryGetValue("result", out result_object))
{
var result = JsonConvert.DeserializeObject<Dictionary<string, string>>((result_object).ToString());
if (result.TryGetValue("session_id", out session_id) && (string)session_id != null)
Debug.WriteLine("session_id = " + session_id);
}
connected = true;
}
}
catch (Exception ex)
{
throw ex;
}
return connected;
}
}
在我的 Class2 我使用 Class1
Class2
{
Class2()
{
InitializeComponent();
timer = new System.Threading.Timer(timer_callback, null, 0, 60000);
}
public void timer_callback()
{
if (Class1.connected == false)
{
Class1.connect_socket().Wait();
}
}
}
如有任何建议,我将不胜感激。 我真的卡在这一点上了
您正在使用线程池线程上的 System.Threading.Timer,即 运行 timer_callback。因此在计时器回调中抛出的任何异常 timer_callback 都将被吞没。因此,当您断开连接时 web_socket.ConnectAsync
抛出的异常也将被吞没。
同时尝试检查套接字关闭消息。
var res = await webSocket.ReceiveAsync(segment, cancellation);
if (res.MessageType == WebSocketMessageType.Close)
return false;
我解决了我的问题,所以我回答了自己的问题。通过将 "finaly" 添加到 "connect_socket" 方法的 try-catch 中:
finally
{
Debug.WriteLine("\n"+ "Dispose websocket");
if (web_socket != null)
web_socket.Dispose();
state = WebsocketState.closed;
session_id = null;
Debug.WriteLine("\n" + "state of websocket is : " + state);
}
"state" 是一个用于代替 "connected" 的变量,其取值:关闭、连接、连接。在第二个 class "Class2" 中,我尝试在状态为 "closed"
时连接if (Class1.state == "closed")
{
Class1.connect_socket().Wait();
}