由于工作的原因经常需要用到一些socket,串口等调试工具,但是好多工具要么只有其中几个或者各种收费,不断提醒捐助等。所以还是自己做一个吧。毕竟也不复杂。今天先做个WebSocket客户端。WebSocket使用了开源组件WatsonWebsocket。文章来源:https://www.toymoban.com/news/detail-552468.html
- 先上图
- View的代码
<local:PageWithId x:Class="ToolsAssistant.Views.WebSocketClientView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ToolsAssistant.Views" xmlns:viewmodels="clr-namespace:ToolsAssistant.ViewModels" d:DataContext="{d:DesignInstance Type=viewmodels:WebSocketClientViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Unloaded="Page_Unloaded" Loaded="Page_Loaded"
Title="WebServerClientView" Background="White">
<Grid>
<Grid.Resources>
<Style x:Key="btn_style" TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding Content, ElementName=btn_connect}" Value="连接">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding Content, ElementName=btn_connect}" Value="断开">
<Setter Property="IsEnabled" Value="true"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="radio_style" TargetType="RadioButton">
<Style.Triggers>
<DataTrigger Binding="{Binding Content, ElementName=btn_connect}" Value="连接">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding Content, ElementName=btn_connect}" Value="断开">
<Setter Property="IsEnabled" Value="true"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border BorderThickness="1" BorderBrush="Gray" Margin="3" CornerRadius="5" Grid.Row="0">
<StackPanel Orientation="Horizontal">
<Label Content="ws://" Margin="3" VerticalContentAlignment="Center"></Label>
<TextBox Text="{Binding Url}" Margin="3" Width="200" VerticalContentAlignment="Center"/>
<Button x:Name="btn_connect" Margin="3" Content="{Binding ConnectString}" Width="60" Command="{Binding ConnectCommand}">
</Button>
</StackPanel>
</Border>
<Border BorderThickness="1" BorderBrush="Gray" Margin="3" CornerRadius="5" Grid.Row="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button Content="发送" Command="{Binding SendCommand}" Width="60" Margin="3" Style="{StaticResource btn_style}">
</Button>
<Button Content="清空" Command="{Binding ClearSendCommand}" Width="60" Margin="3" Style="{StaticResource btn_style}"/>
<RadioButton Content="UTF8" Margin="3" VerticalContentAlignment="Center" IsChecked="{Binding IsUTF8}" Style="{StaticResource radio_style}"/>
<RadioButton Content="ASCII" Margin="3" VerticalContentAlignment="Center" IsChecked="{Binding IsASCII}" Style="{StaticResource radio_style}" />
<RadioButton Content="HEX" Margin="3" VerticalContentAlignment="Center" IsChecked="{Binding IsHex}" Style="{StaticResource radio_style}"/>
</StackPanel>
<ScrollViewer Grid.Row="1" Margin="3">
<TextBox Text="{Binding SendStr}"></TextBox>
</ScrollViewer>
</Grid>
</Border>
<Border BorderThickness="1" BorderBrush="Gray" Margin="3" CornerRadius="5" Grid.Row="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button Content="清空" Command="{Binding ClearRecieveCommand}" Width="60" Margin="3" Style="{StaticResource btn_style}"/>
<RadioButton Content="UTF8" Margin="3" VerticalContentAlignment="Center" IsChecked="{Binding IsUTF8}" Style="{StaticResource radio_style}"/>
<RadioButton Content="ASCII" Margin="3" VerticalContentAlignment="Center" IsChecked="{Binding IsASCII}" Style="{StaticResource radio_style}"/>
<RadioButton Content="HEX" Margin="3" VerticalContentAlignment="Center" IsChecked="{Binding IsHex}" Style="{StaticResource radio_style}"/>
</StackPanel>
<ScrollViewer Grid.Row="1" Margin="3">
<TextBox Text="{Binding RecieveStr}"></TextBox>
</ScrollViewer>
</Grid>
</Border>
</Grid>
</local:PageWithId>
- ViewModel的代码
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using ToolsAssistant.Services;
namespace ToolsAssistant.ViewModels
{
public class WebSocketClientViewModel: ObservableObject
{
#region props
private string _ConnectString = "连接";
public string ConnectString { set => SetProperty(ref _ConnectString, value); get => _ConnectString; }
private string _SendStr;
public string SendStr { set => SetProperty(ref _SendStr, value); get => _SendStr; }
private string _RecieveStr;
public string RecieveStr { set => SetProperty(ref _RecieveStr, value); get => _RecieveStr; }
private bool _IsUTF8 = true;
public bool IsUTF8 {
set
{
SetProperty(ref _IsUTF8, value);
InitEncoder();
}
get => _IsUTF8; }
private bool _IsASCII = false;
public bool IsASCII {
set
{
SetProperty(ref _IsASCII, value);
InitEncoder();
}
get => _IsASCII; }
private bool _IsHex = false;
public bool IsHex {
set
{
SetProperty(ref _IsHex, value);
InitEncoder();
}
get => _IsHex; }
private string _Url = "127.0.0.1:8888";
public string Url { set => SetProperty(ref _Url, value); get => _Url; }
#endregion
#region commands
public RelayCommand SendCommand { set; get; }
public RelayCommand ClearSendCommand { set; get; }
public RelayCommand ClearRecieveCommand { set; get; }
public RelayCommand ConnectCommand { set; get; }
#endregion
#region methods
protected readonly ILogger<WebSocketClientViewModel> _logger;
protected readonly IWebSocketClient _client;
public WebSocketClientViewModel()
{
_logger = App.Current.Services.GetService<ILogger<WebSocketClientViewModel>>();
_client = App.Current.Services.GetService<IWebSocketClient>();
Init();
}
private void Init()
{
SendCommand = new RelayCommand(OnSendCommand);
ClearSendCommand = new RelayCommand(OnClearSendCommand);
ClearRecieveCommand = new RelayCommand(OnClearRecieveCommand);
ConnectCommand = new RelayCommand(OnConnectCommand);
_client.ConnectEvent += ConnectEvent;
}
private void InitEncoder()
{
if(IsUTF8)
{
_client.SetEncording(EncordingType.Utf8);
}
if (IsASCII)
{
_client.SetEncording(EncordingType.ASCII);
}
if (IsHex)
{
_client.SetEncording(EncordingType.Hex);
}
}
private void ConnectEvent(string ipPort, bool isConnect)
{
if(isConnect)
{
ConnectString = "断开";
InitEncoder();
}
else
{
ConnectString = "连接";
}
}
private void OnConnectCommand()
{
try
{
if(ConnectString == "连接")
{
_client.Connect(Url);
}
else
{
_client.Disconnect();
}
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
MessageBox.Show(ex.ToString());
}
}
private void OnClearRecieveCommand()
{
try
{
RecieveStr = "";
}catch(Exception ex)
{
_logger.LogError(ex.ToString());
MessageBox.Show(ex.ToString());
}
}
private void OnClearSendCommand()
{
try
{
SendStr = "";
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
MessageBox.Show(ex.ToString());
}
}
private void OnSendCommand()
{
try
{
if(string.IsNullOrEmpty(SendStr))
{
throw new Exception("发送内容不允许为空");
}
_client.SendData(SendStr);
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
MessageBox.Show(ex.ToString());
}
}
#endregion
}
}
- servervice的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using WatsonWebsocket;
namespace ToolsAssistant.Services
{
internal class WebSocketClient : IWebSocketClient
{
private WatsonWsClient _client = null;
private EncordingType _encordingType = EncordingType.Utf8;
public event EventHandlers.DataRecievedEventHandler DataRecievedEvent;
public event EventHandlers.ConnectEventHandler ConnectEvent;
public void Connect(string ipPort)
{
if(_client == null||!_client.Connected)
{
_client = new WatsonWsClient(new Uri($"ws://{ipPort}"));
}else
{
_client.Stop();
_client = new WatsonWsClient(new Uri($"ws://{ipPort}"));
}
_client.ServerConnected += ServerConnected;
_client.MessageReceived += MessageReceived;
_client.ServerDisconnected += ServerDisconnected;
_client.Start();
}
private void ServerDisconnected(object sender, EventArgs e)
{
ConnectEvent?.Invoke(null, false);
}
private void MessageReceived(object sender, MessageReceivedEventArgs e)
{
try
{
string data = "";
switch(_encordingType)
{
case EncordingType.Utf8:
data = Encoding.UTF8.GetString(e.Data);
break;
case EncordingType.ASCII:
data = Encoding.ASCII.GetString(e.Data);
break;
case EncordingType.Hex:
for(int i=0;i<e.Data.Length;i++)
{
data += Convert.ToString(e.Data[i],16)+" ";
}
break;
}
DataRecievedEvent?.Invoke(e.IpPort,data);
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void ServerConnected(object sender, EventArgs e)
{
ConnectEvent?.Invoke(null, true);
}
public void Disconnect()
{
if(_client.Connected)
{
_client.Stop();
ConnectEvent?.Invoke(null, false);
}
}
public void SetEncording(EncordingType encordingType)
{
_encordingType = encordingType;
}
public void SendData(string data)
{
byte[] dataBytes;
switch (_encordingType)
{
case EncordingType.ASCII:
dataBytes = Encoding.ASCII.GetBytes(data.Replace(" ",""));
break;
case EncordingType.Hex:
var lst = data.Split(" ");
dataBytes = new byte[lst.Length];
for (int i = 0; i < lst.Length; i++)
{
dataBytes[i] = Convert.ToByte(lst[i], 16);
}
break;
default: //EncordingType.Utf8
dataBytes = Encoding.UTF8.GetBytes(data);
break;
}
_client.SendAsync(dataBytes);
}
}
}
其他的代码就不列出来了,见代码仓库文章来源地址https://www.toymoban.com/news/detail-552468.html
到了这里,关于做个小工具-WebSocket客户端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!