赞
踩
由于工作的原因经常需要用到一些socket,串口等调试工具,但是好多工具要么只有其中几个或者各种收费,不断提醒捐助等。所以还是自己做一个吧。毕竟也不复杂。今天先做个WebSocket客户端。WebSocket使用了开源组件WatsonWebsocket。
<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>
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 } }
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); } } }
其他的代码就不列出来了,见代码仓库
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。