LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

大揭秘!.Net如何在5分钟内快速实现物联网扫码器通用扫码功能?

freeflydom
2024年5月30日 15:47 本文热度 219

不管你是用.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"); // 扫码器IP

clientInfo.Port = 3000; // 扫码器端口号

clientInfo.Count = 3;  // 没扫到码重试次数

clientInfo.SendTimeOut = 3000; // 请求超时 毫秒

clientInfo.ReceiveTimeOut = 3000; // 接收扫码内容超时 毫秒

clientInfo.Brand = "SR"; // 扫码器品牌

clientInfo.Command = "CMD"; // 扫码器触发指令,指令可通过各个扫码器厂家提供的配置软件,配置为通用的

clientInfo.ReaderNo = 1;  // 扫码器编号,可自定义,例如有10个,就可以配置1-10号

clientInfo.CloseCommand = ""; // 停止触发指令,如果没有则默认空字符串即可


ReaderResultInfo res = reader.ReaderConnection(ref clientInfo); // 通信连接,连接扫码器服务端,参数返回客户端实例 以及 标准返回值类型ReaderResultInfo


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)

     {

         // 创建一个StringBuilder对象用于存储返回的结果信息

         var result = new StringBuilder();

         try

         {

             if (clientInfos == null || clientInfos.Count == 0)

             {

                 return Ok("没有可用客户连接信息"); // No available client connection info.

             }


             // 为全局静态数组分配空间

             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]); // 假设第一个客户端已连接。下标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());

     }

 }

其他介绍:扫码器配置参数和通用返回值参数对应实体类说明。

扫码器客户端配置实体类:

/// <summary>

/// Represents the client configuration for a scanner.

/// 表示扫描器的客户端配置。

/// </summary>

public class ReaderClientInfo

{

    /// <summary>

    /// The IP address of the scanner.

    /// 扫描器的IP地址。

    /// </summary>

    public IPAddress Ip { get; set; }


    /// <summary>

    /// The port number for the scanner connection.

    /// 扫描器连接的端口号。

    /// </summary>

    public int Port { get; set; }


    /// <summary>

    /// Number of retry attempts if no code is scanned.

    /// 如果没有扫描到码的重试次数。

    /// </summary>

    public short Count { get; set; }


    /// <summary>

    /// The socket connection to the scanner.

    /// 扫描器的Socket连接。

    /// </summary>

    public Socket Client { get; set; }


    /// <summary>

    /// The identifier number of the scanner.

    /// 扫描器的编号。

    /// </summary>

    public ushort ReaderNo { get; set; }


    /// <summary>

    /// Timeout in milliseconds for sending requests.

    /// 发送请求的超时时间(毫秒)。

    /// </summary>

    public int SendTimeOut { get; set; } = 3000;


    /// <summary>

    /// Timeout in milliseconds for receiving responses.

    /// 接收响应的超时时间(毫秒)。

    /// </summary>

    public int ReceiveTimeOut { get; set; } = 3000;


    /// <summary>

    /// The brand of the scanner, such as Keyence, Cognex, OPT, etc.

    /// 扫描器的品牌,例如基恩士、康耐视、OPT等等。

    /// </summary>

    public string Brand { get; set; }


    /// <summary>

    /// Command to trigger the scan.

    /// 触发扫描的命令。

    /// </summary>

    public string Command { get; set; }


    /// <summary>

    /// Command to stop triggering the scanner (used by Keyence).

    /// 停止触发扫描器的命令(基恩士使用)。

    /// </summary>

    public string CloseCommand { get; set; }


    /// <summary>

    /// Start character for commands, if applicable (empty string if none).

    /// 命令的起始字符(如果有),没有则为空字符串。

    /// </summary>

    public string Start { get; set; } = string.Empty;


    /// <summary>

    /// End character for commands, such as '\r\n' for Keyence; empty if not used.

    /// 命令的结束字符,如基恩士使用的'\r\n';如果不使用则为空字符串。

    /// </summary>

    public string End { get; set; } = string.Empty;

}

返回值实体类:

/// <summary>

/// Represents the result information from a scanner.

/// 表示扫描器的结果信息。

/// </summary>

public class ReaderResultInfo

{

/// <summary>

/// Indicates whether the scan was successful.

/// 指示扫描是否成功。

/// </summary>

public bool IsSucceed { get; set; } = false;


/// <summary>

/// The error message if the scan failed.

/// 如果扫描失败,错误信息。

/// </summary>

public string Message { get; set; } = string.Empty;


/// <summary>

/// The result of the scan.

/// 扫描结果。

/// </summary>

public string Value { get; set; } = string.Empty;


/// <summary>

/// The time taken for the scan in milliseconds.

/// 扫描所耗费的时间(毫秒)。

/// </summary>

public long ElapsedMilliseconds { get; set; } = 0;


/// <summary>

/// The number identifying the scanner.

/// 扫描器编号。

/// </summary>

public ushort ReaderNo { get; set; } = 0;


/// <summary>

/// The brand of the scanner.

/// 扫描器品牌。

/// </summary>

public string Brand { get; set; } = string.Empty;

}


转自微信公众号Dotnet Dancer


该文章在 2024/5/30 15:50:12 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved