WebSocketTool/WebSocketTool/Client/ClientViewModel.cs
2022-08-31 10:33:30 +08:00

323 lines
9.0 KiB
C#

using System;
using System.Net.Security;
using System.Timers;
using log4net;
using WebSocketSharp;
using WebSocketTool.Base;
using WebSocketTool.Util;
using LogManager = log4net.LogManager;
namespace WebSocketTool.Client
{
public class ClientViewModel : BaseViewModel
{
private static readonly ILog Log = LogManager.GetLogger(nameof(ClientViewModel));
private readonly IClientView view;
private SocketClient mClient;
public ClientViewModel(IClientView view)
{
this.view = view;
}
private string mWsUrl;
public string WsUrl
{
get => mWsUrl;
set
{
mWsUrl = value;
RaisePropertyChanged(nameof(WsUrl));
}
}
private string mSendContent = string.Empty;
public string SendContent
{
get => mSendContent;
set
{
mSendContent = value;
RaisePropertyChanged(nameof(SendContent));
}
}
private long mPingTime = 1000;
public long PingTime
{
get => mPingTime;
set
{
mPingTime = value;
RaisePropertyChanged(nameof(PingTime));
}
}
#region Proxy
private string proxyAddress;
private string proxyUserName;
private string proxyPassword;
public string ProxyAddress
{
get => proxyAddress;
set
{
proxyAddress = value;
RaisePropertyChanged(nameof(ProxyAddress));
}
}
public string ProxyUserName
{
get => proxyUserName;
set
{
proxyUserName = value;
RaisePropertyChanged(nameof(ProxyUserName));
}
}
public string ProxyPassword
{
get => proxyPassword;
set
{
proxyPassword = value;
RaisePropertyChanged(nameof(ProxyPassword));
}
}
private bool isProxyChecked;
public bool IsProxyChecked
{
get => isProxyChecked;
set
{
isProxyChecked = value;
RaisePropertyChanged(nameof(IsProxyChecked));
}
}
#endregion
public void Connect()
{
if (string.IsNullOrEmpty(WsUrl))
{
view.AppendInfo($"Hint {TimeUtil.GetCurrentDateTime()} \n 请输入正确的WebSocket地址");
return;
}
if (mClient == null)
{
InitSocketClient();
}
if (mClient.IsAlive())
{
view.AppendInfo($"Hint {TimeUtil.GetCurrentDateTime()} \n WebSocket已连接,请先断开上次连接");
return;
}
view.AppendInfo($"Hint {TimeUtil.GetCurrentDateTime()} \n Start Connect Socket");
if (IsProxyChecked)
{
view.AppendInfo($"use proxy: {ProxyAddress}");
mClient.SetHttpProxy(ProxyAddress, ProxyUserName, ProxyPassword);
}
mClient.ConnectAsync();
}
public void Send()
{
view.AppendInfo($"You {TimeUtil.GetCurrentDateTime()} \n {SendContent}");
mClient.Send(SendContent);
}
private bool mIsAlive = false;
private bool mIsConnectEnable = true;
public bool IsConnectEnable
{
get => mIsConnectEnable;
set
{
mIsConnectEnable = value;
RaisePropertyChanged(nameof(IsConnectEnable));
}
}
private bool mIsCloseEnable = false;
public bool IsCloseEnable
{
get => mIsCloseEnable;
set
{
mIsCloseEnable = value;
RaisePropertyChanged(nameof(IsCloseEnable));
}
}
private bool mIsPingChecked;
public bool IsPingChecked
{
get => mIsPingChecked;
set
{
mIsPingChecked = value;
RaisePropertyChanged(nameof(IsPingChecked));
}
}
private bool mIsPingEnable;
public bool IsPingEnable
{
get => mIsPingEnable;
set
{
mIsPingEnable = value;
RaisePropertyChanged(nameof(IsPingEnable));
}
}
public void Close()
{
view.AppendInfo($"Hint {TimeUtil.GetCurrentDateTime()} \n Start Close Socket");
mClient?.CloseAsync();
}
private Timer pingTimer;
public void StartPing()
{
if (!mIsAlive)
{
view.AppendInfo("start ping failure: ws is not connected");
return;
}
if (PingTime <= 0)
{
view.AppendInfo("ping time interval must > 0");
return;
}
pingTimer = new Timer {Interval = PingTime, AutoReset = true};
pingTimer.Enabled = true;
pingTimer.Elapsed += (s, e) =>
{
Ping();
};
pingTimer.Start();
view.AppendInfo($"You {TimeUtil.GetCurrentDateTime()} \n StartPing, TimeSpan:{PingTime}");
}
private void Ping(string msg = null)
{
mClient.Ping(msg);
App.RunOnUIThread(() => view.AppendInfo($"You {TimeUtil.GetCurrentDateTime()} \n Send Ping:{msg}"));
}
public void StopPing()
{
view.AppendInfo($"You {TimeUtil.GetCurrentDateTime()} \n StopPing");
if (pingTimer != null)
{
pingTimer.Stop();
pingTimer = null;
}
}
private void InitSocketClient()
{
view.AppendInfo($"Hint {TimeUtil.GetCurrentDateTime()} \n InitSocketClient");
mClient = new SocketClient(WsUrl);
mClient.SetServerCertificateValidationCallback((sender, certificate, chain, errors) =>
{
App.RunOnUIThread(() => { view.AppendInfo($"ServerCertificateError:{errors}"); });
Log.Info($"error:{errors}");
Log.Info($"Issuer: {certificate.Issuer},Subject:{certificate.Subject}");
Log.Info("ChainStatus:");
foreach (var status in chain.ChainStatus)
{
Log.Info($"{status.StatusInformation}: {status}");
}
Log.Info("ChainElements:");
foreach (var element in chain.ChainElements)
{
Log.Info($"element: {element.Certificate},{element.Information}");
}
return errors == SslPolicyErrors.None;
});
mClient.OpenEvent += ClientOnOpenEvent;
mClient.CloseEvent += ClientOnCloseEvent;
mClient.ErrorEvent += ClientOnErrorEvent;
mClient.MessageEvent += ClientOnMessageEvent;
if (IsProxyChecked)
{
mClient.SetHttpProxy(ProxyAddress, ProxyUserName, ProxyPassword);
}
}
private void ClientOnMessageEvent(object sender, MessageEventArgs e)
{
App.RunOnUIThread(() =>
{
view.AppendInfo($"Server {TimeUtil.GetCurrentDateTime()} \n {e.Data}");
});
}
private void ClientOnErrorEvent(object sender, ErrorEventArgs e)
{
App.RunOnUIThread(() =>
{
view.AppendInfo($"Server {TimeUtil.GetCurrentDateTime()} \n Socket Error: {e.Message}");
SetState(false);
});
StopPing();
}
private void SetState(bool isAlive)
{
mIsAlive = isAlive;
if (isAlive)
{
IsPingEnable = true;
IsConnectEnable = false;
IsCloseEnable = true;
}
else
{
IsPingEnable = false;
if (IsPingChecked)
{
IsPingChecked = false;
}
IsConnectEnable = true;
IsCloseEnable = false;
}
}
private void ClientOnCloseEvent(object sender, CloseEventArgs e)
{
App.RunOnUIThread(() =>
{
view.AppendInfo($"Server {TimeUtil.GetCurrentDateTime()} \n Socket Closed:{e.Code}:{e.Reason}");
SetState(false);
});
StopPing();
}
private void ClientOnOpenEvent(object sender, EventArgs e)
{
App.RunOnUIThread(() =>
{
view.AppendInfo($"Server {TimeUtil.GetCurrentDateTime()} \n Socket Connected");
SetState(true);
});
}
}
}