| Pubblicazione File: CDynamicStub 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 = "CDynamicStub"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
' *********************************************************************
'* CLASS Stub di base con chiamate dinamiche funzionante per una qualsiasi classe
'* <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">
'* Questo Stub può essere utilizzato per ogni oggetto in quanto contiene chiamate _
standard grazie all'utilizzo del costrutto linguistico di Visual Basisc <I>ParamArray</I>.
'* Creare una istanza di questa classe e chiamare la funzione <B>CallRemoteFunction</B> specificando _
i parametri necessari.
'* E' possibile usare la classe indicando di non attendere il risultato delle funzioni e poi _
recuperare il risultato stesso in modalità polling tramite le funzioni <B>IsResultArrived</B> e _
<B>GetResult</B>.
'* </DIV>
' *********************************************************************
Option Explicit
Implements IReceiver 'Necessario per le funzioni
Implements ISender 'Necessario
'* Dispatcher al quale inviare le richieste
Private mDispatcher As IDispatcher
'* Indirizzo di ricezione del manager remoto
Private mstrRemoteMsgManagerAddress As String
'* Indirizzo di ricezione dello Skeleton remoto
Private mstrSkeletonObjectID As String
'* Collezione dei risultati delle funzioni attualmente disponibili
Private Risultati As Collection
'* Variabile contenente il valore della proprietà omonima
Private mstrObjectID As String
'* Milli-Secondi dopo il quale scatterà il timeout se non giunge il risultato della chiamata a funzione
Private mlngTimeOutMilliSeconds As Long
'* TimeOut di default applicato all'inizializzazione della classe
Private Const DEFAULT_TIMEOUT_MILLI_SECONDS = 10000
Private Sub Class_Initialize()
Set Risultati = New Collection
Me.TimeOutMilliSeconds = DEFAULT_TIMEOUT_MILLI_SECONDS
End Sub
'* Restituisce l'identificativo univoco all'interno della applicazione remota dello skeleton di destinazione
Public Property Get RemoteSkeletonID() As String
RemoteSkeletonID = mstrSkeletonObjectID
End Property
'* Restituisce l'identificativo univoco all'interno della applicazione remota dello skeleton di destinazione
Public Property Let RemoteSkeletonID(Value As String)
mstrSkeletonObjectID = Value
End Property
'* Indirizzo di ricezione del manager remoto
Public Property Get RemoteMsgManagerAddress() As String
RemoteMsgManagerAddress = mstrRemoteMsgManagerAddress
End Property
'* Indirizzo di ricezione del manager remoto
Public Property Let RemoteMsgManagerAddress(Value As String)
mstrRemoteMsgManagerAddress = Value
End Property
'* Secondi dopo il quale scatterà il timeout se non giunge il risultato della chiamata a funzione
'* <B>ATTENZIONE:</B> in questa implementazione Visual Basic viene usata una precisione al centesimo di secondo, non al millesimo! Impostare valori multipli di 10!
Public Property Get TimeOutMilliSeconds() As Long
TimeOutMilliSeconds = mlngTimeOutMilliSeconds
End Property
'* Secondi dopo il quale scatterà il timeout se non giunge il risultato della chiamata a funzione
'* <B>ATTENZIONE:</B> in questa implementazione Visual Basic viene usata una precisione al centesimo di secondo, non al millesimo! Impostare valori multipli di 10!
Public Property Let TimeOutMilliSeconds(Value As Long)
mlngTimeOutMilliSeconds = Value
End Property
'* Restituisce l'identificativo univoco all'interno di questa applicazione dell'oggetto
Public Property Get StubID() As String
StubID = mstrObjectID
End Property
'* Restituisce l'identificativo univoco all'interno di questa applicazione dell'oggetto
Public Property Let StubID(Value As String)
mstrObjectID = Value
End Property
'* Verifica se è arrivato il risultato della richiesta
Public Function IsResultArrived(ProcedureInstanceID As String) As Boolean
On Error GoTo ErrorCatch
If Not Risultati.Item(ProcedureInstanceID) Is Nothing Then IsResultArrived = True
ErrorCatch:
End Function
'* Restituisce il risultato della invocazione remota.
'* Restituisce Nothing se il risultato non è ancora giunto.
'* Se il risultato è giunto lo restituisce e lo rimuove dalla collezione dei risultati arrivati
Public Function GetResult(ProcedureInstanceID As String) As CFunctionResult
On Error GoTo ErrorCatch
Dim Risultato As CFunctionResult
Set GetResult = Nothing 'In caso di errore
If IsResultArrived(ProcedureInstanceID) Then
Set Risultato = Risultati.Item(ProcedureInstanceID)
Call Risultati.Remove(ProcedureInstanceID)
Set GetResult = Risultato
End If
ErrorCatch:
End Function
'* Indica che è arrivato il risultato della richiesta
'* Registra il risultato fra quelli disponibili
Private Sub ResultArrived(Result As CFunctionResult)
Call Risultati.Add(Result, Result.InstanceID)
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
'* Funzione da chiamare per contattare lo Skeleton remoto.
'* Impostare tutti i parametri della funzione da chiamare nella variabile <I>ParamArray</I>
'* E' necessario indicare se attendere o meno il risultato della computazione remota. Questo _
è importante sia nel caso in cui il metodo chiamato sia semplicemente una procedura senza ritorno, _
sia nel caso in cui non si desideri attendere il risultato ma semplicemente andarlo a pescare dopo _
eseguendo un polling sulla funzione IsResultAvailable.
'* <B>Nota:</B> se non si desidera attendere il risultato, la funzione restituisce il nome univoco _
della richiesta di procedura remota necessario per eseguire successivamente il polling del risultato.
Public Function CallRemoteFunction(MethodName As String, HoldOnForResult As Boolean, ParamArray Arguments() As Variant)
Dim Procedure As New CProcedure
Dim i As Long
'Creazione delle informazioni sul metodo da chiamare
With Procedure
.Name = MethodName
For i = 0 To UBound(Arguments)
.AddParam Utilities.CreateCValue(Arguments(i))
Next i
End With
'Invio della richiesta
If Not Dispatcher.Send(Procedure.toEnvelope(Me, RemoteSkeletonID), RemoteMsgManagerAddress) Then
Call Utilities.RaiseSMomException(UnKnownSMomException, "SMom.CDynamicStub", "Dispatcher couldn't Send message")
Exit Function
End If
'Se devo attendere il risultato...
If HoldOnForResult Then
CallRemoteFunction = HoldResult(Procedure.InstanceID, Me.TimeOutMilliSeconds)
Else 'Restituisco l'InstanceID
CallRemoteFunction = Procedure.InstanceID
End If
End Function
'* Chiamare questa procedura se si desidera attendere il risultato della chiamata a funzione remota precedentemente effettuata.
Public Function HoldResult(ByVal ProcedureInstanceID As String, ByVal TimeOutS As Long)
Dim IntialTimer As Single
Dim Risultato As CFunctionResult
'In Vb non riesco a fare altro che attendere con un ciclo
'NOTA: il controllo sul timeout fallisce (prima) nei pressi della mezzanotte...
'Uso Abs() proprio per far si che riesca altrimenti non passerebbe mail
IntialTimer = Timer
Do Until (Me.IsResultArrived(ProcedureInstanceID) Or (Abs(CLng((Timer - IntialTimer) * 1000)) > TimeOutS))
DoEvents
Loop
Set Risultato = GetResult(ProcedureInstanceID)
If Not Risultato Is Nothing Then
If Risultato.IsValid Then 'Raccolgo il risultato e lo restituisco
HoldResult = Risultato.FunctionResult.toVariant()
ElseIf Not Risultato.FunctionResult Is Nothing Then
Call Utilities.RaiseSMomException(RemoteException, "SMom.CDynamicStub", "RemoteException description:" & vbCrLf & _
Risultato.FunctionResult.getActualValueToString())
Else 'Errore non specificato!
Call Utilities.RaiseSMomException(UnKnownRemoteException, "SMom.CDynamicStub")
End If
Else 'TimeOut!
Call Utilities.RaiseSMomException(TimeOutExpiredException, "SMom.CDynamicStub", "Not found Result for Request:" & ProcedureInstanceID)
End If
End Function
Private Sub Class_Terminate()
Dim Obj As Object
'Ripulisco tutto
On Error Resume Next
For Each Obj In Risultati
Risultati.Remove Obj
Next
Set Obj = Nothing
'Dispatcher
Set Dispatcher = Nothing
End Sub
Private Function IReceiver_getObjectID() As String
IReceiver_getObjectID = StubID
End Function
Private Sub IReceiver_msgArrived(Env As SMom.CEnvelope)
'Sono arrivati dei risultati
Dim Risultato As New CFunctionResult
If Risultato.fromEnvelope(Env) Then
Call ResultArrived(Risultato)
End If
End Sub
Private Function ISender_getObjectID() As String
ISender_getObjectID = StubID
End Function
|
Documento generato mediante: Documentation Creator By BGSoftware |