Chr
2024-08-23 12acdf14fcddae8d16e00b7b981559da67ce60ea
PdmAlert/MainWindow.xaml.cs
@@ -2,16 +2,19 @@
using DevComponents.DotNetBar;
using System.Windows;
using System.Drawing;
using System.Net.WebSockets;
using System;
using System.Threading.Tasks;
using System.Text;
using System.Diagnostics;
using System.Timers;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using PdmAlert.Entity;
using System.Threading;
using System.Net.Http;
using PdmAlert.Util;
using log4net;
using WebSocketSharp;
using System.Windows.Controls;
namespace PdmAlert
{
@@ -38,10 +41,17 @@
        }
        #endregion
        private ClientWebSocket socket;
        private static ILog Logger = LogManager.GetLogger("MsgAlert");
        // private ClientWebSocket socket;
        private WebSocket socket;
        private Task readTask;
        private Task writeTask;
        private System.Timers.Timer heartbeatTimer;
        private CancellationTokenSource cancelTokenSource;
        private CancellationToken cancelToken;
        private ToolSetting setting;
        private HttpClient client;
        private volatile bool IsRefreshing = false;
        private string _messageTitle = "共有 0 条未读消息";
@@ -50,6 +60,31 @@
            get => _messageTitle;
            set => RaiseAndSetIfChanged(ref _messageTitle, value);
        }
        private string _statusMessage = "启动中...";
        public string statusMessage
        {
            get => _statusMessage;
            set => RaiseAndSetIfChanged(ref _statusMessage, value);
        }
        private string _userInfo = "";
        public string userInfo
        {
            get => _userInfo;
            set => RaiseAndSetIfChanged(ref _userInfo, value);
        }
        private string _socketStatus = "";
        public string socketStatus
        {
            get => _socketStatus;
            set => RaiseAndSetIfChanged(ref _socketStatus, value);
        }
        private ObservableCollection<MsgData> _messages;
@@ -61,19 +96,104 @@
        public MainWindow()
        {
            cancelTokenSource = new CancellationTokenSource();
            cancelToken = cancelTokenSource.Token;
            setting = ToolSetting.Instance;
            client = new HttpClient
            {
                BaseAddress = new Uri($"http://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/"),
                Timeout = TimeSpan.FromSeconds(setting.TimeOut),
            };
            client.DefaultRequestHeaders.Add("Client-Access-Token", LoginUser.CurrentUser.username);
            userInfo = $"用户:{LoginUser.CurrentUser.realName}";
            DataContext = this;
            InitializeComponent();
        }
        private void ShowStatus(string status, string message)
        {
            Dispatcher.Invoke(() =>
            {
                socketStatus = status;
                statusMessage = message;
            });
        }
        private void Refresh_Click(object sender, RoutedEventArgs e)
        {
            MaskAdorner.ShowMask(mainContent);
            Task.Run(() =>
            {
                try
                {
                    RefreshData();
                }
                catch (Exception ex)
                {
                    Logger.Error("Request Unread Message Failed.", ex);
                }
                finally
                {
                    MaskAdorner.HideMask(mainContent);
                }
            });
        }
        public void RefreshData()
        {
            try
            {
                IsRefreshing = true;
                Result<Page<MsgData>> res = client.GetSyncAction<Page<MsgData>>("pdm/annountCement/listSysMsgByUser", new Page<object>
                {
                    pageNo = 1,
                    pageSize = 100
                });
                Page<MsgData> pageList = res.HandleResult();
                Dispatcher.Invoke(() =>
                {
                    messageTitle = $"共有 {pageList.total} 条未读消息";
                    this.messages = new ObservableCollection<MsgData>(pageList.records);
                });
            }
            finally
            {
                IsRefreshing = false;
            }
        }
        private void FirstRefreshMsg()
        {
            try
            {
                Result<Page<MsgData>> res = client.GetSyncAction<Page<MsgData>>("pdm/annountCement/listSysMsgByUser", new Page<object>
                {
                    pageNo = 1,
                    pageSize = 100
                });
                Page<MsgData> pageList = res.HandleResult();
                messageTitle = $"共有 {pageList.total} 条未读消息";
                this.messages = new ObservableCollection<MsgData>(pageList.records);
                if (pageList.total > 0)
                {
                    Dispatcher.Invoke(() =>
                    {
                        eDesktopAlertColor color = eDesktopAlertColor.Default;
                        eAlertPosition position = eAlertPosition.BottomRight;
                        DesktopAlert.Show($"您有{pageList.total}条未读消息,请检查", "\uf005", eSymbolSet.Awesome, Color.Empty, color, position, 5,
                            DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), AlertClicked);
                    });
                }
            }
            catch (Exception ex)
            {
                Logger.Error("First Request Unread Message Failed.", ex);
            }
        }
        private void SwitchUser_Click(object sender, RoutedEventArgs e)
        {
            ((App)Application.Current).SwithUser();
        }
        private void AlertClicked(long alertId)
@@ -85,33 +205,97 @@
        {
            var screeWidth = SystemParameters.WorkArea.Width;
            var sHeight = SystemParameters.WorkArea.Height;
            this.Left = screeWidth - this.Width;
            this.Top = sHeight - this.Height;
            FirstRefreshMsg();
            ConnectWebSocket();
        }
        private async Task ConnectWebSocket()
        private void ConnectWebSocket()
        {
            try
            {
                ClientWebSocket ws = new ClientWebSocket();
                await ws.ConnectAsync(new Uri($"ws://localhost:8888/pdm-web/daws/{LoginUser.CurrentUser?.id}"), default);
                socket = new WebSocket($"ws://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/daws/{LoginUser.CurrentUser?.id}");
                socket.OnOpen += Socket_OnOpen;
                socket.OnClose += Socket_OnClose;
                socket.OnMessage += Socket_OnMessage;
                socket.OnError += Socket_OnError;
                socket.Connect();
                StartHeartBeat();
                /*await ws.ConnectAsync(new Uri($"ws://{setting.Ip}:{setting.Port}/{setting.BaseUrl}/daws/{LoginUser.CurrentUser?.id}"), default);
                socket = ws;
                ReadMsg();
                StartHeartbeat();
                StartHeartbeat();*/
            }
            catch (Exception ex)
            {
                await ConnectWebSocket();
                Logger.Error("Connect Websocket Failed.", ex);
                ShowStatus("Error", "与服务连接连接失败,尝试重连...");
            }
        }
        private void ReadMsg()
        private void Socket_OnError(object sender, ErrorEventArgs e)
        {
            Logger.Error("Websocket On Error.", e.Exception);
            //ResetSocket();
            //ConnectWebSocket();
        }
        private void Socket_OnMessage(object sender, MessageEventArgs e)
        {
            HandleMsg(e.Data);
        }
        private void Socket_OnClose(object sender, CloseEventArgs e)
        {
            Logger.Info("Websocket On Close.");
            StopHeartBeat();
        }
        private void Socket_OnOpen(object sender, EventArgs e)
        {
            Logger.Info("Websocket On Open.");
            ShowStatus("Success", "与服务器连接状态正常");
            // StartHeartBeat();
        }
        public void StartHeartBeat()
        {
            if (heartbeatTimer == null)
            {
                heartbeatTimer = new System.Timers.Timer(30 * 1000);
                heartbeatTimer.Elapsed += HeartbeatTimer_Elapsed;
                heartbeatTimer.AutoReset = true;
                heartbeatTimer.Start();
            }
        }
        private void HeartbeatTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (socket == null || !socket.IsAlive)
            {
                Logger.Error($"Websocket HeartBeat Error. Socket is NULL:{socket == null}; IsAlive:{socket.IsAlive}");
                ShowStatus("Error", "与服务器通讯中断,正在尝试重连...");
                ResetSocket();
                ConnectWebSocket();
            }
            else
            {
                socket.Send("HeartBeat");
            }
        }
        public void StopHeartBeat()
        {
        }
        /*private void ReadMsg()
        {
            readTask = Task.Run(() =>
            {
                while (socket.State == WebSocketState.Open)
                while (socket.State == WebSocketState.Open && !cancelToken.IsCancellationRequested)
                {
                    byte[] buffer = new byte[1024];
                    var task = socket.ReceiveAsync(new ArraySegment<byte>(buffer), default);
@@ -119,9 +303,10 @@
                    var res = task.Result;
                    var msg = Encoding.UTF8.GetString(buffer, 0, res.Count);
                    HandleMsg(msg);
                    Thread.Sleep(100);
                }
            });
        }
            }, cancelToken);
        }*/
        private void HandleMsg(string msg)
        {
@@ -129,35 +314,39 @@
            {
                return;
            }
            Debug.WriteLine(msg);
            Dispatcher.Invoke(() =>
            {
                eDesktopAlertColor color = eDesktopAlertColor.Default;
                eAlertPosition position = eAlertPosition.BottomRight;
                DesktopAlert.Show(msg, "\uf005", eSymbolSet.Awesome, Color.Empty, color, position, 5,
                    DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), AlertClicked);
                Refresh_Click(null, null);
            });
        }
        private void StartHeartbeat()
        public void ResetSocket()
        {
            heartbeatTimer = new System.Timers.Timer(30 * 1000);
            heartbeatTimer.Elapsed += HeartbeatTimer_Elapsed;
            heartbeatTimer.AutoReset = true;
            heartbeatTimer.Start();
        }
        private void HeartbeatTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (socket == null || socket.State != WebSocketState.Open)
            if (readTask != null)
            {
                DoDispose();
                ConnectWebSocket().Wait();
                cancelTokenSource.Cancel();
                readTask = null;
            }
            else
            if (socket != null)
            {
                byte[] buffer = Encoding.UTF8.GetBytes("test");
                socket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, default);
                using (var _socketServer = socket)
                {
                    try
                    {
                        _socketServer.Close();
                        socket = null;
                        /*socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "DoDispose", default).Wait();
                        socket.Dispose();*/
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("Websocket Close Error.", ex);
                    }
                }
            }
        }
@@ -169,25 +358,13 @@
                heartbeatTimer.Dispose();
                heartbeatTimer = null;
            }
            if (readTask != null)
            {
                readTask.Dispose();
                readTask = null;
            }
            if (socket != null)
            {
                try
                {
                    socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "DoDispose", default).Wait();
                    socket.Dispose();
                }
                catch (Exception ex)
                {
            ResetSocket();
                }
                finally
            if (client != null)
            {
                using (var _client = client)
                {
                    socket = null;
                    client = null;
                }
            }
        }
@@ -201,5 +378,56 @@
        {
            this.Hide();
        }
        private void ReadAll_Click(object sender, RoutedEventArgs e)
        {
            MaskAdorner.ShowMask(mainContent);
            Task.Run(() =>
            {
                try
                {
                    Result<object> res = client.PutSyncAction<object>("pdm/sysAnnouncementSend/readAll");
                    _ = res.HandleResult();
                    RefreshData();
                }
                catch (Exception ex)
                {
                    Logger.Error("Read All Fail.", ex);
                }
                finally
                {
                    MaskAdorner.HideMask(mainContent);
                }
            });
        }
        private void SingleRead_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            MsgData msg = button.DataContext as MsgData;
            if (msg == null) return;
            MaskAdorner.ShowMask(mainContent);
            Task.Run(() =>
            {
                try
                {
                    Result<object> res = client.PutSyncAction<object>("pdm/sysAnnouncementSend/editByAnntIdAndUserId", new MsgData
                    {
                        anntId = msg.id
                    });
                    _ = res.HandleResult();
                    RefreshData();
                }
                catch (Exception ex)
                {
                    Logger.Error("Read All Fail.", ex);
                }
                finally
                {
                    MaskAdorner.HideMask(mainContent);
                }
            });
        }
    }
}