using CommunityToolkit.Mvvm.Messaging; using Microsoft.VisualBasic; using SunlightAggregationTerminal.Models; using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Reflection.PortableExecutable; using System.Text; using System.Text.Json; using TouchSocket.Core; using TouchSocket.Sockets; namespace SunlightAggregationTerminal.Class { public class TcpServer { public static TouchSocket.Sockets.TcpClient tcpClient = new TouchSocket.Sockets.TcpClient(); public static async void Configuration(string ip, string Name, string Password, string Terminal) { DataReceived.ServerIP = ip; DataReceived.ServerName = Name; DataReceived.ServerPassword = Password; DataReceived.ServerTerminal = Terminal; await TcpClient(tcpClient, DataReceived.ServerIP); } // 引入发送锁,彻底解决连续发送导致的并发断连问题 private static readonly SemaphoreSlim _sendLock = new SemaphoreSlim(1, 1); public static async void TcpTransmit(string Dat) { var dat = new DataReceived.Person() { User = DataReceived.ServerName, Password = DataReceived.ServerPassword, IP = DataReceived.GetLocalIpSimple(), Terminal = DataReceived.ServerTerminal, Dat = Dat }; // 使用锁确保同一时间只有一个任务在发送,防止并发写入导致 Socket 异常 await _sendLock.WaitAsync(); //发送字符串数据 try { await tcpClient.SendAsync(JsonSerializer.Serialize(dat)); } catch (Exception ex) { MainThread.BeginInvokeOnMainThread(() => { Application.Current!.Windows[0].Page!.DisplayAlertAsync("错误", ex.Message.ToString(), "是"); }); } finally { _sendLock.Release(); // 释放锁 } } public static async Task TcpClient(TouchSocket.Sockets.TcpClient tcpClient, string ip) { tcpClient.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到服务器,此时已经创建socket,但是还未建立tcp tcpClient.Connected = (client, e) => { TcpServer.TcpTransmit("{\"Command\":\"Log\"}"); return EasyTask.CompletedTask; };//成功连接到服务器 tcpClient.Closing = (client, e) => {return EasyTask.CompletedTask; };//即将从服务器断开连接。此处仅主动断开才有效。 tcpClient.Closed = (client, e) => {return EasyTask.CompletedTask; };//从服务器断开连接,当连接不成功时不会触发。 #region Tcp客户端使用Received异步委托接收数据 tcpClient.Received = (client, e) => { //从服务器收到信息。但是一般byteBlock和requestInfo会根据适配器呈现不同的值。 var mes = e.Memory.Span.ToString(Encoding.UTF8); DataReceived.Received(mes); return EasyTask.CompletedTask; }; #endregion try { await tcpClient.SetupAsync(new TouchSocketConfig() .SetSingleStreamDataHandlingAdapter(() => new PeriodPackageAdapter())//以超时周期和包 .SetRemoteIPHost(ip) .ConfigurePlugins(a => { a.UseReconnection(options => { options.PollingInterval = TimeSpan.FromSeconds(5); }); })); await tcpClient.ConnectAsync();//调用连接,当连接不成功时,会抛出异常。 } catch (Exception ex) { MainThread.BeginInvokeOnMainThread(() => { Application.Current!.Windows[0].Page!.DisplayAlertAsync("网络错误", ex.Message.ToString(), "是"); }); } } } }