From 4f77dfadbfe7eaf39f172fa21260d41ebca002b1 Mon Sep 17 00:00:00 2001
From: zrg <z1873@LAPTOP-EAVL132E>
Date: 星期四, 15 一月 2026 17:53:56 +0800
Subject: [PATCH] 1

---
 WebAPI/WebSocketServer.cs |  212 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 212 insertions(+), 0 deletions(-)

diff --git a/WebAPI/WebSocketServer.cs b/WebAPI/WebSocketServer.cs
new file mode 100644
index 0000000..2460a95
--- /dev/null
+++ b/WebAPI/WebSocketServer.cs
@@ -0,0 +1,212 @@
+锘縰sing Fleck;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Data;
+using System.Web;
+using WebAPI;
+
+namespace WebApiWithFleck
+{
+    /// <summary>
+    /// Fleck WebSocket 鏈嶅姟灏佽
+    /// </summary>
+    public static class WebSocketServer
+    {
+        private static List<IWebSocketConnection> _connections = new List<IWebSocketConnection>();
+        // 濂楁帴瀛楄繛鎺� 涓� 鐢ㄦ埛鏍囪瘑绗� 瀛楀吀
+        private static ConcurrentDictionary<IWebSocketConnection, string> _NameConnectionDict = new ConcurrentDictionary<IWebSocketConnection, string>();
+        
+        private static Fleck.WebSocketServer _server;
+        // 鍐呯疆瀹氭椂鍣紙鐢ㄤ簬瀹氭椂鏌ヨ鏁版嵁搴撳苟鎺ㄩ�侊級
+        private static System.Timers.Timer _pushTimer;
+        // 鍐呯疆瀹氭椂鍣紙鐢ㄤ簬鍙戦�佸績璺充俊鍙凤級
+        private static System.Timers.Timer _pushTimerBeat;
+        // 300000
+        private static readonly int _pushInterval = 300000; // 姣�5鍒嗛挓鍙戦�佷竴娆℃秷鎭�
+
+        /// <summary>
+        /// 鍚姩 WebSocket 鏈嶅姟锛堢洃鍚� 8089 绔彛锛�
+        /// </summary>
+        public static void Start()
+        {
+            // 閰嶇疆 WebSocket 鐩戝惉鍦板潃锛堢嫭绔嬬鍙� 8089锛�
+            var wsUrl = "ws://0.0.0.0:8089/ws"; // 0.0.0.0 鍏佽澶栭儴璁块棶
+            _server = new Fleck.WebSocketServer(wsUrl);
+
+            _pushTimer = new System.Timers.Timer(_pushInterval);
+            _pushTimer.AutoReset = false; // 闈炶嚜鍔ㄩ噸缃紝閬垮厤骞跺彂
+            _pushTimer.Elapsed += OnTimerElapsed; // 缁戝畾闈欐�佷簨浠�
+
+            _pushTimerBeat = new System.Timers.Timer(30000);
+            _pushTimerBeat.AutoReset = false; // 闈炶嚜鍔ㄩ噸缃紝閬垮厤骞跺彂
+            _pushTimerBeat.Elapsed += BeatSignalSender; // 缁戝畾闈欐�佷簨浠�
+
+            // 閰嶇疆 Fleck 鏈嶅姟
+            _server.Start(connection =>
+            {
+                _pushTimer.Start();
+                // 瀹㈡埛绔繛鎺ュ缓绔嬫椂
+                connection.OnOpen = () =>
+                {
+                    string userId = "";
+                    string userName = "";
+                    // 鑾峰彇鍙傛暟
+                    string path = connection.ConnectionInfo.Path;
+                    Uri dummyUri = new Uri($"http://localhost{path}");
+                    var queryParams = HttpUtility.ParseQueryString(dummyUri.Query);
+
+                    userId = queryParams["userId"];
+                    userName = queryParams["userName"];
+
+                    LogService.Write($"WebSocket 瀹㈡埛绔繛鎺ワ細{userId}_{userName}-{connection.ConnectionInfo.ClientIpAddress}");
+                    _connections.Add(connection); // 淇濆瓨杩炴帴
+                    _NameConnectionDict[connection] =  $@"{userId}_{userName}";
+                };
+
+                // 鏀跺埌瀹㈡埛绔秷鎭椂
+                connection.OnMessage = message =>
+                {
+                    Console.WriteLine($"鏀跺埌娑堟伅锛歿message}");
+                };
+
+                // 瀹㈡埛绔柇寮�杩炴帴鏃�
+                connection.OnClose = () =>
+                {
+                    LogService.Write($"WebSocket 瀹㈡埛绔柇寮�锛歿connection.ConnectionInfo.ClientIpAddress}");
+
+                    string success = "";
+                    // 绉婚櫎杩炴帴
+                    _NameConnectionDict.TryRemove(connection,out success);
+                    // _connections.Remove(connection);
+                };
+
+                // 杩炴帴鍑洪敊鏃�
+                connection.OnError = ex =>
+                {
+                    string success = "";
+                    LogService.Write($"WebSocket 閿欒锛歿ex.Message}");
+                    _NameConnectionDict.TryRemove(connection, out success);
+                };
+            });
+
+            LogService.Write($"Fleck WebSocket 鏈嶅姟宸插惎鍔紝鐩戝惉锛歿wsUrl}");
+        }
+
+        /// <summary>
+        /// 鍋滄 WebSocket 鏈嶅姟
+        /// </summary>
+        public static void Stop()
+        {
+            _server?.Dispose();
+            _pushTimer?.Stop();
+            _pushTimerBeat?.Stop();
+
+            Console.WriteLine("Fleck WebSocket 鏈嶅姟宸插仠姝�");
+        }
+
+
+        /// <summary>
+        /// 闈欐�佸畾鏃跺櫒瑙﹀彂浜嬩欢 鎺ㄩ�� 鏈娑堟伅
+        /// </summary>
+        private static void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
+        {
+            SQLHelper.ClsCN oCN = new SQLHelper.ClsCN();
+            DataSet ds = new DataSet();
+            try
+            {
+                JObject NameMsgKVP = new JObject();
+                // 鑾峰彇鏁版嵁搴撲腑鏈璇诲彇鐨勬暟鎹�
+                ds = oCN.RunProcReturn("select * from h_v_OA_WorkLinkBillAllList where 鍗曟嵁鐘舵�� = '宸插鏍�' and 闃呰鐘舵�� = '鏈槄'", "h_v_OA_WorkLinkBillAllList");
+                // 鍒ゆ柇骞挎挱杩樻槸绉佸彂 锛岀粺璁℃暟鎹�
+                JArray dataTableJArray = JArray.Parse(JsonConvert.SerializeObject(ds.Tables[0]));
+                foreach (JToken row in dataTableJArray)
+                {
+                    // 鎻愬墠鑾峰彇骞跺鐞嗚鏁版嵁锛堥伩鍏嶉噸澶嶈闂� row["鍒楀悕"]锛屼笖澶勭悊 null锛�
+                    string receiver = row["鎺ユ敹浜�"]?.ToString() ?? string.Empty; // 涓� null 鏃惰繑鍥炵┖瀛楃涓�
+                    string ccUsers = row["鎵�鏈夋妱閫佷汉"]?.ToString() ?? string.Empty;
+                    string sendType = row["鍙戦�佺被鍨�"]?.ToString() ?? string.Empty;
+
+                    // 璺宠繃鏃犳晥鏁版嵁琛岋紙涓夊垪鍧囦负绌烘椂锛屾棤闇�澶勭悊锛�
+                    if (string.IsNullOrEmpty(receiver) && string.IsNullOrEmpty(ccUsers) && string.IsNullOrEmpty(sendType))
+                        continue;
+
+                    foreach (var dictOne in _NameConnectionDict)
+                    {
+                        string UName = dictOne.Value.Split('_')[1];
+                        // 灏嗘帴鏀朵汉 鎶勯�佷汉 鑾峰彇 骞挎挱鐨勬秷鎭坊鍔犲埌娑堟伅缂撳瓨
+                        if (string.Equals(row["鎺ユ敹浜�"].ToString(), UName)
+                            || row["鎵�鏈夋妱閫佷汉"].ToString().Contains(UName)
+                            || string.Equals(row["鍙戦�佺被鍨�"].ToString(), "鍏叡"))
+                        {
+                            string dictOneVal = dictOne.Value.ToString();
+                            if (NameMsgKVP[dictOneVal] == null)
+                            {
+                                NameMsgKVP[dictOneVal] = new JArray();
+                            }
+
+                            var jArray = NameMsgKVP[dictOneVal] as JArray;
+                            
+                            jArray.Add(row);
+                        }
+                    }
+                }
+                // 鏍规嵁鐢ㄦ埛ID鍒嗗彂鍒颁笉鍚岀殑瀹㈡埛绔�
+                foreach (var dictOne in _NameConnectionDict)
+                {
+                    if(NameMsgKVP[dictOne.Value.ToString()] != null)
+                    {
+                        // 灏佽 websocket 淇℃伅
+                        dictOne.Key.Send(new JObject{ 
+                            ["Type"]="Message",
+                            ["Content"]= NameMsgKVP[dictOne.Value.ToString()].ToString()
+                        }.ToString());
+                    }
+                }
+                LogService.Write("娑堟伅鎺ㄩ�佸畬鎴�...");
+            }
+            catch (Exception ex)
+            {
+                LogService.Write(ex.ToString());
+                return;
+            }
+            finally
+            {
+                // 闈欐�佸畾鏃跺櫒鎵嬪姩閲嶅惎
+                if (_pushTimer != null && !_pushTimer.Enabled)
+                {
+                    _pushTimer.Start();
+                }
+            }
+        }
+
+        // 瀹氭椂鍣ㄥ彂閫佸績璺充俊鍙�
+        private static void BeatSignalSender(object sender, System.Timers.ElapsedEventArgs e)
+        {
+            try
+            {
+                foreach (var dictOne in _NameConnectionDict)
+                {
+                    LogService.Write($@"鏈嶅姟绔� 鍚� {dictOne.Value} 鍙戦�佸績璺充俊鍙�");
+                    dictOne.Key.SendPing(new byte[0]);
+                }
+            }
+            catch (Exception ex)
+            {
+                LogService.Write(ex.ToString());
+                return;
+            }
+            finally
+            {
+                // 闈欐�佸畾鏃跺櫒鎵嬪姩閲嶅惎
+                if (_pushTimer != null && !_pushTimer.Enabled)
+                {
+                    _pushTimer.Start();
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.1