不管你是用.net framework还是用.net core或者更高版本.net环境,这篇文章也许都能帮到你!因为接下来我会提供一个简单粗暴的方式,来快速实现多款扫码器的通用扫码功能。目前本地测试过的包括基恩士系列、康耐视系列、以及其他支持以太网通信的多款小众厂家等。
下面开始重点操作:
首先,在你的项目里面引用Wesky.Net.OpenTools 包,1.0.7以及以上版本均可。

如果你是在.netframework环境下面开放,或者是没有使用依赖注入的项目中使用,使用方式可以直接new一个对象来使用,有关使用如下代码:
ICodeReader reader = new CodeReader();
ReaderClientInfo clientInfo = new ReaderClientInfo();
clientInfo.Ip = IPAddress.Parse("192.168.1.102");
clientInfo.Port = 3000;
clientInfo.Count = 3;
clientInfo.SendTimeOut = 3000;
clientInfo.ReceiveTimeOut = 3000;
clientInfo.Brand = "SR";
clientInfo.Command = "CMD";
clientInfo.ReaderNo = 1;
clientInfo.CloseCommand = "";
ReaderResultInfo res = reader.ReaderConnection(ref clientInfo);
if (!res.IsSucceed)
{
Console.WriteLine($"与扫码器建立通信连接失败:{res.Message}");
return;
}
res = reader.ReaderRead(ref clientInfo);
if (!res.IsSucceed)
{
Console.WriteLine($"扫码异常:{res.Message}");
return;
}
else
{
Console.WriteLine($"扫到码:{res.Value} 扫码耗时:{res.ElapsedMilliseconds}");
}
当然,强烈建议你们的项目使用.net core或以上环境。毕竟.net core是开源的,还可以跨平台,不管你是在Windows运行还是在Linux,都可以运行。
下面是在.net core或以上环境下的使用。例如我新建一个.net 8的webapi项目,
对ICodeReader接口和CodeReader类进行依赖注入的注册,建议使用瞬时生命周期,可以提高多个扫码器同时存在时的并发扫码效率。
例如:builder.Services.AddTransient<ICodeReader, CodeReader>();
建议新建一个全局实体类属性,用于存储扫码器的所有客户端实例,用于保持实例长连接。
例如:
public class ReaderClients
{
public static ReaderClientInfo[] Clients { get; set; }=new ReaderClientInfo[0];
}

扫码器服务注入和使用.此处为了方便,我直接创建一个api控制器来演示,并对ICodeReader进行了构造函数注入。大佬们请自行根据实际情况进行操作。

假设有一个方法,或者接口等,传入一批扫码设备的配置信息,例如配置文件读取、数据库读取、或者其他任意方式配置的扫码器集合信息,传给连接接口或者方法等。然后根据传入的配置信息,进行对每个设备通信连接:

访问扫码函数,进行触发扫码操作。以下案例仅供参考,请根据个人实际情况进行优化或者修改。例如修改扫码次数、扫码成功或失败的其他处理等等。

控制器内所有代码如下:
public class ScannerController : ControllerBase
{
private readonly ICodeReader _reader;
public ScannerController(ICodeReader reader)
{
_reader = reader;
}
[HttpPost]
public IActionResult Connection([FromBody] List<ReaderClientInfo> clientInfos)
{
var result = new StringBuilder();
try
{
if (clientInfos == null || clientInfos.Count == 0)
{
return Ok("没有可用客户连接信息");
}
ReaderClients.Clients = new ReaderClientInfo[clientInfos.Count];
for (int i = 0; i < clientInfos.Count; i++)
{
var clientInfo = clientInfos[i];
var res = _reader.ReaderConnection(ref clientInfo);
if (res.IsSucceed)
{
result.AppendLine($"{DateTime.Now:yyyy/MM/dd HH:mm:ss}>>>与扫码器设备通信连接成功:{res.Message}");
}
else
{
ReaderClients.Clients[i] = clientInfo;
result.AppendLine($"{DateTime.Now:yyyy/MM/dd HH:mm:ss}>>>通信连接失败");
}
}
return Ok(result.ToString());
}
catch (Exception ex)
{
return Ok($"{DateTime.Now:yyyy/MM/dd HH:mm:ss}>>>通信连接失败: {ex.Message}");
}
}
[HttpPost]
public IActionResult BeginScanner(int count)
{
const string timeFormat = "yyyy/MM/dd HH:mm:ss";
StringBuilder result = new StringBuilder();
if (ReaderClients.Clients == null || !ReaderClients.Clients.Any())
{
return Ok($"{DateTime.Now.ToString(timeFormat)} >>> 没有可连接的扫码器客户端,无法启动扫描功能。");
}
try
{
for (int now = 1; now <= count; now++)
{
var res = _reader.ReaderRead(ref ReaderClients.Clients[0]);
if (res.IsSucceed)
{
result.AppendLine($"{DateTime.Now.ToString(timeFormat)} >>> 第{now}次扫码,扫码结果:{res.Message}");
}
else
{
result.AppendLine($"{DateTime.Now.ToString(timeFormat)} >>> 第{now}次扫码,扫码失败:{res.Value} 扫码耗时:{res.ElapsedMilliseconds}毫秒");
}
}
}
catch (Exception ex)
{
result.AppendLine($"{DateTime.Now.ToString(timeFormat)} >>> 扫码异常:{ex.Message}");
}
return Ok(result.ToString());
}
}
其他介绍:扫码器配置参数和通用返回值参数对应实体类说明。
扫码器客户端配置实体类:
public class ReaderClientInfo
{
public IPAddress Ip { get; set; }
public int Port { get; set; }
public short Count { get; set; }
public Socket Client { get; set; }
public ushort ReaderNo { get; set; }
public int SendTimeOut { get; set; } = 3000;
public int ReceiveTimeOut { get; set; } = 3000;
public string Brand { get; set; }
public string Command { get; set; }
public string CloseCommand { get; set; }
public string Start { get; set; } = string.Empty;
public string End { get; set; } = string.Empty;
}
返回值实体类:
public class ReaderResultInfo
{
public bool IsSucceed { get; set; } = false;
public string Message { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
public long ElapsedMilliseconds { get; set; } = 0;
public ushort ReaderNo { get; set; } = 0;
public string Brand { get; set; } = string.Empty;
}
转自微信公众号Dotnet Dancer
该文章在 2024/5/30 15:50:12 编辑过