176 lines
5.5 KiB
C#
176 lines
5.5 KiB
C#
|
|
using MegaRobo.Connections;
|
|||
|
|
using MegaRobo.Contract;
|
|||
|
|
using MegaRobo.ControlDevices.Abstractions;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Diagnostics;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
|
|||
|
|
namespace MegaRobo.C00225155.ControlDevices.USBScanner
|
|||
|
|
{
|
|||
|
|
public class USBScannerService : ConnectorBase
|
|||
|
|
{
|
|||
|
|
public SerialPortService MegaSerialPort { get; set; }
|
|||
|
|
|
|||
|
|
public bool IsConnected => this.MegaSerialPort?.IsOpen ?? false;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 扫描仪数据接收事件(外部可订阅,实时获取串口数据)
|
|||
|
|
/// </summary>
|
|||
|
|
public event EventHandler<Message> ScannerDataReceived;
|
|||
|
|
|
|||
|
|
#region Base
|
|||
|
|
public override async Task<string> Initialize(ICoreService coreService, params object[] args)
|
|||
|
|
{
|
|||
|
|
await Task.Delay(0);
|
|||
|
|
this.CoreService = coreService;
|
|||
|
|
if (args != null && args.Length > 0 && args[0] is string portName)
|
|||
|
|
{
|
|||
|
|
this.SetConnection(portName);
|
|||
|
|
}
|
|||
|
|
//else
|
|||
|
|
//{
|
|||
|
|
// throw new ArgumentException("初始化失败:未传入有效的串口名称(portName)");
|
|||
|
|
//}
|
|||
|
|
return string.Empty;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
private void SetConnection(string portName)
|
|||
|
|
{
|
|||
|
|
// 若已有串口实例,先断开并清理
|
|||
|
|
if (MegaSerialPort != null)
|
|||
|
|
{
|
|||
|
|
Disconnect();
|
|||
|
|
}
|
|||
|
|
this.MegaSerialPort = new SerialPortService(portName);
|
|||
|
|
this.Connection();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public string Connection()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (MegaSerialPort != null && !MegaSerialPort.IsOpen)
|
|||
|
|
{
|
|||
|
|
this.MegaSerialPort.Open();
|
|||
|
|
// 2. 连接成功后订阅串口DataReceived事件(先取消再订阅,防止重复)
|
|||
|
|
MegaSerialPort.DataReceived -= MegaSerialPort_DataReceived; // 取消旧订阅
|
|||
|
|
MegaSerialPort.DataReceived += MegaSerialPort_DataReceived; // 新订阅
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
return ex.Message;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return this.MegaSerialPort.IsOpen ? null : "连接异常";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Task<string> ConnectionAsync()
|
|||
|
|
{
|
|||
|
|
return Task.Run(this.Connection);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public bool Disconnect()
|
|||
|
|
{
|
|||
|
|
if (MegaSerialPort != null)
|
|||
|
|
{
|
|||
|
|
// 3. 断开连接前取消事件订阅(避免内存泄漏)
|
|||
|
|
MegaSerialPort.DataReceived -= MegaSerialPort_DataReceived;
|
|||
|
|
MegaSerialPort.Dispose(); // 触发SerialPortService的Close和资源释放
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Dispose()
|
|||
|
|
{
|
|||
|
|
this.Disconnect();
|
|||
|
|
this.MegaSerialPort = null;
|
|||
|
|
}
|
|||
|
|
#endregion Base
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 串口DataReceived事件的处理方法(自动触发)
|
|||
|
|
/// </summary>
|
|||
|
|
private void MegaSerialPort_DataReceived(object sender, Message msg)
|
|||
|
|
{
|
|||
|
|
if (msg == null || msg.Data == null || msg.Data.Length == 0)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
string receivedData = msg.ReadString(SerialPortDataFormat.Char); // 用串口配置的格式解析
|
|||
|
|
|
|||
|
|
// --------------------------
|
|||
|
|
// 步骤2:对外透传数据(触发自定义事件)
|
|||
|
|
// 外部订阅ScannerDataReceived即可实时获取数据
|
|||
|
|
// --------------------------
|
|||
|
|
OnScannerDataReceived(msg);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 触发自定义事件(线程安全的事件触发方式)
|
|||
|
|
/// </summary>
|
|||
|
|
protected virtual void OnScannerDataReceived(Message msg)
|
|||
|
|
{
|
|||
|
|
// 临时保存事件引用,避免多线程下事件被注销后为空
|
|||
|
|
var handler = ScannerDataReceived;
|
|||
|
|
handler?.Invoke(this, msg);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public string SendAndReceive(string cmd, TimeSpan timeout)
|
|||
|
|
{
|
|||
|
|
string mReply = string.Empty;
|
|||
|
|
EventHandler<Message> tempHandler = (sender, msg) =>
|
|||
|
|
{
|
|||
|
|
mReply = msg.ReadString(SerialPortDataFormat.Char);
|
|||
|
|
};
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
MegaSerialPort.DataReceived += tempHandler;
|
|||
|
|
MegaSerialPort.WriteLine(cmd);
|
|||
|
|
Stopwatch stopwatch = Stopwatch.StartNew();
|
|||
|
|
while (string.IsNullOrEmpty(mReply) && stopwatch.Elapsed < timeout)
|
|||
|
|
{
|
|||
|
|
Thread.Sleep(50);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
MegaSerialPort.DataReceived -= tempHandler;
|
|||
|
|
}
|
|||
|
|
return mReply;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public override async Task<ConnectionState> CheckConnected()
|
|||
|
|
{
|
|||
|
|
await Task.Delay(0);
|
|||
|
|
if (this.MegaSerialPort.IsOpen)
|
|||
|
|
{
|
|||
|
|
return ConnectionState.IsConnected;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return ConnectionState.NotConnected;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public override async Task<ConnectionState> ReconnectAsync()
|
|||
|
|
{
|
|||
|
|
await Task.Delay(0);
|
|||
|
|
if (string.IsNullOrEmpty(await ConnectionAsync()))
|
|||
|
|
{
|
|||
|
|
return ConnectionState.IsConnected;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return ConnectionState.NotConnected;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|