using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace Seyounth.Auto.Hs.Runtime.Scanner { /// /// 人工扫纱扫码枪 /// public class YarnScanner : IScanner { public int Id => 1; //扫到码后的业务逻辑 public event Action OnScanned; private DeviceConnectConfig DeviceConnectConfig; private TcpClient _tcp; private NetworkStream _stream; private readonly ILogger logger; private CancellationTokenSource _receiveDataCancellationToken; public YarnScanner(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); } OnScanned += 每次扫到码后的业务逻辑; 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)); } } /// /// 把人工扫码的逻辑写这里,在这里将码返回给前端 /// /// private void 每次扫到码后的业务逻辑(string code) { } /// /// 断开连接 /// /// public Task DisconnectAsync() { _receiveDataCancellationToken.Cancel(); _tcp?.Dispose(); return Task.CompletedTask; } } }