Imports System.IO
Imports System.Threading
Imports UTS_Core.Compress
Imports UTS_Core.Database
Imports UTS_Core.Security
Imports UTS_Core.UTSModule
Imports UTS_Core.UTSModule.License
Imports UTS_Core.UTSModule.Service
Imports UTS_Core.UTSModule.DbConnect
Imports UTS_Core.UTSModule.DbTableModel.Manage
Imports System.Text

Public Class UpdateService

    ''' <summary> AUTS_DataService服务名 </summary>
    Private _dsName As String

    ''' <summary> AUTS_DataService的索引 </summary>
    Private _dsIndex As String

    ''' <summary>数据服务的文件夹路径，不包含版本</summary>
    Private _dsDirPath As String

    ''' <summary>数据服务升级时存放从FTP下载的最新包文件夹路径</summary>
    Private _dsPacketDirPath As String

    ''' <summary>服务本地版本</summary>
    Private _dsVersion As String

    ''' <summary>数据服务在线状态，0离线，1在线</summary>
    Private _dsOnline As Integer

    ''' <summary>服务上一次本地版本</summary>
    Private _lastDsVersion As String

    ''' <summary>当前服务正在运行</summary>
    Private _serviceRunning As Boolean

    ''' <summary>Log文件夹路径</summary>
    Private _logDirPath As String

    ''' <summary>设置文件夹路径</summary>
    Private _settingsDirPath As String

    ''' <summary>更新服务版本</summary>
    Private _usVersion As String

    ''' <summary>更新服务版本</summary>
    Private _usErrMsg As String

    ''' <summary>更新服务名称</summary>
    Private _usName As String

    ''' <summary>是否已更新过版本</summary>
    Private _uploaded As Boolean

    ''' <summary>当前服务正在升级</summary>
    Private _serviceUpdating As Boolean

    ''' <summary>等待检测服务</summary>
    Private _waitCheckService As Boolean

    Protected Overrides Sub OnStart(args() As String)
        ' 请在此处添加代码以启动您的服务。此方法应完成设置工作，
        ' 以使您的服务开始工作。
        Thread.Sleep(3000)

        InitServiceInfo()

        CreateSystemFolder()

        ApplicationLog.InitApplicationLogInfo(_logDirPath, My.Application.Info.ProductName)

        If CheckLicense() = False Then Return
        UtsDb.InitConnectParams(_license) '根据License信息,初始化数据库连接信息
        UTS_Core.DebugLog.ApplicationLog.WriteInfoLog($"InitConnectParams Success.")

        ApplicationLog.VendorName = _license.VendorName '写入数据前指定软件公司名
        ApplicationLog.StartSaveLogToDatabase() '需要先指定数据库路径

        _ftpClient = New FtpService(UtsRegistry.FtpHost, CInt(_license.FtpPort), _license.FtpUser, _license.FtpPwd)

        _serviceRunning = True
        ApplicationLog.WriteTraceLog($"Start Monitor!")

        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf KeepServiceConnect))
        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf UpdateMonitor))
        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf UpdateServiceInfo))
    End Sub


    Protected Overrides Sub OnStop()
        ' 在此处添加代码以执行任何必要的拆解操作，从而停止您的服务。
        StopUpdateMonitor()

        ApplicationLog.WriteTraceLog($"UpdateService OnStop")
        ApplicationLog.StopSaveLogToDatabase()
    End Sub

#Region "准备工作"

    ''' <summary>
    ''' 初始化服务信息
    ''' </summary>
    Private Sub InitServiceInfo()
        _dsOnline = 1
        _dsIndex = UtsRegistry.DataServiceIndex
        _dsName = UtsRegistry.DataServiceName
        _dsDirPath = $"{UtsRegistry.RootPath}\{UtsRegistry.DataServiceName}"
        _dsPacketDirPath = $"{UtsRegistry.RootPath}\DataServiceDownload"

        _usName = My.Application.Info.ProductName
        _usVersion = My.Application.Info.Version.ToString
        _usErrMsg = String.Empty

        _logDirPath = $"{UtsRegistry.RootPath}\Log\{My.Application.Info.ProductName}"
        _settingsDirPath = $"{UtsRegistry.UpdateServiceDirPath}\Settings"

        UtsRegistry.UpdateServiceVersion = _usVersion
    End Sub


    ''' <summary>
    ''' 创建运行时必要文件夹
    ''' </summary>
    Private Sub CreateSystemFolder()
        Directory.CreateDirectory(_dsDirPath)      '数据服务文件夹路径
        Directory.CreateDirectory(_dsPacketDirPath)    '数据服务下载文件夹路径
        Directory.CreateDirectory(_settingsDirPath) '创建设置文件夹
        Directory.CreateDirectory(_logDirPath) '创建日志文件夹
    End Sub


    ''' <summary>
    ''' 关闭更新服务
    ''' </summary>
    Private Sub StopUpdateMonitor()
        _serviceRunning = False
    End Sub

#End Region

#Region "更新服务操作"
    ''' <summary>
    ''' 保持与服务的定期通讯
    ''' </summary>
    Private Sub KeepServiceConnect(obj As Object)
        While _serviceRunning
            Thread.Sleep(1000)

            '升级状态中，取消通讯
            If _serviceUpdating Then Continue While

            '开始通讯
            If InitTcpClient() AndAlso GetServiceLocalVersion() Then '初始化网络客户端连接,进行获取版本号通讯
                ResetServiceHeartBeatFailCount()
            Else
                UpdateServiceHeartBeatFailCount()
            End If
        End While
    End Sub

    ''' <summary>
    ''' 定期更新数据库中服务的状态
    ''' </summary>
    Private Sub UpdateServiceInfo(obj As Object)

        Dim Interval As Integer = 1 * 60 * 1000

        While _serviceRunning

            Dim sb As New StringBuilder
            sb.Append($"update `{UtsDb.RemotePublicDb}`.`{DataServiceListTable.TableName}` set ")
            sb.Append($"`{DataServiceListTable.ColNames.USVer}` = '{_usVersion}' ")
            sb.Append($",`{DataServiceListTable.ColNames.IsOnline}` = {_dsOnline} ")
            sb.Append($",`{DataServiceListTable.ColNames.ServiceLastActiveDateTime}` =  current_timestamp() ")
            If String.IsNullOrEmpty(_usErrMsg) = False Then
                sb.Append($",`{DataServiceListTable.ColNames.USErrMsg}` = '{_usErrMsg}' ")
                _usErrMsg = String.Empty
            End If

            sb.Append($"where `{DataServiceListTable.ColNames.ID}` = {_dsIndex}")

            Try
                Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
                    db.Open()

                    db.ExecuteNonQuery(sb.ToString)

                    db.Close()
                End Using
            Catch ex As Exception
                ApplicationLog.WriteErrorLog($"Update ServiceInfo Error:{ex.Message}")
            End Try

            Thread.Sleep(Interval)
        End While
    End Sub


    ''' <summary>
    ''' 定期检查DataService是否需要更新
    ''' </summary>
    ''' <param name="obj"></param>
    Private Sub UpdateMonitor(obj As Object)
        Dim Interval As Integer = 5 * 60 * 1000

        While _serviceRunning
            Try
                DetectionService()
            Catch ex As Exception
                ApplicationLog.WriteErrorLog($"DetectionService Error:{ex.Message}")
            End Try

            '等待任务
            Dim lastTime As Date = Now
            _waitCheckService = True
            While (Now - lastTime).TotalMilliseconds < Interval
                If _waitCheckService = False Then
                    Exit While
                End If

                Thread.Sleep(1000)
            End While
        End While
    End Sub

    Private _startServiceFailCount As Integer = 0
    Private ReadOnly _startServiceFailMaxCount As Integer = 3

    Private _upgradeServiceFailCount As Integer = 0
    Private ReadOnly _upgradeerviceFailMaxCount As Integer = 3

    Private _serviceHeartBeatFailCount As Integer = 0
    Private ReadOnly _serviceHeartBeatFailMaxCount As Integer = 30


    ''' <summary>
    ''' 检测服务
    ''' </summary>
    Private Sub DetectionService()
        '服务不存在处理
        If WinService.ServicesExists(_dsName) = False Then
            ApplicationLog.WriteTraceLog($"{_dsName} Service Not Exists,Begin Download Packet And Install Service!")
            InstallDataService()
            Return
        End If

        '服务存在未启动
        If WinService.ServicesStatus(_dsName) <> WinService.ServiceStatusEnum.Started Then '存在,则检测是否启动
            ApplicationLog.WriteTraceLog($"{_dsName} Service Not Running!Status:{WinService.ServicesStatus(_dsName)},Begin StartService!")
            If WinService.StartService(_dsName) = False Then
                UpdateStartServiceFailCount()
                Return
            End If
            ApplicationLog.WriteTraceLog($"Start {_dsName} Service Success!")
            Return
        End If

        '服务启动但失联
        If _dsOnline = 0 Then
            If WinService.RestartService(_dsName) = False Then
                UpdateStartServiceFailCount()
                Return
            End If
            ApplicationLog.WriteTraceLog($"ReStart {_dsName} Service Success!")
            Return
        End If


        ResetStartServiceFailCount() '重置启动失败次数

        If UpgradeDataService() Then
            InstallDataService()
        Else
            Console.WriteLine($"服务已是最新版本!")
        End If
    End Sub


    ''' <summary>
    ''' 数据服务正常运行时,检查数据服务更新
    ''' </summary>
    Private Function UpgradeDataService() As Boolean

        '获取云端信息
        Dim packetInfo As UpdatePackageInfo = GetDataServiceInfo()
        If packetInfo Is Nothing Then Return False

        '获取本地旧版本服务
        Dim dataSerFilePath As String = UtsRegistry.DataServiceFilePath

        '确定需要更新服务
        If NeedToUpdateService(_dsVersion, packetInfo.LastVersion) = False Then
            Return False
        End If
        ApplicationLog.WriteTraceLog($"Relldy To Update DataService,LocalVer:{_dsVersion},RemoteVer:{packetInfo.LastVersion}")

        '卸载服务
        Try
            WinService.UnInstallService(dataSerFilePath, Nothing)
            ApplicationLog.WriteTraceLog($"{dataSerFilePath} UnInstallService Success!")
        Catch ex As Exception
            ApplicationLog.WriteTraceLog($"{dataSerFilePath} UnInstallService Fail,{ex.Message}")
            Return False
        End Try

        'ResetTcpConnection()

        Return True
    End Function


    ''' <summary>
    ''' 从远程获取数据服务信息,安装或覆盖数据服务
    ''' </summary>
    ''' <param name="serviceExists">服务存在状态,如果服务存在则覆盖原文件,不存在则安装服务</param>
    Private Sub InstallDataService(Optional serviceExists As Boolean = False)
        _serviceUpdating = True
        Dim packetInfo As UpdatePackageInfo = GetDataServiceInfo()
        If packetInfo Is Nothing Then Return

        ApplicationLog.WriteTraceLog($"Begin DownloadServicePacket...")
        If DownloadServicePacket(packetInfo, serviceExists) = False Then
            ApplicationLog.WriteTraceLog($"DownloadServicePacket Fail!")

            '添加下载失败计数
            UpdateUpgradeFailCount()

            _serviceUpdating = False
            Return
        End If
        ApplicationLog.WriteTraceLog($"DownloadServicePacket Success!")
        _serviceUpdating = False
    End Sub


    ''' <summary>
    ''' 获取数据服务的最新信息
    ''' </summary>
    Private Function GetDataServiceInfo() As UpdatePackageInfo
        Try
            If DbConnector.CanConnectToRemote = False Then '判断网络连接状态
                ApplicationLog.WriteWarningLog($"Can’t Connect To Database!")
                Return Nothing
            End If

            Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
                db.Open()

                Dim tableName As String = $"{SwUpdateTable.TableName}"
                Dim colNames As New List(Of String) From {
                    $"{SwUpdateTable.ColNamesEnum.LastVersion}",
                    $"{SwUpdateTable.ColNamesEnum.BinPackageMd5}",
                    $"{SwUpdateTable.ColNamesEnum.PackageName}"
                }
                Dim condition As String = $"`{SwUpdateTable.ColNamesEnum.SoftwareName}` = '{_dsName}'"

                Dim dtServiceInfo As DataTable = db.ExecuteDataTable(db.CmdHelper.DbSearch(UtsDb.RemotePublicDb, colNames, tableName, condition))
                If dtServiceInfo.Rows.Count <= 0 Then
                    ApplicationLog.WriteErrorLog($"Database Can’t Find [{_dsName}] Software!")

                    db.Close()
                    Return Nothing
                End If

                Dim packetInfo As New UpdatePackageInfo
                packetInfo.BinPackageMd5 = dtServiceInfo.Rows(0)($"{SwUpdateTable.ColNamesEnum.BinPackageMd5}").ToString()
                packetInfo.LastVersion = dtServiceInfo.Rows(0)($"{SwUpdateTable.ColNamesEnum.LastVersion}").ToString()
                packetInfo.PackageName = dtServiceInfo.Rows(0)($"{SwUpdateTable.ColNamesEnum.PackageName}").ToString()

                db.Close()

                Return packetInfo
            End Using

        Catch ex As Exception
            ApplicationLog.WriteErrorLog($"GetServiceRemoteVersion Error:{ex.Message}!")
            Return Nothing
        End Try
    End Function

    ''' <summary>
    ''' 重置心跳包失败计数
    ''' </summary>
    Private Sub ResetServiceHeartBeatFailCount()
        _serviceHeartBeatFailCount = 0

    End Sub

    ''' <summary>
    ''' 心跳包通讯失败后，更新心跳包失败计数
    ''' </summary>
    Private Sub UpdateServiceHeartBeatFailCount()
        _serviceHeartBeatFailCount += 1

        If _serviceHeartBeatFailCount < _serviceHeartBeatFailMaxCount Then Return
        ApplicationLog.WriteErrorLog($"Services NetWork FailCount [{_serviceHeartBeatFailCount}] Is greater than the limit {_serviceHeartBeatFailMaxCount}")

        _dsOnline = 0

        ResetServiceHeartBeatFailCount()
        ResetTcpConnection()

        '立刻检测服务状态
        _waitCheckService = False
    End Sub


    ''' <summary>
    ''' 重置启动服务失败计数
    ''' </summary>
    Private Sub ResetStartServiceFailCount()
        _startServiceFailCount = 0
    End Sub

    ''' <summary>
    ''' 重启或则启动服务失败后，更新启动服务失败计数,超过计数上限则重置数据服务内容
    ''' </summary>
    Private Sub UpdateStartServiceFailCount()
        _startServiceFailCount += 1

        ApplicationLog.WriteWarningLog($"StartDataService Fail,FailCount:{_startServiceFailCount}!")
        If _startServiceFailCount < _startServiceFailMaxCount Then Return

        ApplicationLog.WriteErrorLog($"StartDataService Fail,FailCount:{_startServiceFailCount} Is Greater Than The Limit {_startServiceFailMaxCount},Begin Reset DataService!")
        ResetStartServiceFailCount()

        InstallDataService(WinService.ServicesExists(_dsName))
    End Sub



    Private Sub ResetUpgradeFailCount()
        _upgradeServiceFailCount = 0
    End Sub

    Private Sub UpdateUpgradeFailCount()
        _upgradeServiceFailCount += 1

        ApplicationLog.WriteErrorLog($"Upgrade DataService Error,Count：{_upgradeServiceFailCount}")
        If _upgradeServiceFailCount >= 3 Then
            _upgradeServiceFailCount = 0

            _usErrMsg = "DataService  unable upgrade"

            ApplicationLog.WriteErrorLog($"DataService  unable upgrade")

        End If
    End Sub


    ''' <summary>
    ''' 下载服务包,完成服务安装
    ''' </summary>
    ''' <param name="packetInfo">数据库中该程序包的信息</param>
    ''' <param name="serviceExists">服务是否已经安装</param>
    ''' <returns></returns>
    Private Function DownloadServicePacket(packetInfo As UpdatePackageInfo, Optional serviceExists As Boolean = True) As Boolean
        Dim localFilePath As String = $"{_dsPacketDirPath}\{packetInfo.PackageName}"
        Dim ftpFilePath As String = $"{_ftpUpdateDirPath}/{packetInfo.PackageName}"
        Dim newDataServiceVerDirPath As String = $"{_dsDirPath}\{packetInfo.LastVersion}"

        '检测本地包是否存在
        If Directory.Exists(_dsPacketDirPath) = False Then Directory.CreateDirectory(_dsPacketDirPath)
        If Directory.Exists(newDataServiceVerDirPath) = False Then Directory.CreateDirectory(newDataServiceVerDirPath)

        '下载FTP文件
        If File.Exists(localFilePath) = False Then
            ApplicationLog.WriteTraceLog($"Begin FtpDownloadFile...")
            If FtpDownloadFile(ftpFilePath, localFilePath) = False Then
                ApplicationLog.WriteErrorLog($"ftpPath:{ftpFilePath},localPath:{localFilePath},FtpDownloadFile Fail!")
                Return False
            End If
            ApplicationLog.WriteTraceLog($"ftpPath:{ftpFilePath},localPath:{localFilePath},FtpDownloadFile Success!")
        End If

        Thread.Sleep(2000)

        '更新包文件校验
        ApplicationLog.WriteTraceLog($"Begin CheckDataServicePacket...")
        If CheckDataServicePacket(localFilePath, packetInfo) = False Then
            '文件非法,删除下载文件
            ApplicationLog.WriteErrorLog($"CheckDataServicePacket Fail,Delete {localFilePath} File!")
            File.Delete(localFilePath)
            Return False
        End If
        ApplicationLog.WriteTraceLog($"CheckDataServicePacket Success!")

        Thread.Sleep(2000)

        '解压更新包
        ApplicationLog.WriteTraceLog($"Begin Uncompress {localFilePath} File To {newDataServiceVerDirPath}...")
        Try
            Compress.LoadFromZip(newDataServiceVerDirPath, localFilePath)
        Catch ex As Exception
            ApplicationLog.WriteErrorLog($"Uncompress Fail!{ex.Message}")
            Return False
        End Try

        ApplicationLog.WriteTraceLog($"Uncompress Success!")
        Thread.Sleep(2000)

        '安装服务
        If serviceExists = False Then
            ApplicationLog.WriteTraceLog($"Begin InstallService {newDataServiceVerDirPath}\{_dsName}...")
            Try
                WinService.InstallService($"{newDataServiceVerDirPath}\{_dsName}.exe", Nothing)
            Catch ex As Exception
                ApplicationLog.WriteErrorLog($"InstallService Fail,{ex.Message}")
                Return False
            End Try
        End If
        ApplicationLog.WriteTraceLog($"InstallService Success!")

        '启动服务
        ApplicationLog.WriteTraceLog($"Begin StartDataService...")
        If WinService.StartService(_dsName) = False Then
            ApplicationLog.WriteErrorLog($"StartDataService Fail!")
            Return False
        End If
        ApplicationLog.WriteTraceLog($"StartDataService Success!")

        _lastDsVersion = packetInfo.LastVersion
        _uploaded = True

        Return True
    End Function

#End Region

#Region "自动更新"
    ''' <summary> 初始化FTP服务类 </summary>
    Private _ftpClient As FtpService

    ''' <summary>Ftp远程升级文件夹路径</summary>
    Private ReadOnly _ftpUpdateDirPath As String = $"/uts_Manager/AUTS/Service"

    ''' <summary>
    ''' 判断本地与云端版本号是否一致,不一致则代表需要更新数据服务
    ''' </summary>
    ''' <param name="localVer">本地数据服务版本号</param>
    ''' <param name="remoteVer">远端数据服务版本号</param>
    ''' <returns></returns>
    Private Function NeedToUpdateService(localVer As String, remoteVer As String) As Boolean
        If String.IsNullOrWhiteSpace(localVer) OrElse String.IsNullOrWhiteSpace(remoteVer) Then
            ApplicationLog.WriteTraceLog($"Get Version Fail,LocalVer:{localVer},RemoteVer:{remoteVer}")
            Return False
        End If

        If String.Compare(localVer, remoteVer) = 0 Then
            ApplicationLog.WriteTraceLog($"No Need To Update DataService,LocalVer:{_dsVersion},RemoteVer:{remoteVer}")
            Return False
        End If

        Return True
    End Function


    ''' <summary>
    ''' Ftp下载文件
    ''' </summary>
    ''' <param name="ftpFilePath">Ftp文件路径</param>
    ''' <param name="localFilePath">本地文件路径</param>
    ''' <returns></returns>
    Private Function FtpDownloadFile(ftpFilePath As String, localFilePath As String) As Boolean
        ApplicationLog.WriteTraceLog($"soursePath:{ftpFilePath},targetPath:{localFilePath},Begin FtpDownloadFile...")

        Try
            _ftpClient.FtpDownload(ftpFilePath, localFilePath)
        Catch ex As Exception
            ApplicationLog.WriteErrorLog("Ftp DownloadFile Fail," & ex.Message)
            Return False
        End Try

        ApplicationLog.WriteTraceLog($"Ftp DownloadFile Success!")
        Return True
    End Function

    ''' <summary>
    ''' 校验数据服务包
    ''' </summary>
    ''' <param name="localFilePath">本地文件路径</param>
    ''' <param name="packetInfo">压缩包信息</param>
    ''' <returns></returns>
    Private Function CheckDataServicePacket(localFilePath As String, packetInfo As UpdatePackageInfo) As Boolean
        Try
            Dim localMd5 As String = Md5.GetFileMd5(localFilePath)
            Dim remoteMd5 As String = packetInfo.BinPackageMd5

            If String.Compare(localMd5, remoteMd5, True) <> 0 Then
                ApplicationLog.WriteErrorLog($"CheckDataServicePacket Fail!localMd5:{localMd5},remoteMd5:{remoteMd5}")
                Return False
            End If
        Catch ex As Exception
            ApplicationLog.WriteErrorLog($"CheckDataServicePacket Error:{ex.Message}")
            Return False
        End Try

        Return True
    End Function

#End Region

#Region "服务通讯"

    Private _tcpClient As AutsTcpClient

    ''' <summary> License检测 </summary>
    Private _license As License

    ''' <summary> User </summary>
    Private _user As String = "Admin"


    ''' <summary>
    ''' 初始化License内容
    ''' </summary>
    Private Function CheckLicense() As Boolean
        Try
            Dim licensePath As String = UtsRegistry.LicenseFilePath
            UTS_Core.DebugLog.ApplicationLog.WriteInfoLog($"Begin CheckLicense,Path:{licensePath}.")

            _license = New License(licensePath)
            _license.CheckLicense()

            UTS_Core.DebugLog.ApplicationLog.WriteInfoLog($"CheckLicense Success.")
        Catch ex As Exception
            UTS_Core.DebugLog.ApplicationLog.WriteErrorLog($"CheckLicense Error:{ex.Message}.")
            Return False
        End Try
        Return True
    End Function


    ''' <summary>
    ''' 获取服务版本信息
    ''' </summary>
    Public Function GetServiceLocalVersion() As Boolean
        Dim taskParam As New TaskJsonParam(TaskJsonParam.CmdNamesEnum.GetServiceVersion, _user, _usName)
        taskParam.ServiceVersion = _usVersion
        Return ServiceCommunicator(taskParam)
    End Function


    ''' <summary>
    ''' 初始化网络套接字
    ''' 注册表中无端口号时会引发异常
    ''' </summary>
    Private Function InitTcpClient() As Boolean
        Static remoteIp As String = "127.0.0.1"
        Static remotePort As Integer = -1 '默认55533,实际使用从注册表中获取

        Try
            If _tcpClient Is Nothing OrElse (_tcpClient.Connected() = False) Then
                remotePort = CInt(UtsRegistry.DataServicePort)
                _tcpClient = New AutsTcpClient(remoteIp, remotePort)
                _tcpClient.Open()
                ApplicationLog.WriteTraceLog($"InitTcpClient Success!")
            End If
        Catch ex As Exception
            ResetTcpConnection()
            If _serviceHeartBeatFailCount <= 1 Then '避免离线后大量重复数据
                ApplicationLog.WriteWarningLog($"InitTcpClient Error:{ex.Message}")
            End If
            Return False
        End Try

        Return True
    End Function


    ''' <summary>
    ''' 重启服务后，重置连接服务TCP标志位
    ''' </summary>
    Private Sub ResetTcpConnection()
        If _tcpClient IsNot Nothing Then
            _tcpClient.Dispose()
            _tcpClient = Nothing
        End If
    End Sub


    ''' <summary>
    ''' 与服务通讯,包含发送，接收，处理过程
    ''' </summary>
    ''' <param name="taskParam"></param>
    Private Function ServiceCommunicator(taskParam As TaskJsonParam) As Boolean
        Try
            Dim jsonString As String = TaskJsonParam.SerializeToJson(taskParam) & vbCrLf
            _tcpClient.WriteJsonString(jsonString)  '发送数据
        Catch ex As Exception
            ApplicationLog.WriteErrorLog($"Send jsonString Error:{ex.Message}")
            Return False
        End Try

        Dim replyString As String = _tcpClient.ReadJsonString()
        Try
            Dim replyParam As TaskJsonParam = CheckReplyString(replyString, taskParam.CmdName)  '接收数据校验

            If replyParam.CmdStatus = TaskJsonParam.CmdStatusEnum.Pass.ToString() Then
                DealFunction(replyParam)
            End If
        Catch ex As Exception
            ApplicationLog.WriteWarningLog($"CmdName:{taskParam.CmdName} Deal ReplyString Error:{ex.Message}")
            Return False
        End Try

        Return True
    End Function


    ''' <summary>
    ''' 校验回复字符串
    ''' </summary>
    ''' <param name="replyString"></param>
    ''' <param name="cmdName"></param>
    ''' <returns></returns>
    Private Function CheckReplyString(replyString As String, cmdName As TaskJsonParam.CmdNamesEnum) As TaskJsonParam
        If String.IsNullOrWhiteSpace(replyString) Then Return Nothing

        Dim replyParam As TaskJsonParam
        replyParam = TaskJsonParam.DeserializeFormJson(replyString)

        If replyParam.CmdName <> cmdName Then Return Nothing

        Return replyParam
    End Function


    ''' <summary>
    ''' 处理返回值
    ''' </summary>
    ''' <param name="replyParam"></param>
    Private Sub DealFunction(replyParam As TaskJsonParam)
        Select Case replyParam.CmdName
            Case TaskJsonParam.CmdNamesEnum.GetServiceVersion
                DealServiceVersion(replyParam)
        End Select

    End Sub

    ''' <summary>
    ''' 获取服务版本信息
    ''' </summary>
    ''' <param name="replyParam"></param>
    Private Sub DealServiceVersion(replyParam As TaskJsonParam)
        _dsVersion = replyParam.ServiceVersion
        _dsOnline = 1


        '更新失败计数
        If _uploaded = False Then Return

        If String.Compare(_dsVersion, _lastDsVersion) = 0 Then
            _uploaded = False
            ResetUpgradeFailCount()

            ApplicationLog.WriteTraceLog($"Upgrade DataService To {_lastDsVersion} Success!")
        Else
            _uploaded = False

            UpdateUpgradeFailCount()
        End If
    End Sub

#End Region

End Class
