| Pubblicazione File: CTcpManager Documento generato mediante: Documentation Creator By BGSoftware |
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "CTcpManager"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
' *********************************************************************
'* CLASS Manager utilizzabile per connettere due applicazioni differenti via IP
'* <BR/>Autore: <B>Giorgio Bernardi</B>
'* E-Mail: <A HREF="mailto:giorgio.bernardi@studio.unibo.it">Giorgio.Bernardi@studio.unibo.it</A>
'* Data : Settembre 2004
'* <DIV CLASS="ClassDescription">
'* Il manager funge da Server su porta TCP per ricevere i messaggi.
'* Il manager sfrutta l'invio di messaggi TCP per spedire i messaggi.
'* Il manager stabilisce un metodo per l'identificazione del Manager _
in modo che il nome <I>getAddress()</I> del Manager consenta di identificarlo in una rete di _
computer.
'* Il manager stabilisce altresì un formato di spedizione dei pacchetti TCP in modo che _
il destinatario possa comprenderlo ricreando a sua volta l'CEnvelope.
'* Ad ogni richiesta di invio di un messaggio il manager legge la lista di connessioni aperte _
per verificare se conosce il destinatario, altrimenti crea una nuova connessione.
'* Ad ogni richiesta di connessione dall'esterno, questa viene recuperata indicando che _
si conosce già il mittente.
'* <B>Importante:</B> le socket vanno chiuse esplicitamente altrimenti il GarbageCollector di _
Visual Basic le lascia aperte indefinitamente causando spiacevoli errori ed inconvenienti!
'* Usare il metodo <B>Destroy</B> per pulire tutto.
'* </DIV>
' *********************************************************************
Option Explicit
Implements IMsgManager
'* Variabile contenente il valore della proprietà omonima dell'oggetto
Private mDispatcher As IDispatcher
'* Variabile contenente il valore della proprietà omonima dell'oggetto
Private mManagers As Collection
'* Variabile contenente il valore della proprietà omonima dell'oggetto
Private mHostData As CRemoteHost
'* Socket Server usata per accettare le connessioni dall'esterno
Private WithEvents mServerSocket As CSocket
Attribute mServerSocket.VB_VarHelpID = -1
'* Porta di default per l'apertura di una nuova Socket server
Private Const mDEFAULT_PORT As Long = 5230
Private mstrLastError As String
'* Indica che l'indirizzo del manager potrebbe essere cambiato
Public Event OnAddressChange()
'* Descrizione dell'ultimo errore
Public Property Get LastError() As String
LastError = mstrLastError
End Property
'* Descrizione dell'ultimo errore
Private Property Let LastError(newValue As String)
mstrLastError = newValue
End Property
'* Gestisce l'errore
Private Sub GenerateError(Description As String, Optional Number As Long = vbObjectError)
LastError = Description
End Sub
'* Gestisce l'errore
Private Sub GenerateErrorGenerico(Procedure As String)
Call GenerateError("Errore non previsto in " & Procedure & vbCrLf & Err.Description, Err.Number)
End Sub
'* Identificativo dell'oggetto che si occuperà di indirizzare i messaggi ai destinatari
Public Property Get Dispatcher() As IDispatcher
Set Dispatcher = mDispatcher
End Property
'* Identificativo dell'oggetto che si occuperà di indirizzare i messaggi ai destinatari
Public Property Set Dispatcher(dsptchr As IDispatcher)
Set mDispatcher = dsptchr
End Property
'* Indirizzo logico del manager. Identifica il manager specificandolo in maniera univoca
'* L'indirizzo viene generato automaticamente alla creazione dell'oggetto.
Public Function getAddress() As String
getAddress = mHostData.toString()
End Function
'* Porta di ascolto per il manager
Public Function getPort() As Long
getPort = mHostData.Port
End Function
'* Porta di ascolto per il manager
Public Function setPort(newValue As Long)
mHostData.Port = newValue
RaiseEvent OnAddressChange
End Function
'* Indirizzo IP di ascolto per il manager
Public Function getLocalIpAddress() As String
getLocalIpAddress = mHostData.IP.toString()
End Function
'* Porta di ascolto per il manager
Public Function setLocalIpAddress(newValue As String)
mHostData.IP.fromString newValue
RaiseEvent OnAddressChange
End Function
'* La funzione ignora il MngAddress
'* Restituisce False se il manager non è nell'elenco dei manager registrati.
'* Se il manager destinazione è vuoto o è l'oggetto stesso, restituisce False se il Dispatcher non è stato specificato.
Public Function Send(Env As CEnvelope, ByVal MngAddress As String) As Boolean
Dim Index As Long
Dim PeerManagerSlave As CTcpManagerSlave
Send = False
'Informazioni di dispatching
If Env.TraceRoute Is Nothing Then Set Env.TraceRoute = New CEnvelopeTrace
Env.TraceRoute.RemoteMsgManagerAddress = Me.getAddress()
'Controllo se sono io
If (MngAddress = vbNullString) Or (MngAddress = getAddress()) Then
If Not Dispatcher Is Nothing Then
'Informazioni di dispatching
Set Env.TraceRoute.LocalMsgManager = Me
Send = Dispatcher.msgArrived(Env)
End If
Else
Set PeerManagerSlave = FindPeerServer(MngAddress)
If PeerManagerSlave Is Nothing Then
'Ne creo uno tentando di connettermi al pari
Set PeerManagerSlave = New CTcpManagerSlave
Debug.Print Me.getAddress & " Try to Connect to " & MngAddress
If Not PeerManagerSlave.StartConnecting(MngAddress, Me) Then
Debug.Print Me.getAddress & " Cannot Connect to " & MngAddress & "due to " & PeerManagerSlave.LastError
Call GenerateError("Error in Send:" & vbCrLf & PeerManagerSlave.LastError)
Exit Function
End If
'Lo aggiungo alla lista
Call mManagers.Add(PeerManagerSlave, MngAddress)
End If
'Inviare all'host indicato
Debug.Print "Socket state=" & PeerManagerSlave.Socket.State
Debug.Print Me.getAddress & " Send to " & MngAddress
Send = PeerManagerSlave.SendTCPMessage(Env)
End If
End Function
'* Recupera un elemento da una collection se esiste, altrimenti restituisce Nohting
Private Function FindPeerServer(MngAddress As String) As CTcpManagerSlave
On Error GoTo ErrorCatch
Set FindPeerServer = mManagers.Item(MngAddress)
Exit Function
ErrorCatch: Set FindPeerServer = Nothing
End Function
'* Funzione chiamata dagli slave in ascolto quando arriva un messaggio
Friend Sub MsgArrivedFromSlave(Env As CEnvelope, RemoteMsgManagerAddress As String)
If Not Dispatcher Is Nothing Then
'Informazioni di dispatching
If Env.TraceRoute Is Nothing Then Set Env.TraceRoute = New CEnvelopeTrace
Set Env.TraceRoute.LocalMsgManager = Me
Env.TraceRoute.RemoteMsgManagerAddress = RemoteMsgManagerAddress
Call Dispatcher.msgArrived(Env)
End If
End Sub
'* Indica il numero di manager conosciuti.
Public Function getKnownManagerNumber() As Long
getKnownManagerNumber = mManagers.Size
End Function
'* Permette di cominciare ad ascoltare sulla porta indicata i messaggi in ingresso
Public Function StartListenForMessages() As Boolean
Set mServerSocket = New CSocket
mServerSocket.LocalHost.Port = mHostData.Port
Call mServerSocket.LocalHost.IP.fromString(mHostData.IP.toString())
StartListenForMessages = mServerSocket.OpenServerConnection()
End Function
'* Permette di cominciare ad ascoltare sulla porta indicata i messaggi in ingresso
Public Sub StopListenForMessages()
If Not mServerSocket Is Nothing Then
mServerSocket.CloseSocket
Set mServerSocket = Nothing
End If
End Sub
Private Sub Class_Initialize()
Set mHostData = New CRemoteHost
mHostData.Port = mDEFAULT_PORT
Set mManagers = New Collection
End Sub
'* <B>IMPORTANTE</B>: Funzione che distrugge l'oggetto.
'* E' importante chiamare questa funzione perché il Garbage Collector di Visual Basic _
ritarda molto a pulire le risorse non più usate a causa dei riferimenti circolari.
Public Sub Destroy()
Dim PeerServer As CTcpManagerSlave
On Error Resume Next
'Server
If Not mServerSocket Is Nothing Then mServerSocket.CloseSocket
Set mServerSocket = Nothing
'Peers
If Not mManagers Is Nothing Then
For Each PeerServer In mManagers
PeerServer.CloseSocket
mManagers.Remove PeerServer
Set PeerServer = Nothing
Next
Set mManagers = Nothing
End If
'Altro
Set mDispatcher = Nothing
Set mHostData = Nothing
End Sub
Private Sub Class_Terminate()
Call Destroy
End Sub
Private Property Set IMsgManager_Dispatcher(RHS As IDispatcher)
Set Dispatcher = RHS
End Property
Private Property Get IMsgManager_Dispatcher() As IDispatcher
Set IMsgManager_Dispatcher = Dispatcher
End Property
Private Function IMsgManager_getAddress() As String
IMsgManager_getAddress = getAddress()
End Function
Private Function IMsgManager_Send(Env As CEnvelope, MngAddress As String) As Boolean
IMsgManager_Send = Send(Env, MngAddress)
End Function
Private Sub mServerSocket_OnConnectionRequest(ByVal requestID As Long)
Dim newSocket As New CSocket
Dim PeerManagerSlave As CTcpManagerSlave
If newSocket.Accept(requestID) Then
'Ne creo uno tentando di connettermi al pari
Set PeerManagerSlave = New CTcpManagerSlave
Debug.Print newSocket.RemoteHost.toString; " Try to Connect to me = " & Me.getAddress
Call PeerManagerSlave.StartListening(newSocket, Me, newSocket.RemoteHost.toString())
'Lo aggiungo alla lista
Call mManagers.Add(PeerManagerSlave, newSocket.RemoteHost.toString)
End If
End Sub
|
Documento generato mediante: Documentation Creator By BGSoftware |