933 lines
35 KiB
VB.net
933 lines
35 KiB
VB.net
|
|
Imports System.Net.Sockets
|
|||
|
|
Imports System.Text
|
|||
|
|
Imports System.Threading
|
|||
|
|
Imports System.Windows.Forms
|
|||
|
|
Imports UTS_Core.UTSModule.DbConnect
|
|||
|
|
Imports UTS_Core.UTSModule.DbTableModel.Customer
|
|||
|
|
Imports UTS_Core.UTSModule.Login
|
|||
|
|
Imports UTS_Core.UTSModule.Production
|
|||
|
|
Imports UTS_Core.UTSModule.Service
|
|||
|
|
Imports UTS_Core.UTSModule.Station
|
|||
|
|
Imports UTS_Core.UTSModule.Test
|
|||
|
|
Imports UTS_Core.UTSModule.Test.StatusMonitor
|
|||
|
|
|
|||
|
|
|
|||
|
|
Namespace UTSModule
|
|||
|
|
''' <summary>
|
|||
|
|
'''UTS系列App与UtsCore交互为避免重复书写产生的中间类
|
|||
|
|
''' </summary>
|
|||
|
|
Public Class UtsAppForm
|
|||
|
|
Implements IDisposable
|
|||
|
|
|
|||
|
|
''' <summary>本地服务索引</summary>
|
|||
|
|
Private _serviceIndex As Integer
|
|||
|
|
|
|||
|
|
''' <summary>本地服务角色,0客户端,1服务器</summary>
|
|||
|
|
Private _serviceRoles As Integer
|
|||
|
|
|
|||
|
|
''' <summary>本地服务别名</summary>
|
|||
|
|
Private _serviceAlias As String
|
|||
|
|
|
|||
|
|
''' <summary>本地服务组名(子网名)</summary>
|
|||
|
|
Private _serviceGroup As String
|
|||
|
|
|
|||
|
|
''' <summary>软件名称</summary>
|
|||
|
|
Private _appName As String
|
|||
|
|
|
|||
|
|
''' <summary>软件版本</summary>
|
|||
|
|
Private _appVersion As String
|
|||
|
|
|
|||
|
|
''' <summary>测试记录表名</summary>
|
|||
|
|
Private _testLogTableName As String
|
|||
|
|
|
|||
|
|
''' <summary>登录用户信息</summary>
|
|||
|
|
Private _userInfo As UserInfo
|
|||
|
|
|
|||
|
|
''' <summary>鉴权文件信息</summary>
|
|||
|
|
Private _license As License.License
|
|||
|
|
|
|||
|
|
''' <summary>当前选择站位信息</summary>
|
|||
|
|
Private _processStation As ProcessStation
|
|||
|
|
|
|||
|
|
''' <summary>测试结果内容</summary>
|
|||
|
|
Private ReadOnly _testResult As TestResult
|
|||
|
|
|
|||
|
|
''' <summary>软件注册器</summary>
|
|||
|
|
Private _register As AppRegister
|
|||
|
|
|
|||
|
|
''' <summary>服务通讯TCP客户端</summary>
|
|||
|
|
Private _tcpClient As TcpClient
|
|||
|
|
|
|||
|
|
''' <summary>是否释放当前类</summary>
|
|||
|
|
Private _disposedValue As Boolean
|
|||
|
|
|
|||
|
|
''' <summary>站位观察者集合</summary>
|
|||
|
|
Private ReadOnly _observerList As List(Of IProcessStation)
|
|||
|
|
|
|||
|
|
''' <summary>当前软件所属站位类型,None则无类型</summary>
|
|||
|
|
Private _stationType As ProcessStation.StationTypeEnum
|
|||
|
|
|
|||
|
|
''' <summary>UTS软件单例对象</summary>
|
|||
|
|
Private Shared _utsApp As UtsAppForm
|
|||
|
|
|
|||
|
|
''' <summary>UTS软件单例对象初始化锁</summary>
|
|||
|
|
Private Shared InitLock As New Object
|
|||
|
|
|
|||
|
|
'CZH 2023-05-19 增加站位列表集
|
|||
|
|
Public projectInfo As Project.ProjectInfo
|
|||
|
|
''' <summary>
|
|||
|
|
''' 创建单例对象
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public Shared Function CreateSingleton() As UtsAppForm
|
|||
|
|
If _utsApp IsNot Nothing Then
|
|||
|
|
Return _utsApp
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
SyncLock InitLock
|
|||
|
|
Thread.MemoryBarrier()
|
|||
|
|
If _utsApp Is Nothing Then
|
|||
|
|
_utsApp = New UtsAppForm
|
|||
|
|
End If
|
|||
|
|
End SyncLock
|
|||
|
|
|
|||
|
|
Return _utsApp
|
|||
|
|
End Function
|
|||
|
|
|
|||
|
|
|
|||
|
|
Private Sub New()
|
|||
|
|
_disposedValue = False
|
|||
|
|
|
|||
|
|
_testLogTableName = String.Empty
|
|||
|
|
|
|||
|
|
_testResult = New TestResult()
|
|||
|
|
|
|||
|
|
_observerList = New List(Of IProcessStation)()
|
|||
|
|
|
|||
|
|
ShowUnSearchOrderIDTip = True
|
|||
|
|
|
|||
|
|
SaveUnSearchOrderIDLog = False
|
|||
|
|
|
|||
|
|
IsInitialized = False
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 添加站位修改观察者,唯一添加
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="observer"></param>
|
|||
|
|
Public Sub AddStatisticsObserver(observer As IProcessStation)
|
|||
|
|
If _observerList.Contains(observer) = False Then _observerList.Add(observer)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 移除站位修改观察者
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="observer"></param>
|
|||
|
|
Public Sub RemoveStatisticsObserver(observer As IProcessStation)
|
|||
|
|
If _observerList.Contains(observer) Then _observerList.Remove(observer)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 清空站位修改观察者
|
|||
|
|
''' </summary>
|
|||
|
|
Public Sub ClearStatisticsObserver()
|
|||
|
|
_observerList.Clear()
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 初始化完成
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public Property IsInitialized As Boolean
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 用户账号信息
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property Account As UserInfo
|
|||
|
|
Get
|
|||
|
|
Return _userInfo
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 服务索引
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property ServiceIndex As Integer
|
|||
|
|
Get
|
|||
|
|
Return _serviceIndex
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 服务角色,0客户端,1服务器
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property ServiceRoles As Integer
|
|||
|
|
Get
|
|||
|
|
Return _serviceRoles
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 服务别名
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property ServiceAlias As String
|
|||
|
|
Get
|
|||
|
|
Return _serviceAlias
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 服务所属分组
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property ServiceGroup As String
|
|||
|
|
Get
|
|||
|
|
Return _serviceGroup
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 鉴权文件信息
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property License As License.License
|
|||
|
|
Get
|
|||
|
|
Return _license
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 工厂产线信息
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property ProductionLines() As ProductionLinesManager
|
|||
|
|
Get
|
|||
|
|
Return ProductionLinesManager.CreateManager()
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 测试站信息
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property TestResult() As TestResult
|
|||
|
|
Get
|
|||
|
|
Return _testResult
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 测试站信息
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property ProcessStation() As ProcessStation
|
|||
|
|
Get
|
|||
|
|
Return _processStation
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' APP注册机
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property Register() As AppRegister
|
|||
|
|
Get
|
|||
|
|
Return _register
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 测试记录表名
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public ReadOnly Property TestLogTableName() As String
|
|||
|
|
Get
|
|||
|
|
Return _testLogTableName
|
|||
|
|
End Get
|
|||
|
|
End Property
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 未查询到数据库订单号时是否显示提示
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public Property ShowUnSearchOrderIDTip() As Boolean
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 允许保存未查询到订单号的记录入库,显示提示时,此字段不生效。
|
|||
|
|
''' </summary>
|
|||
|
|
''' <returns></returns>
|
|||
|
|
Public Property SaveUnSearchOrderIDLog() As Boolean
|
|||
|
|
|
|||
|
|
Private _testChangedTime As DateTime
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 初始化信息,唯一初始化
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="sType">软件选择站位时,可以选择的站位类型,默认显示测试站位</param>
|
|||
|
|
Public Sub Initialize(Optional sType As ProcessStation.StationTypeEnum = ProcessStation.StationTypeEnum.Test)
|
|||
|
|
If IsInitialized = True Then Return
|
|||
|
|
IsInitialized = True
|
|||
|
|
|
|||
|
|
'建立Tcp与服务通讯的套接字
|
|||
|
|
ConnectDataService()
|
|||
|
|
|
|||
|
|
'显示登录窗体
|
|||
|
|
ShowLoginForm()
|
|||
|
|
|
|||
|
|
'注册软件
|
|||
|
|
RegisterApp()
|
|||
|
|
|
|||
|
|
'给测试记录附上初始值
|
|||
|
|
InitializeTestResult()
|
|||
|
|
|
|||
|
|
'记录站位类型提供过滤筛选
|
|||
|
|
_stationType = sType
|
|||
|
|
|
|||
|
|
'记录测试变化信息
|
|||
|
|
_testChangedTime = Now
|
|||
|
|
AddHandler TestStatusMonitor.TestStatusChanged, AddressOf TestStatusChanged
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 测试状态改变处理事件
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="sender"></param>
|
|||
|
|
''' <param name="e"></param>
|
|||
|
|
Private Sub TestStatusChanged(sender As Object, e As TestStatusChangedEventArgs)
|
|||
|
|
'记录上一次变化的时间
|
|||
|
|
_testChangedTime = Now
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
#Region "服务通讯模块"
|
|||
|
|
''' <summary>
|
|||
|
|
''' 连接数据服务,异步执行
|
|||
|
|
''' </summary>
|
|||
|
|
Public Sub ConnectDataService()
|
|||
|
|
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf KeepTcpClientAlive))
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 保持与数据服务的Tcp连接存活
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="state"></param>
|
|||
|
|
Private Sub KeepTcpClientAlive(state As Object)
|
|||
|
|
Static remoteIp As String = "127.0.0.1"
|
|||
|
|
|
|||
|
|
While True
|
|||
|
|
Try
|
|||
|
|
If _tcpClient Is Nothing OrElse _tcpClient.Client Is Nothing Then
|
|||
|
|
_tcpClient = New TcpClient(remoteIp, CInt(UtsRegistry.DataServicePort))
|
|||
|
|
|
|||
|
|
'开启监听
|
|||
|
|
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ClientReceive), _tcpClient)
|
|||
|
|
|
|||
|
|
'通知服务软件启动
|
|||
|
|
SendAppMsg(_tcpClient, TaskJsonParam.AppMsgTypes.AppStart)
|
|||
|
|
|
|||
|
|
'开启与服务通知心跳包
|
|||
|
|
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SendAppAlive), _tcpClient)
|
|||
|
|
End If
|
|||
|
|
Catch ex As Exception
|
|||
|
|
Console.WriteLine($"InitTcpClient Error:{ex.Message}!")
|
|||
|
|
End Try
|
|||
|
|
|
|||
|
|
Thread.Sleep(1000 * 10)
|
|||
|
|
End While
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 定期发送App心跳包
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="state"></param>
|
|||
|
|
Private Sub SendAppAlive(state As Object)
|
|||
|
|
Dim client As TcpClient = CType(state, TcpClient)
|
|||
|
|
While True
|
|||
|
|
If client Is Nothing OrElse client.Client Is Nothing Then Return
|
|||
|
|
|
|||
|
|
Thread.Sleep(1000)
|
|||
|
|
|
|||
|
|
SendAppMsg(client, TaskJsonParam.AppMsgTypes.AppAlive)
|
|||
|
|
|
|||
|
|
End While
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 主动向服务发送变化数据
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="type">变化类型</param>
|
|||
|
|
''' <param name="fileds">字段内容</param>
|
|||
|
|
Public Sub SendAppMsg(type As TaskJsonParam.AppMsgTypes, fileds As Dictionary(Of String, String))
|
|||
|
|
If _tcpClient Is Nothing OrElse _tcpClient.Client Is Nothing Then Return
|
|||
|
|
|
|||
|
|
Dim param As New TaskJsonParam
|
|||
|
|
param.CmdName = TaskJsonParam.CmdNamesEnum.AppMsg
|
|||
|
|
param.AppName = Application.ProductName
|
|||
|
|
|
|||
|
|
If _userInfo Is Nothing Then
|
|||
|
|
param.User = "Admin"
|
|||
|
|
Else
|
|||
|
|
param.User = _userInfo.UserName
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
param.AppInfo.Add("AppStatus", type.ToString)
|
|||
|
|
For Each filed As KeyValuePair(Of String, String) In fileds
|
|||
|
|
param.AppInfo.Add(filed.Key, filed.Value)
|
|||
|
|
Next
|
|||
|
|
|
|||
|
|
SendJsonString(_tcpClient, TaskJsonParam.SerializeToJson(param) & vbCrLf)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 发送App上报信息
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="client"></param>
|
|||
|
|
''' <param name="type"></param>
|
|||
|
|
Private Sub SendAppMsg(client As TcpClient, type As TaskJsonParam.AppMsgTypes)
|
|||
|
|
If client Is Nothing OrElse client.Client Is Nothing Then Return
|
|||
|
|
|
|||
|
|
Dim param As New TaskJsonParam
|
|||
|
|
param.CmdName = TaskJsonParam.CmdNamesEnum.AppMsg
|
|||
|
|
param.AppName = Application.ProductName
|
|||
|
|
|
|||
|
|
If _userInfo Is Nothing Then
|
|||
|
|
param.User = "Admin"
|
|||
|
|
Else
|
|||
|
|
param.User = _userInfo.UserName
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Select Case type
|
|||
|
|
Case TaskJsonParam.AppMsgTypes.AppStart
|
|||
|
|
param.AppInfo.Add("AppStatus", TaskJsonParam.AppMsgTypes.AppStart.ToString)
|
|||
|
|
param.AppInfo.Add("Version", Application.ProductVersion)
|
|||
|
|
param.AppInfo.Add("AppPath", Application.StartupPath)
|
|||
|
|
Case TaskJsonParam.AppMsgTypes.AppClose
|
|||
|
|
param.AppInfo.Add("AppStatus", TaskJsonParam.AppMsgTypes.AppClose.ToString)
|
|||
|
|
Case TaskJsonParam.AppMsgTypes.AppAlive
|
|||
|
|
param.AppInfo.Add("AppStatus", TaskJsonParam.AppMsgTypes.AppAlive.ToString)
|
|||
|
|
param.AppInfo.Add("Version", Application.ProductVersion)
|
|||
|
|
|
|||
|
|
If _processStation Is Nothing Then
|
|||
|
|
param.AppInfo.Add("Project", "")
|
|||
|
|
param.AppInfo.Add("Station", "")
|
|||
|
|
param.AppInfo.Add("TestPlan", "")
|
|||
|
|
Else
|
|||
|
|
param.AppInfo.Add("Project", _processStation.ParentProject.Name)
|
|||
|
|
param.AppInfo.Add("Station", _processStation.Name)
|
|||
|
|
param.AppInfo.Add("TestPlan", _processStation.Packet.FileName)
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
param.AppInfo.Add("UtsStatus", StatusMonitor.ComportStatusMonitor.ComportStatus.ToString)
|
|||
|
|
param.AppInfo.Add("TestStatus", StatusMonitor.TestStatusMonitor.TestStatus.ToString)
|
|||
|
|
Case TaskJsonParam.AppMsgTypes.StationChanged
|
|||
|
|
param.AppInfo.Add("AppStatus", TaskJsonParam.AppMsgTypes.StationChanged.ToString)
|
|||
|
|
param.AppInfo.Add("Project", _processStation.ParentProject.Name)
|
|||
|
|
param.AppInfo.Add("Station", _processStation.Name)
|
|||
|
|
param.AppInfo.Add("TestPlan", _processStation.Packet.FileName)
|
|||
|
|
End Select
|
|||
|
|
|
|||
|
|
SendJsonString(client, TaskJsonParam.SerializeToJson(param) & vbCrLf)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 发送数据
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="tcpClient"></param>
|
|||
|
|
''' <param name="jsonString"></param>
|
|||
|
|
Private Sub SendJsonString(tcpClient As TcpClient, jsonString As String)
|
|||
|
|
Static SendLock As New Object
|
|||
|
|
Static FailCount As Integer = 0
|
|||
|
|
|
|||
|
|
If tcpClient Is Nothing OrElse tcpClient.Client Is Nothing Then Return
|
|||
|
|
|
|||
|
|
SyncLock SendLock
|
|||
|
|
Try
|
|||
|
|
Dim buf() As Byte = Encoding.UTF8.GetBytes(jsonString)
|
|||
|
|
tcpClient.GetStream().Write(buf, 0, buf.Length)
|
|||
|
|
FailCount = 0
|
|||
|
|
Catch ex As Exception
|
|||
|
|
FailCount += 1
|
|||
|
|
If FailCount > 3 Then
|
|||
|
|
FailCount = 0
|
|||
|
|
tcpClient.Close()
|
|||
|
|
End If
|
|||
|
|
Console.WriteLine($"TcpClient Send Data Error!{ex.Message}")
|
|||
|
|
End Try
|
|||
|
|
End SyncLock
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' APP接收服务器数据
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="state"></param>
|
|||
|
|
Public Sub ClientReceive(state As Object)
|
|||
|
|
Dim client As TcpClient = CType(state, TcpClient)
|
|||
|
|
Dim len As Integer
|
|||
|
|
Dim buf(4096) As Byte
|
|||
|
|
|
|||
|
|
While True
|
|||
|
|
Try
|
|||
|
|
len = client.Client.Receive(buf)
|
|||
|
|
Catch ex As Exception
|
|||
|
|
Console.WriteLine($"TcpServer Receive Error:{ex.Message},Recycling Connection!")
|
|||
|
|
Exit While
|
|||
|
|
End Try
|
|||
|
|
|
|||
|
|
If len = 0 Then
|
|||
|
|
Console.WriteLine($"TcpServer {client.Client.RemoteEndPoint} Is Disconnect.")
|
|||
|
|
Exit While
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Dim destBuf(len - 1) As Byte
|
|||
|
|
Array.Copy(buf, 0, destBuf, 0, destBuf.Length)
|
|||
|
|
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf DealData), New TcpData(client, destBuf))
|
|||
|
|
End While
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub DealData(state As Object)
|
|||
|
|
Dim data As TcpData = CType(state, TcpData)
|
|||
|
|
Dim jsonStrings As String = Encoding.UTF8.GetString(data.Buffer)
|
|||
|
|
|
|||
|
|
'校验Json字符串,必须以回车换行结尾
|
|||
|
|
If jsonStrings.EndsWith(vbCrLf) = False Then Return
|
|||
|
|
|
|||
|
|
For Each jsonString As String In jsonStrings.Split(New String() {vbCrLf}, Integer.MaxValue, StringSplitOptions.RemoveEmptyEntries)
|
|||
|
|
Try
|
|||
|
|
'反序列化
|
|||
|
|
Dim taskParam As TaskJsonParam = TaskJsonParam.DeserializeFormJson(jsonString)
|
|||
|
|
|
|||
|
|
'反序列化失败,则处理下一包
|
|||
|
|
If IsNothing(taskParam) Then Continue For
|
|||
|
|
|
|||
|
|
'处理数据,返回回复数据
|
|||
|
|
Dim reply As TaskJsonParam = DealReceiveData(taskParam)
|
|||
|
|
|
|||
|
|
'无需回复,则处理下一包
|
|||
|
|
If reply Is Nothing Then Continue For
|
|||
|
|
|
|||
|
|
'序列化回复数据
|
|||
|
|
Dim replyString As String = TaskJsonParam.SerializeToJson(reply) & vbCrLf
|
|||
|
|
|
|||
|
|
'回复数据
|
|||
|
|
SendJsonString(data.Client, replyString)
|
|||
|
|
Catch ex As Exception
|
|||
|
|
Console.WriteLine($"Deal Receive Data Error!{ex.Message}")
|
|||
|
|
End Try
|
|||
|
|
Next
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 处理数据,并返回回复数据
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="taskParam">需要处理的数据参数</param>
|
|||
|
|
''' <returns>需要回复的数据</returns>
|
|||
|
|
Private Function DealReceiveData(taskParam As TaskJsonParam) As TaskJsonParam
|
|||
|
|
Dim replyParam As TaskJsonParam
|
|||
|
|
Select Case taskParam.CmdName
|
|||
|
|
Case TaskJsonParam.CmdNamesEnum.AppMsg
|
|||
|
|
replyParam = Nothing '不处理
|
|||
|
|
|
|||
|
|
If taskParam.CmdStatus = "Fail" Then Exit Select
|
|||
|
|
|
|||
|
|
Dim status As TaskJsonParam.AppMsgTypes
|
|||
|
|
Try
|
|||
|
|
status = CType([Enum].Parse(GetType(TaskJsonParam.AppMsgTypes), taskParam.AppInfo("AppStatus")), TaskJsonParam.AppMsgTypes)
|
|||
|
|
|
|||
|
|
Select Case status
|
|||
|
|
Case TaskJsonParam.AppMsgTypes.AppAlive
|
|||
|
|
Static dbLastStatus As Integer = -1
|
|||
|
|
Static ftpLastStatus As Integer = -1
|
|||
|
|
Static cacheLastStatus As Integer = -1
|
|||
|
|
Static syncLastStatus As String = ""
|
|||
|
|
Static servicesLastStatus As String = ""
|
|||
|
|
|
|||
|
|
Dim dbStatus As Integer = -1
|
|||
|
|
Dim ftpStatus As Integer = -1
|
|||
|
|
Dim cacheCount As Integer = -1
|
|||
|
|
|
|||
|
|
Integer.TryParse(taskParam.AppInfo("DbStatus"), dbStatus)
|
|||
|
|
If dbLastStatus <> dbStatus Then
|
|||
|
|
dbLastStatus = dbStatus
|
|||
|
|
RaiseEvent DbStatusChanged(dbLastStatus)
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Integer.TryParse(taskParam.AppInfo("FtpStatus"), ftpStatus)
|
|||
|
|
If ftpLastStatus <> ftpStatus Then
|
|||
|
|
ftpLastStatus = ftpStatus
|
|||
|
|
RaiseEvent FtpStatusChanged(dbLastStatus)
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Dim flg As Boolean = False '是否更新同步状态文本
|
|||
|
|
Integer.TryParse(taskParam.AppInfo("CacheCount"), cacheCount)
|
|||
|
|
If cacheLastStatus <> cacheCount Then
|
|||
|
|
cacheLastStatus = cacheCount
|
|||
|
|
flg = True
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Dim syncTime As String = taskParam.AppInfo("SyncTime")
|
|||
|
|
If syncLastStatus <> syncTime Then
|
|||
|
|
syncLastStatus = syncTime
|
|||
|
|
flg = True
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
If flg Then
|
|||
|
|
RaiseEvent SyncTimeChanged($"[{cacheLastStatus}] {syncLastStatus}")
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Dim tmpTime As Date
|
|||
|
|
If Date.TryParse(syncTime, tmpTime) Then
|
|||
|
|
If (Now - tmpTime).TotalMinutes > 6 Then
|
|||
|
|
DatabaseStatusMonitor.DatabaseSyncStatus = DatabaseStatusMonitor.DatabaseSyncStatusEnum.UnCompleted
|
|||
|
|
Else
|
|||
|
|
DatabaseStatusMonitor.DatabaseSyncStatus = DatabaseStatusMonitor.DatabaseSyncStatusEnum.Completed
|
|||
|
|
End If
|
|||
|
|
Else
|
|||
|
|
DatabaseStatusMonitor.DatabaseSyncStatus = DatabaseStatusMonitor.DatabaseSyncStatusEnum.Unknown
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Dim services As String = taskParam.AppInfo("Services")
|
|||
|
|
If servicesLastStatus <> services Then
|
|||
|
|
servicesLastStatus = services
|
|||
|
|
RaiseEvent ServicesChanged(servicesLastStatus)
|
|||
|
|
End If
|
|||
|
|
Case Else
|
|||
|
|
Console.WriteLine($"status:{status}")
|
|||
|
|
End Select
|
|||
|
|
Catch ex As Exception
|
|||
|
|
|
|||
|
|
End Try
|
|||
|
|
|
|||
|
|
Case TaskJsonParam.CmdNamesEnum.ServiceMsg
|
|||
|
|
replyParam = DealServiceMsg(taskParam)
|
|||
|
|
Case Else
|
|||
|
|
replyParam = Nothing
|
|||
|
|
Console.WriteLine($"Invalid CmdName:{taskParam.CmdName}")
|
|||
|
|
End Select
|
|||
|
|
Return replyParam
|
|||
|
|
End Function
|
|||
|
|
|
|||
|
|
Public Event DbStatusChanged(status As Integer)
|
|||
|
|
Public Event FtpStatusChanged(status As Integer)
|
|||
|
|
Public Event SyncTimeChanged(timeString As String)
|
|||
|
|
Public Event ServicesChanged(services As String)
|
|||
|
|
|
|||
|
|
|
|||
|
|
Private Function DealServiceMsg(taskParam As TaskJsonParam) As TaskJsonParam
|
|||
|
|
Dim replyParam As New TaskJsonParam(taskParam.CmdName, True)
|
|||
|
|
|
|||
|
|
Try
|
|||
|
|
If taskParam.AppInfo Is Nothing OrElse taskParam.AppInfo.Count = 0 Then Return Nothing
|
|||
|
|
|
|||
|
|
'依此判断App修改类型
|
|||
|
|
Dim status As TaskJsonParam.ServiceMsgTypes
|
|||
|
|
status = CType([Enum].Parse(GetType(TaskJsonParam.ServiceMsgTypes), taskParam.AppInfo("AppStatus")), TaskJsonParam.ServiceMsgTypes)
|
|||
|
|
|
|||
|
|
Select Case status
|
|||
|
|
Case TaskJsonParam.ServiceMsgTypes.DbHostChange
|
|||
|
|
UtsDb.DbHostChanged(taskParam.AppInfo("DbHost"))
|
|||
|
|
Case TaskJsonParam.ServiceMsgTypes.FtpHostChange
|
|||
|
|
UtsFtp.CreateObject.FtpHost = taskParam.AppInfo("FtpHost")
|
|||
|
|
End Select
|
|||
|
|
|
|||
|
|
replyParam.CmdStatus = TaskJsonParam.CmdStatusEnum.Pass.ToString()
|
|||
|
|
Catch ex As Exception
|
|||
|
|
replyParam.CmdStatus = TaskJsonParam.CmdStatusEnum.Fail.ToString()
|
|||
|
|
replyParam.CmdMsg = ex.Message
|
|||
|
|
End Try
|
|||
|
|
|
|||
|
|
Return replyParam
|
|||
|
|
End Function
|
|||
|
|
|
|||
|
|
Public Class TcpData
|
|||
|
|
Sub New(c As TcpClient, buf() As Byte)
|
|||
|
|
Client = c
|
|||
|
|
Buffer = buf
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Client As TcpClient
|
|||
|
|
|
|||
|
|
Public Buffer() As Byte
|
|||
|
|
End Class
|
|||
|
|
#End Region
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 显示登陆页面
|
|||
|
|
''' </summary>
|
|||
|
|
Private Sub ShowLoginForm()
|
|||
|
|
If LoginParams.IsShowLoginForm = False Then Return
|
|||
|
|
Using frmLogin As New LoginForm
|
|||
|
|
If frmLogin.ShowDialog() = DialogResult.OK Then
|
|||
|
|
_userInfo = frmLogin.UserLoginInfo
|
|||
|
|
_license = frmLogin.UserLicense
|
|||
|
|
Else
|
|||
|
|
Throw New Exception($"User Quit!")
|
|||
|
|
End If
|
|||
|
|
End Using
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 注册APP
|
|||
|
|
''' </summary>
|
|||
|
|
Private Sub RegisterApp()
|
|||
|
|
_serviceIndex = CInt(UtsRegistry.DataServiceIndex)
|
|||
|
|
_serviceRoles = CInt(UtsRegistry.Roles)
|
|||
|
|
_serviceAlias = UtsRegistry.DataServiceAlias
|
|||
|
|
_serviceGroup = UtsRegistry.BarnchNet
|
|||
|
|
_appName = Application.ProductName
|
|||
|
|
_appVersion = Application.ProductVersion
|
|||
|
|
|
|||
|
|
AppRegister.CreateAppListTable() '创建日志列表
|
|||
|
|
AppRegister.CreateAppLogTable() '创建日志记录表
|
|||
|
|
_register = New AppRegister(_serviceIndex, _appName, _appVersion)
|
|||
|
|
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf UpdateAppAliveTime))
|
|||
|
|
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SaveServiceLog))
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 初始化测试结果字段信息
|
|||
|
|
''' </summary>
|
|||
|
|
Private Sub InitializeTestResult()
|
|||
|
|
_testResult.UserID = Account.UserId
|
|||
|
|
_testResult.ServiceID = _serviceIndex
|
|||
|
|
_testResult.AppName = _appName & _appVersion
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 填充测试结果订单信息字段
|
|||
|
|
''' </summary>
|
|||
|
|
Private Sub FillTestResultOrderID()
|
|||
|
|
_testResult.OrderID = DbConnector.SearchOrderID(_processStation.ParentProject.Index, _testResult.DUT_SN)
|
|||
|
|
|
|||
|
|
If _testResult.OrderID = -1 Then
|
|||
|
|
'仅自动生成条码模式下保证有订单号,其余模式条码不检测
|
|||
|
|
If _processStation.SnType <> ProcessStation.SnTypeEnum.Auto Then Return
|
|||
|
|
If ShowUnSearchOrderIDTip Then
|
|||
|
|
If MsgBox($"未查询到条码[{_testResult.DUT_SN}]对应的订单号,是否继续录入?", MsgBoxStyle.OkCancel, "Tip") <> MsgBoxResult.Ok Then
|
|||
|
|
Throw New Exception($"未查询条码[{_testResult.DUT_SN}]到指定订单号")
|
|||
|
|
End If
|
|||
|
|
Else
|
|||
|
|
If SaveUnSearchOrderIDLog = False Then
|
|||
|
|
Throw New Exception($"未查询条码[{_testResult.DUT_SN}]到指定订单号")
|
|||
|
|
End If
|
|||
|
|
End If
|
|||
|
|
End If
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 根据序号分配给测试记录的订单号,并将测试记录写入到数据库中,提交成功后会重置测试记录。
|
|||
|
|
''' </summary>
|
|||
|
|
Public Sub CommitTestResult(Optional uniqueRecord As Boolean = False)
|
|||
|
|
'填充订单号
|
|||
|
|
FillTestResultOrderID()
|
|||
|
|
|
|||
|
|
'提交测试记录
|
|||
|
|
If uniqueRecord Then
|
|||
|
|
DbConnector.SaveUniqueTestLog(_testLogTableName, _processStation, _testResult)
|
|||
|
|
Else
|
|||
|
|
DbConnector.SaveTestLog(_testLogTableName, _processStation, _testResult)
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 根据项目名与站位名称,加载项目站信息
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="projectName"></param>
|
|||
|
|
''' <param name="stationName"></param>
|
|||
|
|
Public Sub LoadStation(projectName As String, stationName As String, Optional filed As Dictionary(Of String, String) = Nothing)
|
|||
|
|
If String.IsNullOrWhiteSpace(projectName) Or String.IsNullOrWhiteSpace(stationName) Then
|
|||
|
|
Return
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Using dlg As New DlgLoadStation
|
|||
|
|
dlg.UserInfo = Account '用与初始化项目信息时,更新操作者,同时可用与根据用户权限筛选项目
|
|||
|
|
If dlg.InitProjectStationWithoutShow(projectName, stationName) Then
|
|||
|
|
_processStation = dlg.ProcessStation
|
|||
|
|
projectInfo = dlg._projectInfo
|
|||
|
|
If String.IsNullOrEmpty(ProcessStation.Packet.FileName) Then
|
|||
|
|
ProcessStation.Packet.CreatePacket() '新建测试站包
|
|||
|
|
Else
|
|||
|
|
ProcessStation.Packet.LoadPacket() '读取测试站包
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
StationChanged(ProcessStation, filed) '测试站修改
|
|||
|
|
End If
|
|||
|
|
End Using
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 显示切换项目站信息页面,供用户修改测试站
|
|||
|
|
''' </summary>
|
|||
|
|
Public Sub ChangeStation(Optional filed As Dictionary(Of String, String) = Nothing)
|
|||
|
|
Using dlg As New DlgLoadStation
|
|||
|
|
dlg.UserInfo = Account '用与初始化项目信息时,更新操作者,同时可用与根据用户权限筛选项目
|
|||
|
|
|
|||
|
|
If _processStation Is Nothing Then
|
|||
|
|
If dlg.ShowDialog("", "", _stationType) <> DialogResult.OK Then Return
|
|||
|
|
Else
|
|||
|
|
If dlg.ShowDialog(_processStation.ParentProject.Name, _processStation.Name, _stationType) <> DialogResult.OK Then Return
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
If dlg.ProcessStation Is Nothing Then Return
|
|||
|
|
_processStation = dlg.ProcessStation
|
|||
|
|
projectInfo = dlg._projectInfo
|
|||
|
|
If String.IsNullOrEmpty(ProcessStation.Packet.FileName) Then
|
|||
|
|
ProcessStation.Packet.CreatePacket() '新建测试站包
|
|||
|
|
Else
|
|||
|
|
ProcessStation.Packet.LoadPacket() '读取测试站包
|
|||
|
|
End If
|
|||
|
|
StationChanged(ProcessStation, filed)
|
|||
|
|
|
|||
|
|
End Using
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
'2022-10-19 CZH 该改动针对已固定某一站的 资源包刷新
|
|||
|
|
Public Sub ChangeStation(processStation As ProcessStation, Optional filed As Dictionary(Of String, String) = Nothing)
|
|||
|
|
'Using dlg As New DlgLoadStation
|
|||
|
|
' dlg.UserInfo = Account '用与初始化项目信息时,更新操作者,同时可用与根据用户权限筛选项目
|
|||
|
|
|
|||
|
|
' If _processStation Is Nothing Then
|
|||
|
|
' If dlg.ShowDialog("", "", _stationType) <> DialogResult.OK Then Return
|
|||
|
|
' Else
|
|||
|
|
' If dlg.ShowDialog(_processStation.ParentProject.Name, _processStation.Name, _stationType) <> DialogResult.OK Then Return
|
|||
|
|
' End If
|
|||
|
|
|
|||
|
|
If processStation Is Nothing Then Return
|
|||
|
|
_processStation = processStation
|
|||
|
|
|
|||
|
|
If String.IsNullOrEmpty(processStation.Packet.FileName) Then
|
|||
|
|
processStation.Packet.CreatePacket() '新建测试站包
|
|||
|
|
Else
|
|||
|
|
processStation.Packet.LoadPacket() '读取测试站包
|
|||
|
|
End If
|
|||
|
|
StationChanged(processStation, filed)
|
|||
|
|
|
|||
|
|
'End Using
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 用户选择测试站后回调函数
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="station"></param>
|
|||
|
|
''' <param name="filed"></param>
|
|||
|
|
Private Sub StationChanged(station As ProcessStation, Optional filed As Dictionary(Of String, String) = Nothing)
|
|||
|
|
_testLogTableName = TestLogTable.TableName(station.ParentProject.Index, ProcessStation.StationID)
|
|||
|
|
|
|||
|
|
'本地新建测试记录表
|
|||
|
|
DbConnector.UtsCreateTestLogTableToLocal(_testLogTableName)
|
|||
|
|
|
|||
|
|
'添加预添加列
|
|||
|
|
If filed IsNot Nothing AndAlso filed.Count > 0 Then
|
|||
|
|
DbConnector.AddTestLogCols(_testLogTableName, filed)
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
'修改测试记录中测试流程
|
|||
|
|
_testResult.TestPlan = _processStation.Packet.FileName
|
|||
|
|
|
|||
|
|
'App日志
|
|||
|
|
_register.ProjectName = _processStation.ParentProject.Name
|
|||
|
|
_register.StationName = _processStation.Name
|
|||
|
|
_register.TestPlan = _processStation.Packet.FileName
|
|||
|
|
_register.AppendTraceLog($"Station Changed,PN:{station.ParentProject.Name},SN:{station.Name}.")
|
|||
|
|
_register.AppMsg = $"PN:{_processStation.ParentProject.Name},SN:{_processStation.Name},TP:{_register.TestPlan}"
|
|||
|
|
|
|||
|
|
'触发其他页面的站位修改事件
|
|||
|
|
For Each observer As IProcessStation In _observerList
|
|||
|
|
observer.StationChanged()
|
|||
|
|
Next
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 定期更新APP存活时间
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="state"></param>
|
|||
|
|
Private Sub UpdateAppAliveTime(state As Object)
|
|||
|
|
Dim Interval As Integer = 1000 * 60 * 1 '单位ms
|
|||
|
|
|
|||
|
|
While _disposedValue = False
|
|||
|
|
|
|||
|
|
If (Now - _testChangedTime).TotalMinutes >= 1 AndAlso TestStatusMonitor.TestStatus <> TestStatusMonitor.TestStatusEnum.Testing Then
|
|||
|
|
_register.AppStatus = 0
|
|||
|
|
Else
|
|||
|
|
_register.AppStatus = 1
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
Try
|
|||
|
|
_register.UpdateAliveTime()
|
|||
|
|
Catch ex As Exception
|
|||
|
|
Console.WriteLine($"UpdateAppAliveTime Error:{ex.Message}")
|
|||
|
|
End Try
|
|||
|
|
|
|||
|
|
Thread.Sleep(Interval)
|
|||
|
|
End While
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 保存软件运行日志至数据库
|
|||
|
|
''' </summary>
|
|||
|
|
''' <param name="state"></param>
|
|||
|
|
Private Sub SaveServiceLog(state As Object)
|
|||
|
|
Dim Interval As Integer = 1000 * 60 * 1 '单位ms
|
|||
|
|
|
|||
|
|
While _disposedValue = False
|
|||
|
|
SaveServiceLogQueueToDb()
|
|||
|
|
|
|||
|
|
Thread.Sleep(Interval)
|
|||
|
|
End While
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
''' <summary>
|
|||
|
|
''' 保存软件运行日志至数据库
|
|||
|
|
''' </summary>
|
|||
|
|
Private Sub SaveServiceLogQueueToDb()
|
|||
|
|
Try
|
|||
|
|
If _register IsNot Nothing Then
|
|||
|
|
_register.SaveLogQueueToDb()
|
|||
|
|
End If
|
|||
|
|
Catch ex As Exception
|
|||
|
|
Console.WriteLine($"SaveServiceLog Error:{ex.Message}")
|
|||
|
|
End Try
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
|
|||
|
|
Protected Overridable Sub Dispose(disposing As Boolean)
|
|||
|
|
If Not _disposedValue Then
|
|||
|
|
If disposing Then
|
|||
|
|
'释放托管状态(托管对象)
|
|||
|
|
End If
|
|||
|
|
|
|||
|
|
'释放未托管的资源(未托管的对象)并替代终结器
|
|||
|
|
'将大型字段设置为 null
|
|||
|
|
|
|||
|
|
_disposedValue = True
|
|||
|
|
|
|||
|
|
SaveServiceLogQueueToDb()
|
|||
|
|
End If
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
Public Sub Dispose() Implements IDisposable.Dispose
|
|||
|
|
' 不要更改此代码。请将清理代码放入“Dispose(disposing As Boolean)”方法中
|
|||
|
|
Dispose(disposing:=True)
|
|||
|
|
GC.SuppressFinalize(Me)
|
|||
|
|
End Sub
|
|||
|
|
|
|||
|
|
End Class
|
|||
|
|
End Namespace
|