(LINUX) LINUX (2022)

Monitoring docker events


This project allow immediately receive ContainerID from Docker when Docker Events fired. Project uploaded to Github https://github.com/Alex-1557/DockerMonitor and use my Async SSH library https://github.com/Alex-1557/SshEngine2.


   1:  Imports System
   2:  Imports System.ComponentModel
   3:  Imports System.Diagnostics.Metrics
   4:  Imports System.Runtime.ExceptionServices
   5:  Imports System.Threading
   6:  Imports BackendAPI
   7:  Imports BackendAPI.Docker
   8:  Imports BackendAPI.Helper
   9:  Imports BackendAPI.Model
  10:  Imports BackendAPI.Services
  11:  Imports BackendAPI.Vm
  12:  Imports DockerMonitor.Helper
  13:  Imports Microsoft.AspNetCore.Components.RenderTree
  14:  Imports Microsoft.AspNetCore.Mvc
  15:  Imports Microsoft.EntityFrameworkCore
  16:  Imports Microsoft.Extensions.Configuration
  17:  Imports Microsoft.Net.Http
  18:  Imports MySqlConnector
  19:   
  20:  Module Program
  21:      Dim ClearCN As String
  22:      Dim ClearVmPass As String
  23:      Dim DockerHubVm As Integer
  24:      Dim _DB As ApplicationDbContext
  25:      Dim VmI As Integer
  26:      Dim ProjectAes As AesCryptor
  27:      Dim CN As MySqlConnection
  28:      Dim OptionsBuilder As DbContextOptionsBuilder(Of ApplicationDbContext)
  29:      Dim BackendBaseURL As String
  30:      Dim ContainerStart As String
  31:      Dim ContainerStop As String
  32:      Dim LogDockerEvents As String
  33:      Dim LogDockerEventArr As String()
  34:      Dim LogSshError As Boolean
  35:      Dim SendBackendNotification As Boolean
  36:   
  37:      Sub Main(args As String())
  38:   
  39:          Dim CurDomain As AppDomain = AppDomain.CurrentDomain
  40:          AddHandler CurDomain.FirstChanceException, AddressOf FirstChanceException
  41:          AddHandler CurDomain.UnhandledException, AddressOf UnhandledException
  42:   
  43:          Dim Config As IConfiguration = New ConfigurationBuilder().
  44:              AddJsonFile("appsettings.json").
  45:              AddEnvironmentVariables().
  46:              Build()
  47:          Dim CryptoCN = Config.GetConnectionString("DefaultConnection")
  48:          DockerHubVm = Config.GetValue(Of Integer)("DockerHubVm:ID")
  49:          Dim CryptoPass = Config.GetValue(Of String)("DockerHubVm:VmConnectionDecryptPass")
  50:          LogDockerEvents = Config.GetValue(Of String)("Output:LogDockerEvents")
  51:          LogDockerEventArr = LogDockerEvents.Split(",")
  52:          LogSshError = Config.GetValue(Of Boolean)("Output:LogSshError")
  53:          SendBackendNotification = Config.GetValue(Of Boolean)("Output:SendBackendNotification")
  54:          BackendBaseURL = Config.GetValue(Of String)("Backend:BaseURL")
  55:          ContainerStart = Config.GetValue(Of String)("Backend:ContainerStart")
  56:          ContainerStop = Config.GetValue(Of String)("Backend:ContainerStop")
  57:          NotificationTokenLogin = Config.GetValue(Of String)("NotificationToken:Login")
  58:          NotificationTokenPass = Config.GetValue(Of String)("NotificationToken:Password")
  59:   
  60:          ProjectAes = New AesCryptor
  61:   
  62:          ClearCN = ProjectAes.DecryptSqlConnection(CryptoCN, "bGVubWF4")
  63:          OptionsBuilder = New DbContextOptionsBuilder(Of ApplicationDbContext)
  64:          OptionsBuilder.UseMySql(ClearCN,
  65:                                  ServerVersion.Parse("10.5.9-MariaDB-1:10.5.9+maria~xenial"), 'SHOW VARIABLES LIKE "%version%";
  66:                                  Sub(ByVal mySqlOption As Microsoft.EntityFrameworkCore.Infrastructure.MySqlDbContextOptionsBuilder)
  67:                                      mySqlOption.CommandTimeout(10)
  68:                                      mySqlOption.EnableRetryOnFailure(10)
  69:                                  End Sub)
  70:          _DB = New ApplicationDbContext(OptionsBuilder.Options)
  71:          CN = _DB.Database.GetDbConnection()
  72:          CN.Open()
  73:   
  74:          If _DB.Database.GetDbConnection().State = Data.ConnectionState.Open Then
  75:              Console.Write($"Started for DockerHub {DockerHubVm}, Db opened, ")
  76:          End If
  77:   
  78:          Dim CurDockerHub = _DB.RawSqlQuery(Of Integer)($"SELECT ToVM FROM DockerHubVm Where i={DockerHubVm};", Function(X) X("ToVm"))
  79:          If CurDockerHub.Item2 Is Nothing Then
  80:              VmI = CurDockerHub.Item1(0)
  81:          Else
  82:              Console.WriteLine(CurDockerHub.Item2.ToString)
  83:              Stop
  84:          End If
  85:   
  86:          _DB = New ApplicationDbContext(OptionsBuilder.Options)
  87:          CN = _DB.Database.GetDbConnection()
  88:          CN.Open()
  89:          Dim CurrentVM = Sql.ExecRDR(Of TmpVmAccess)(_DB, $"SELECT Name, AdminLogin, aes_decrypt(AdminPassword,'{CryptoPass}') as DecryptedPass  FROM `VM` where i={VmI};",
  90:                                                     Function(X)
  91:                                                         Return New TmpVmAccess With {
  92:                                                         .Name = X("Name"),
  93:                                                         .AdminLogin = X("AdminLogin"),
  94:                                                         .AdminPassword = If(IsDBNull(X("DecryptedPass")), "", Text.UTF8Encoding.UTF8.GetString(X("DecryptedPass")))
  95:                                                         }
  96:                                                     End Function)
  97:          If CurrentVM.Count = 0 Then
  98:              Console.WriteLine($"Vm {VmI} absent")
  99:              Stop
 100:          Else
 101:              Console.Write($"VmName {CurrentVM(0).Name}, ")
 102:          End If
 103:   
 104:  Bash:
 105:          _DB = New ApplicationDbContext(OptionsBuilder.Options)
 106:          CN = _DB.Database.GetDbConnection()
 107:          CN.Open()
 108:          Dim Vm As New VmBashAsync2(_DB, ProjectAes, CurrentVM(0).Name, CryptoPass)
 109:          Dim Connect = Vm.SSHServerConnect()
 110:          If Connect.Item1 IsNot Nothing Then
 111:              Console.WriteLine("Vm terminal opened. Waiting docker events....")
 112:              Dim Ret1 = Vm.Bash($"sudo -S <<< ""{CurrentVM(0).AdminPassword.Replace("$", "\$")}"" sudo docker events", New Threading.CancellationTokenSource, AddressOf NewLine, AddressOf ErrLine)
 113:              Ret1.Wait()
 114:              ' this command never ended, only with error in NewLine/SaveLogToDb/Inspect/SendNotification or any another place<<<---
 115:              Console.WriteLine($"{Now} Unexpected stop. Restarted")
 116:              'Task.Delay(10000).Wait()
 117:              GoTo Bash
 118:          Else
 119:              Console.WriteLine($"Not connected. Restart. SSH ={Connect.Item2?.Message}, DB ={Connect.Item3?.Message}")
 120:              Stop
 121:          End If
 122:      End Sub
 123:      Sub UnhandledException(sender As Object, e As UnhandledExceptionEventArgs)
 124:          Console.WriteLine((CType(e.ExceptionObject, Exception).Message))
 125:      End Sub
 126:      Sub FirstChanceException(sender As Object, e As FirstChanceExceptionEventArgs)
 127:          Console.WriteLine(e.Exception.Message)
 128:      End Sub
 129:   
 130:      Sub NewLine(sender As Object, e As KeyValuePair(Of Integer, String))
 131:          Debug.WriteLine($"{e.Key}:{e.Value}")
 132:          SaveLogToDb(sender, e, AddressOf Inspect)
 133:      End Sub
 134:   
 135:      Sub ErrLine(sender As Object, e As KeyValuePair(Of Integer, String))
 136:          Debug.WriteLine($"Error {e.Key}:{e.Value}")
 137:          If LogSshError Then
 138:              SaveLogToDb(sender, e, Nothing)
 139:          End If
 140:      End Sub
 141:   
 142:      Sub SaveLogToDb(sender As Object, e As KeyValuePair(Of Integer, String), SendNotification As EventHandler(Of String))
 143:          Dim Lines As String() = e.Value.Split(vbLf)
 144:          For i As Integer = 0 To Lines.Count - 1
 145:              If Not String.IsNullOrWhiteSpace(Lines(i)) Then
 146:                  If LogDockerEvents = "All" Then
 147:                      GoTo Write
 148:                  Else
 149:                      For j As Integer = 0 To LogDockerEventArr.Count - 1
 150:                          If Lines(i).Contains(LogDockerEventArr(j)) Then
 151:                              GoTo Write
 152:                          End If
 153:                      Next
 154:                      Continue For
 155:                  End If
 156:  Write:
 157:                  _DB = New ApplicationDbContext(OptionsBuilder.Options)
 158:                  CN = _DB.Database.GetDbConnection()
 159:                  CN.Open()
 160:                  Sql.ExecNonQuery(_DB, $"INSERT INTO `DockerEvents`(`toDockerHub`,`j`,`Event`) VALUES ({DockerHubVm},{e.Key},'{Lines(i).Replace("'", "^").Replace("`", "^")}');")
 161:                  If SendNotification IsNot Nothing Then
 162:                      If SendBackendNotification Then
 163:                          SendNotification.Invoke(sender.ToString, Lines(i))
 164:                      End If
 165:                  End If
 166:              End If
 167:          Next
 168:      End Sub
 169:   
 170:      '2022-09-10T09:14:36.909917942+02:00 container create ecfdaa3352c22c5f8b851d2d24cc00c1b56108aacaeb67931322dd6c573ccc19 (image=busybox, name=busybox.2022-09-10-09.14.36.d5002f29-f7e8-48b8-bd4e-c9e6e6c4397c)
 171:      '2022-09-10T17:56:46.731982177+02:00 container die a0fd089078f9974df0d4d28053adb4e3091701ec1b06bb1d3dc44a3b00bf733f (exitCode=0, image=busybox, name=busybox.2022-09-10-17.56.46.d717cc89-77b7-425d-baea-45690bbb5e96)
 172:      Sub Inspect(sender As Object, e As String)
 173:          Dim Items As String() = e.Split(" ")
 174:          If Items.Count >= 0 Then
 175:              If Items(1) = "container" And Items(2) = "start" Then
 176:                  SendNotification(ContainerStart, Items(3), Items(5).Replace(vbLf, ""), Items(0).Replace(vbLf, ""))
 177:              ElseIf Items(1) = "container" And Items(2) = "die" Then
 178:                  SendNotification(ContainerStop, Items(3), Items(6).Replace(vbLf, ""), Items(0).Replace(vbLf, ""))
 179:              End If
 180:          End If
 181:      End Sub
 182:   
 183:      Private NotificationTokenLogin As String
 184:      Private NotificationTokenPass As String
 185:      Private Request As MyWebClient
 186:      Private Counter As Integer
 187:      Private RequestWebRequest As New Object
 188:      Sub SendNotification(URL As String, ContainerID As String, Name As String, Time As String)
 189:          Task.Run(Sub()
 190:                       Interlocked.Increment(Counter)
 191:                       SyncLock RequestWebRequest
 192:                           Dim FullUrl As String = $"{URL}?ID={ContainerID}&{Name.Replace(")", "")}&Time={Time}&N={Counter}"
 193:                           Try
 194:                               Request = New MyWebClient
 195:                               Request.BaseAddress = BackendBaseURL
 196:                               Request.Headers.Add("Content-Type", "application/json")
 197:                               Dim Token = GetNotificationToken(Request, NotificationTokenLogin, NotificationTokenPass)
 198:                               Request.Headers.Clear()
 199:                               Request.Headers.Add("Authorization", "Bearer: " & Token)
 200:                               Request.Headers.Add("Content-Type", "application/json")
 201:                               While (Request.IsBusy)
 202:                                   Task.Delay(1000).Wait()
 203:                               End While
 204:                               Dim Response As String = Request.DownloadString(FullUrl)
 205:                               Console.WriteLine($"Notification {Request.BaseAddress}/{FullUrl} - {Response}") '"OkObjectResult"/"ObjectResult"
 206:                           Catch ex As Exception
 207:                               Console.WriteLine($"Notification {Request.BaseAddress}/{FullUrl} Failed. {ex.Message}")
 208:                           End Try
 209:                       End SyncLock
 210:                   End Sub)
 211:      End Sub
 212:  End Module
 213:   
 214:  Class TmpVmAccess
 215:      Property AdminLogin As String
 216:      Property AdminPassword As String
 217:      Property Name As String
 218:  End Class

Project use a number of tables woth description of server, VM and Docker.



Result of this program is log to console and DB.



Than project use engine similar to https://www.vb-net.com/SshQueueNotificationServer/Index.htm and send notification to Backend API.


   1:  Imports System.IO
   2:  Imports System.Text
   3:  Imports BackendAPI.Helper
   4:  Imports BackendAPI.KVM
   5:  Imports BackendAPI.Model
   6:  Imports BackendAPI.Notification
   7:  Imports BackendAPI.Services
   8:  Imports Microsoft.AspNetCore.Http
   9:  Imports Microsoft.AspNetCore.Mvc
  10:  Imports Microsoft.AspNetCore.SignalR
  11:  Imports Microsoft.EntityFrameworkCore
  12:  Imports Microsoft.Extensions.Configuration
  13:  Imports Microsoft.Extensions.Logging
  14:  Imports Newtonsoft.Json.Linq
  15:   
  16:  Namespace WebApi.Controllers
  17:   
  18:      <ApiController>
  19:      <Route("[controller]/[action]")>
  20:      Public Class NotificationController
  21:          Inherits ControllerBase
  22:   
  23:          Private ReadOnly _Log As ILogger(Of NotificationController)
  24:          Private ReadOnly _Aes As AesCryptor
  25:          Private ReadOnly _DB As ApplicationDbContext
  26:          Private ReadOnly _UserService As IUserService
  27:          Private ReadOnly _httpContextAccessor As IHttpContextAccessor
  28:          Private ReadOnly _Trace As Boolean
  29:          Private ReadOnly _WithResult As Boolean
  30:          Private ReadOnly _NotificationCache As INotificationCacheService
  31:          Private ReadOnly _NotificationHub As IHubContext(Of NotificationHub)
  32:          Private ReadOnly _DockerEventsHubCollectorService As IDockerEventsHubCollectorService
  33:          Private ReadOnly _DockerEventsHub As IHubContext(Of DockerEventsHub)
  34:          Sub New(ByVal UserService As IUserService, Cryptor As IAesCryptor, DbContext As ApplicationDbContext, DockerEventsHubCollectorService As IDockerEventsHubCollectorService, NotificationHub As IHubContext(Of NotificationHub), DockerEventsHub As IHubContext(Of DockerEventsHub), httpContextAccessor As IHttpContextAccessor, Logger As ILogger(Of NotificationController), Configuration As IConfiguration, NotificationService As INotificationCacheService)
  35:              _Aes = Cryptor
  36:              _DB = DbContext
  37:              _Log = Logger
  38:              _UserService = UserService
  39:              _httpContextAccessor = httpContextAccessor
  40:              _Trace = Configuration.GetValue(Of Boolean)("TraceAPI:Trace")
  41:              _WithResult = Configuration.GetValue(Of Boolean)("TraceAPI:Trace")
  42:              _NotificationCache = NotificationService
  43:              _NotificationHub = NotificationHub
  44:              _DockerEventsHubCollectorService = DockerEventsHubCollectorService
  45:              _DockerEventsHub = DockerEventsHub
  46:          End Sub
  47:   
  ..:   
 290:          <State("Ok. Finished.")>
 291:          <Jwt.Authorize>
 292:          <HttpGet>
 293:          Public Function ListAllDockerEventsConnectionToHub() As IActionResult
 294:              Dim CurUsers = _UserService.GetCurrentUser(_httpContextAccessor.HttpContext.Request.Headers("JwtUserName")(0))
 295:              If CurUsers.IsAdmin Or CurUsers.UserName = "Notification" Then
 296:                  Return Ok(_DockerEventsHubCollectorService.PrintSignalRConnectionKeys)
 297:              Else
 298:                  Return New JsonResult(Unauthorized())
 299:              End If
 300:          End Function
 301:   
 302:          <State("Ok. Finished.")>
 303:          <Jwt.Authorize>
 304:          <HttpGet>
 305:          Public Async Function NotifyAllDockerEventsClientsTST() As Task(Of IActionResult)
 306:              Dim CurUsers = _UserService.GetCurrentUser(_httpContextAccessor.HttpContext.Request.Headers("JwtUserName")(0))
 307:              If CurUsers.IsAdmin Or CurUsers.UserName = "Notification" Then
 308:                  Dim SignalRTSK = _DockerEventsHub.Clients.All.SendAsync("TestDockerEvents", New DockerEventsMesssage With {.Time = Now})
 309:                  Await SignalRTSK
 310:                  Return Ok(New With {.SignalRStatus = SignalRTSK.Status.ToString, .AllSignalRConnectionKeys = _DockerEventsHubCollectorService.PrintSignalRConnectionKeys})
 311:              Else
 312:                  Return New JsonResult(Unauthorized())
 313:              End If
 314:          End Function
 315:   
 316:          <State("Ok. Finished.")>
 317:          <Jwt.Authorize>
 318:          <HttpGet>
 319:          Public Async Function NotifyOneDockerEventsClientTST(ConnectionID As String) As Task(Of IActionResult)
 320:              Dim CurUsers = _UserService.GetCurrentUser(_httpContextAccessor.HttpContext.Request.Headers("JwtUserName")(0))
 321:              If CurUsers.IsAdmin Or CurUsers.UserName = "Notification" Then
 322:                  Dim SignalRTSK = _DockerEventsHub.Clients.Client(ConnectionID).SendAsync("TestDockerEvents", New DockerEventsMesssage With {.Time = Now})
 323:                  Await SignalRTSK
 324:                  Return Ok(New With {.SignalRStatus = SignalRTSK.Status.ToString, .AllSignalRConnectionKeys = _DockerEventsHubCollectorService.PrintSignalRConnectionKeys})
 325:              Else
 326:                  Return New JsonResult(Unauthorized())
 327:              End If
 328:          End Function
 329:   
 330:          <State("Ok. Finished.")>
 331:          <Jwt.Authorize>
 332:          <HttpGet>
 333:          Public Async Function ContainerStart(ID As String, name As String, Time As String, N As Integer) As Task(Of IActionResult)
 334:              Dim CurUsers = _UserService.GetCurrentUser(_httpContextAccessor.HttpContext.Request.Headers("JwtUserName")(0))
 335:              If CurUsers.IsAdmin Or CurUsers.UserName = "Notification" Then
 336:                  Dim SignalRTSK = _DockerEventsHub.Clients.All.SendAsync("ContainerStart", New DockerEventsMesssage With {.ContainerID = ID, .Name = name, .Time = Time, .N = N})
 337:                  Await SignalRTSK
 338:                  Return Ok(New With {.SignalRStatus = SignalRTSK.Status.ToString, .AllSignalRConnectionKeys = _DockerEventsHubCollectorService.PrintSignalRConnectionKeys})
 339:              Else
 340:                  Return New JsonResult(Unauthorized())
 341:              End If
 342:          End Function
 343:   
 344:          <State("Ok. Finished.")>
 345:          <Jwt.Authorize>
 346:          <HttpGet>
 347:          Public Async Function ContainerStop(ID As String, name As String, Time As String, N As Integer) As Task(Of IActionResult)
 348:              Dim CurUsers = _UserService.GetCurrentUser(_httpContextAccessor.HttpContext.Request.Headers("JwtUserName")(0))
 349:              If CurUsers.IsAdmin Or CurUsers.UserName = "Notification" Then
 350:                  Dim SignalRTSK = _DockerEventsHub.Clients.Client(ID).SendAsync("ContainerStop", New DockerEventsMesssage With {.ContainerID = ID, .Name = name, .Time = Time, .N = N})
 351:                  Await SignalRTSK
 352:                  Return Ok(New With {.SignalRStatus = SignalRTSK.Status.ToString, .AllSignalRConnectionKeys = _DockerEventsHubCollectorService.PrintSignalRConnectionKeys})
 353:              Else
 354:                  Return New JsonResult(Unauthorized())
 355:              End If
 356:          End Function
 357:   
 358:      End Class
 359:  End Namespace

This is service to collect docker events.


   57:          Services.AddSingleton(Of IDockerEventsHubCollectorService, DockerEventsHubCollectorService)

   1:  Imports BackendAPI.Notification
   2:   
   3:  Public Interface IDockerEventsHubCollectorService
   4:      Function AddSignalRClientConnection(ConnectionID As String, UserId As Integer) As Boolean
   5:      Function DelSignalRClientConnection(ConnectionID As String) As Boolean
   6:      Function AllSignalRClientConnection() As MyConcurrentDictionary(Of String, Integer)
   7:      Function PrintSignalRConnectionKeys() As String
   8:  End Interface
   9:   

   1:  Imports System.Threading
   2:  Imports BackendAPI.Model
   3:  Imports BackendAPI.Notification
   4:  Imports BackendAPI.Services
   5:  Imports Microsoft.AspNetCore.SignalR
   6:  Imports Microsoft.Extensions.Logging
   7:   
   8:  Public Class DockerEventsHubCollectorService
   9:      Implements IDockerEventsHubCollectorService
  10:   
  11:      Private ReadOnly _DB As ApplicationDbContext
  12:      Private ReadOnly _Log As ILogger(Of DockerEventsHubCollectorService)
  13:      Private ClientConnections As MyConcurrentDictionary(Of String, Integer)
  14:      Private ReadOnly _DockerEventsHub As IHubContext(Of DockerEventsHub)
  15:      Private Counter As Integer
  16:   
  17:      Public Sub New(DbContext As ApplicationDbContext, Logger As ILogger(Of DockerEventsHubCollectorService), DockerEventsHub As IHubContext(Of DockerEventsHub))
  18:          ClientConnections = New MyConcurrentDictionary(Of String, Integer)
  19:          _DB = DbContext
  20:          _Log = Logger
  21:          _DockerEventsHub = DockerEventsHub
  22:      End Sub
  23:      Public Function AddSignalRClientConnection(ConnectionID As String, UserId As Integer) As Boolean Implements IDockerEventsHubCollectorService.AddSignalRClientConnection
  24:          Interlocked.Increment(Counter)
  25:          Return ClientConnections.TryAdd(ConnectionID, UserId)
  26:      End Function
  27:      Public Function DelSignalRClientConnection(ConnectionID As String) As Boolean Implements IDockerEventsHubCollectorService.DelSignalRClientConnection
  28:          Interlocked.Increment(Counter)
  29:          Dim Record = ClientConnections.Where(Function(x) x.Key = ConnectionID).ToList
  30:          If Record.Count > 0 Then
  31:              Return ClientConnections.TryRemove(ConnectionID, Record(0).Value)
  32:          Else
  33:              Return False
  34:          End If
  35:      End Function
  36:      Public Function AllSignalRClientConnection() As MyConcurrentDictionary(Of String, Integer) Implements IDockerEventsHubCollectorService.AllSignalRClientConnection
  37:          Interlocked.Increment(Counter)
  38:          Return ClientConnections
  39:      End Function
  40:      Public Function PrintSignalRConnectionKeys() As String Implements IDockerEventsHubCollectorService.PrintSignalRConnectionKeys
  41:          Interlocked.Increment(Counter)
  42:          Return ClientConnections.PrintKeys
  43:      End Function
  44:   
  45:  End Class

And this is definition of SignalR hub to send notification to frontend.


  27:      Public Sub ConfigureServices(ByVal Services As IServiceCollection)
  ..:   
  61:          Services.AddSignalR().
  62:                  AddHubOptions(Of NotificationHub)(Sub(options)
  63:                                                        options.EnableDetailedErrors = True
  64:                                                    End Sub).
  65:                  AddHubOptions(Of DockerEventsHub)(Sub(options)
  66:                                                        options.EnableDetailedErrors = True
  67:                                                    End Sub)
  ..:   
  78:      Public Sub Configure(ByVal App As IApplicationBuilder, ByVal Env As IWebHostEnvironment, RequestLoggerFactory As ILoggerFactory)
  ..:   
 114:          App.UseEndpoints(Sub(endpoints)
 115:                               endpoints.MapHub(Of NotificationHub)("/NotificationHub", Sub(opt)
 116:                                                                                            opt.Transports =
 117:                                                                                          HttpTransportType.WebSockets Or
 118:                                                                                          HttpTransportType.LongPolling
 119:                                                                                        End Sub)
 120:                               endpoints.MapHub(Of DockerEventsHub)("/DockerEventsHub", Sub(opt)
 121:                                                                                            opt.Transports =
 122:                                                                                          HttpTransportType.WebSockets Or
 123:                                                                                          HttpTransportType.LongPolling
 124:                                                                                        End Sub)
 125:                           End Sub)
 126:   
 127:      End Sub
 128:  End Class

This is definition of SignalR hub.


   1:  Namespace Notification
   2:      Public Interface IHubDockerEventsMesssage
   3:          Function NotifyAllClient(msg As DockerEventsMesssage) As Task
   4:          Function NotifyClient(ClientId As Integer, msg As DockerEventsMesssage) As Task
   5:      End Interface
   6:  End Namespace
   7:   

   1:  Imports BackendAPI.Model
   2:  Imports BackendAPI.Services
   3:  Imports Microsoft.AspNetCore.Http
   4:  Imports Microsoft.AspNetCore.SignalR
   5:  Imports Microsoft.Extensions.Configuration
   6:  Imports Microsoft.Extensions.Logging
   7:  Imports Microsoft.Extensions.Options
   8:   
   9:  Namespace Notification
  10:      Public Class DockerEventsHub
  11:          Inherits Hub(Of IHubDockerEventsMesssage)
  12:   
  13:   
  14:          Private ReadOnly _logger As ILogger(Of DockerEventsHub)
  15:          Private ReadOnly _DockerEventsHubCollectorService As IDockerEventsHubCollectorService
  16:          Private ReadOnly _Aes As AesCryptor
  17:          Private ReadOnly _DB As ApplicationDbContext
  18:          Private ReadOnly _UserService As IUserService
  19:          Private ReadOnly _httpContextAccessor As IHttpContextAccessor
  20:          Private ReadOnly _Trace As Boolean
  21:          Private ReadOnly _WithResult As Boolean
  22:          Private ReadOnly _JwtSettings As Jwt.JwtSettings
  23:   
  24:          Public ReadOnly Property ListAllConnections As MyConcurrentDictionary(Of String, Integer)
  25:              Get
  26:                  Return _DockerEventsHubCollectorService.AllSignalRClientConnection
  27:              End Get
  28:          End Property
  29:   
  30:          Public Sub New(logger As ILogger(Of DockerEventsHub), AppSettings As IOptions(Of Jwt.JwtSettings), DockerEventsHubCollectorService As IDockerEventsHubCollectorService, UserService As IUserService, Cryptor As IAesCryptor, DbContext As ApplicationDbContext, httpContextAccessor As IHttpContextAccessor, Configuration As IConfiguration)
  31:              _logger = logger
  32:              _DockerEventsHubCollectorService = DockerEventsHubCollectorService
  33:              _Aes = Cryptor
  34:              _DB = DbContext
  35:              _UserService = UserService
  36:              _httpContextAccessor = httpContextAccessor
  37:              _Trace = Configuration.GetValue(Of Boolean)("TraceAPI:Trace")
  38:              _WithResult = Configuration.GetValue(Of Boolean)("TraceAPI:Trace")
  39:              _JwtSettings = AppSettings.Value
  40:          End Sub
  41:   
  42:          'after new
  43:          Public Overrides Async Function OnConnectedAsync() As Task
  44:              Dim JWTToken As String = Context.GetHttpContext().Request.Headers("Authorization")
  45:              Dim ValidUserID As String = ""
  46:              Try
  47:                  ValidUserID = Jwt.ValidateJWT(JWTToken, _JwtSettings)
  48:              Catch e As Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException
  49:                  _logger.LogInformation("token experied")
  50:              End Try
  51:   
  52:              If ValidUserID IsNot Nothing Then
  53:                  _DockerEventsHubCollectorService.AddSignalRClientConnection(Context.ConnectionId, ValidUserID)
  54:                  _logger.LogInformation($"User {ValidUserID} connected to {Me.[GetType].Name} hub, ConnectionId={Context.ConnectionId}")
  55:              Else
  56:                  _logger.LogInformation("WrongToken")
  57:              End If
  58:              Await MyBase.OnConnectedAsync()
  59:          End Function
  60:   
  61:          'after new Again
  62:          Public Overrides Async Function OnDisconnectedAsync(ByVal Exception As System.Exception) As Task
  63:              _logger.LogInformation("OnDisconnectedAsync" & Exception?.Message)
  64:   
  65:              Dim JWTToken As String = Context.GetHttpContext().Request.Headers("Authorization")
  66:              Dim ValidUserID As String = ""
  67:   
  68:              Try
  69:                  ValidUserID = Jwt.ValidateJWT(JWTToken, _JwtSettings)
  70:              Catch e As Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException
  71:                  _logger.LogInformation("token experied")
  72:              End Try
  73:   
  74:              If ValidUserID IsNot Nothing Then
  75:                  _DockerEventsHubCollectorService.DelSignalRClientConnection(Context.ConnectionId)
  76:                  _logger.LogInformation($"User {ValidUserID} disconnected from {Me.[GetType]().Name} hub, ConnectionId={Context.ConnectionId}")
  77:              Else
  78:                  _logger.LogInformation("WrongToken")
  79:              End If
  80:   
  81:              Await MyBase.OnDisconnectedAsync(Exception)
  82:          End Function
  83:   
  84:      End Class
  85:  End Namespace

Project can deployed in remote server, not in local machine with docker.



Comments ( )
Link to this page: http://www.vb-net.com/DockerMonitor/Index.htm
< THANKS ME>