Browse Source

fix close procedure

Robert 1 year ago
parent
commit
18fdf208db
2 changed files with 37 additions and 43 deletions
  1. 20 33
      EVCB_OCPP.WSServer/ProtalServer.cs
  2. 17 10
      EVCB_OCPP.WSServer/Service/WsService/WsSession.cs

+ 20 - 33
EVCB_OCPP.WSServer/ProtalServer.cs

@@ -541,8 +541,8 @@ namespace EVCB_OCPP.WSServer
 
                 TryRemoveDuplicatedSession(session);
                 clientDic[session.ChargeBoxId] = session;
-                session.SessionClosed += AppServer_SessionClosed;
 
+                session.SessionClosed += AppServer_SessionClosed;
                 session.m_ReceiveData += ReceivedMessageTimeLimited;
                 // logger.LogDebug("------------New " + (session == null ? "Oops" : session.ChargeBoxId));
                 WriteMachineLog(session, "NewSessionConnected", "Connection", "");
@@ -556,16 +556,17 @@ namespace EVCB_OCPP.WSServer
             }
         }
 
-
-        private void AppServer_SessionClosed(object sender, EventArgs e)
+        private void AppServer_SessionClosed(object sender, CloseReason closeReason)
         {
             if (sender is not WsClientData session)
             {
                 return;
             }
+
             session.SessionClosed -= AppServer_SessionClosed;
-            CloseReason value = CloseReason.ServerShutdown;
-            WriteMachineLog(session, string.Format("CloseReason: {0}", value), "Connection", "");
+            session.m_ReceiveData -= ReceivedMessageTimeLimited;
+
+            WriteMachineLog(session, string.Format("CloseReason: {0}", closeReason), "Connection", "");
             RemoveClient(session);
         }
 
@@ -575,7 +576,6 @@ namespace EVCB_OCPP.WSServer
             {
                 var oldSession = clientDic[session.ChargeBoxId];
                 WriteMachineLog(oldSession, "Duplicate Logins", "Connection", "");
-                oldSession.Close(CloseReason.ServerShutdown);
                 RemoveClient(oldSession);
             }
         }
@@ -1252,12 +1252,9 @@ namespace EVCB_OCPP.WSServer
             return confirmed;
         }
 
-
-
-
-        internal void RemoveClient(WsClientData session)
+        internal async void RemoveClient(WsClientData session)
         {
-            if (session == null)
+            if (session is null)
             {
                 return;
             }
@@ -1265,47 +1262,37 @@ namespace EVCB_OCPP.WSServer
             if (!string.IsNullOrEmpty(session.MachineId))
                 logger.LogTrace("RemoveClient[" + session.ChargeBoxId + "]");
 
-            if (session.State == WebSocketState.Open)
-            {
-                session.Close(CloseReason.ServerShutdown);
-            }
             RemoveClientDic(session);
+
             try
             {
-                session.m_ReceiveData -= ReceivedMessageTimeLimited;
+                if (session.State == WebSocketState.Open)
+                {
+                    await session.Close(CloseReason.ServerShutdown);
+                }
+                //session.m_ReceiveData -= ReceivedMessageTimeLimited;
                 // session.Close(CloseReason.ServerShutdown);
-
             }
             catch (Exception ex)
             {
                 //logger.LogWarning("Close client socket error!!");
                 logger.LogWarning(string.Format("Close client socket error!! {0} Msg:{1}", session.ChargeBoxId, ex.Message));
             }
-
-            if (session != null)
-            {
-                session = null;
-            }
         }
 
         private void RemoveClientDic(WsClientData session)
         {
-            if (string.IsNullOrEmpty(session.ChargeBoxId))
+            if (string.IsNullOrEmpty(session.ChargeBoxId) ||
+                !clientDic.ContainsKey(session.ChargeBoxId) ||
+                clientDic[session.ChargeBoxId].SessionID != session.SessionID)
             {
                 return;
             }
 
-            if (clientDic.ContainsKey(session.ChargeBoxId))
-            {
-                if (clientDic[session.ChargeBoxId].SessionID == session.SessionID)
-                {
-                    logger.LogDebug(String.Format("ChargeBoxId:{0} Remove SessionId:{1} Removed SessionId:{2}", session.ChargeBoxId, session.SessionID, clientDic[session.ChargeBoxId].SessionID));
+            logger.LogDebug(String.Format("ChargeBoxId:{0} Remove SessionId:{1} Removed SessionId:{2}", session.ChargeBoxId, session.SessionID, clientDic[session.ChargeBoxId].SessionID));
 
-                    clientDic.Remove(session.ChargeBoxId, out _);
-                    logger.LogTrace("RemoveClient ContainsKey " + session.ChargeBoxId);
-                }
-
-            }
+            clientDic.Remove(session.ChargeBoxId, out _);
+            logger.LogTrace("RemoveClient ContainsKey " + session.ChargeBoxId);
         }
 
         private void WarmUpLog()

+ 17 - 10
EVCB_OCPP.WSServer/Service/WsService/WsSession.cs

@@ -42,15 +42,15 @@ namespace EVCB_OCPP.WSServer.Service.WsService
 
         //public event OCPPClientDataEventHandler<WsSession, String> m_ReceiveData;
 
-        public event EventHandler SessionClosed;
+        public event EventHandler<CloseReason> SessionClosed;
 
-        private CancellationTokenSource stopReceivCancellationTokenSource = new CancellationTokenSource();
+        private CancellationTokenSource disconnectCancellationTokenSource = new CancellationTokenSource();
         private Task ReceiveLoopTask;
 
         private void Init(WebSocket webSocket)
         {
             _WebSocket = webSocket;
-            ReceiveLoopTask = StartReceivd(webSocket, stopReceivCancellationTokenSource.Token);
+            ReceiveLoopTask = StartReceivd(webSocket, disconnectCancellationTokenSource.Token);
         }
 
         private async Task StartReceivd(WebSocket webSocket, CancellationToken token)
@@ -61,7 +61,7 @@ namespace EVCB_OCPP.WSServer.Service.WsService
                 var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), token);
                 if (result.CloseStatus.HasValue)
                 {
-                    Close(CloseReason.ClientClosing);
+                    _ = Close(CloseReason.ClientClosing);
                     break;
                 }
                 string received = Encoding.UTF8.GetString(buffer, 0, result.Count);
@@ -79,19 +79,26 @@ namespace EVCB_OCPP.WSServer.Service.WsService
         internal void Send(string dataString)
         {
             var data = Encoding.UTF8.GetBytes(dataString);
-            ClientWebSocket.SendAsync(data, WebSocketMessageType.Text, endOfMessage: true, cancellationToken: default);
+            ClientWebSocket.SendAsync(data, WebSocketMessageType.Text, endOfMessage: true, cancellationToken: disconnectCancellationTokenSource.Token);
         }
 
         internal void Send(byte[] data, int offset, int length)
         {
-            ClientWebSocket.SendAsync(data, WebSocketMessageType.Text, endOfMessage: true, cancellationToken: default);
+            ClientWebSocket.SendAsync(data, WebSocketMessageType.Text, endOfMessage: true, cancellationToken: disconnectCancellationTokenSource.Token);
         }
 
-        internal void Close(CloseReason closeReason)
+        internal async Task Close(CloseReason closeReason)
         {
-            SessionClosed?.Invoke(this, null);
-            stopReceivCancellationTokenSource.Cancel();
-            _WebSocket.Dispose();
+            try
+            {
+                await _WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, closeReason.ToString(), default);
+            }
+            finally
+            {
+                _WebSocket.Dispose();
+            }
+            disconnectCancellationTokenSource.Cancel();
+            SessionClosed?.Invoke(this, closeReason);
             EndConnSemaphore.Release();
         }
     }