using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading.Tasks; namespace Seyounth.Auto.Hs.Runtime.Scanner { /// /// 料箱扫码枪 /// public class BoxScanner : IScanner { public int Id => 2; //扫到码后的业务逻辑 public event Action OnScanned; private DeviceConnectConfig DeviceConnectConfig; private TcpClient _tcp; //字节流、可以理解为后端与扫码枪之间的一条管道,扫码枪的数据就是通过这条管道发送给我们的 private NetworkStream _stream; private readonly ILogger logger; private CancellationTokenSource _receiveDataCancellationToken; public BoxScanner(IConfiguration configuration, ILogger logger) { /* * 从配置文件获取扫码枪IP/端口 */ var configs = configuration.GetSection("Scanner").Get(); if (configs is not null && configs.Length > 0) { DeviceConnectConfig = configs.FirstOrDefault(e => e.Id == Id); } this.logger = logger; } /// /// 连接扫码枪 /// /// public async Task ConnectAsync() { if (_tcp is not null) { try { _tcp.Dispose(); } catch (Exception ex) { /* * 忽略释放异常 */ } } _tcp = new TcpClient(); try { await _tcp.ConnectAsync(new IPEndPoint(IPAddress.Parse(DeviceConnectConfig.IP), DeviceConnectConfig.Port)) .ContinueWith((task, obj) => { if (task.IsCompletedSuccessfully) { if (_stream is not null) _stream.Dispose(); _stream = _tcp.GetStream(); logger.LogInformation("箱扫码枪连接成功,开始接收数据"); _receiveDataCancellationToken = new CancellationTokenSource(); Task.Factory.StartNew(() => ReceiveData(_receiveDataCancellationToken.Token), _receiveDataCancellationToken.Token); } }, null); } catch (Exception ex) { logger.LogError(ex, "箱扫码枪连接失败"); } } /// /// 接收扫码枪数据 /// /// private void ReceiveData(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { //一次最大读取1M byte[] buffer = new byte[1024]; /* readCount :实际读取字节数*/ var readCount = _stream.Read(buffer, 0, buffer.Length); /* UTF-8 编码获取字符串*/ var result = Encoding.UTF8.GetString(buffer, 0, readCount); logger.LogInformation($"箱扫码枪接收数据:{result},字节数:{readCount}"); /* 异步执行所有事件避免事件中报错未能执行完成所有事件而阻塞下次接收 */ Task.Run(() => OnScanned?.Invoke(result)); } } /// /// 断开连接 /// /// public Task DisconnectAsync() { _receiveDataCancellationToken.Cancel(); _tcp?.Dispose(); return Task.CompletedTask; } } }