Announcement

Collapse
No announcement yet.

Event Problem mit vb.net Remoting

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Event Problem mit vb.net Remoting

    Hallo zusammen, ich steh hier vor einem Problem, bei dem ich nicht mehr weiter weis. Ich stelle ein gemeinsames Remotingobjekt (eine Serverkomponente) im Netzwerk im Aktivierungsmodell Singleton zentral zur verfügung. So, dieses Objekt kann auch Events abfeuern, an den alle ageschlossenen Clients horchen (über eine Proxyklasse, die ich im Internet gefunden hab). So weit so gut, ich vereinfache das Szenario mal ganz stark. Also die Clients haben jetzt nur eine Listbox und jedes mal, wenn das Serverobjekt ein Event feuert, dann wird das vom Client in die Listbox eingetragen (über invoke und delegates... da ja nur der Erzeugerthead auf Formelemente zugreifen darf) .. Jetzt soll es aber auch möglich sein, dass der Client am gemeinsamen Serverobjekt ein Event auslöst, dazu hat das Serverobjekt eine einfache Methode namens invokeEvent (welches dann denn Multicastdelegat auflöst und die Events einzeln an die angeschlossenen Clients sendet und eventuell tote Clients rausschmeisst.). Das Ding hängt allerdings, wenn ich am Client dieses Serverevent auslöse und der gleiche Client dabei selbst observer ist. Irgendwie kommt dann das vom gleichen Client ausgelöste Event nicht mehr an und das ganze Remotingobjekt hängt, in diesem Fall sind alle beteiligten betroffen. Ich post hier mal ein bisschen Code.
    Code:
    Imports System.Runtime.Remoting
    Imports System.Runtime.Remoting.Channels.Http.HttpChannel
    
    Public Class MyRemotingObject
        Inherits MarshalByRefObject
    
        Public Event LibCalled(ByVal message As String)
    
        Private Shared _iNextID As Integer = 1
    
        Public Overrides Function InitializeLifetimeService() As Object
            Return Nothing
        End Function
    
    
        Public Function sayHello() As String
            Console.WriteLine("sayHello() was invoked by remote " & _iNextID & " times!")
            _iNextID += 1
            Return ("Hello Remoteworld " & _iNextID & " !")
        End Function
    
    
    
    
        Public Sub invokeEvent(ByVal refobjVar As String)
            Dim obj(0) As Object
            obj(0) = refobjVar
    
            Try
                Dim invocationList() As [Delegate] = LibCalledEvent.GetInvocationList 'LibCalled.getinvocationlist
                Dim del As [Delegate]
                For Each del In invocationList
                    Try
                          del.Method.Invoke(del.Target, obj)
                    Catch deadClientEx As Exception
                        LibCalledEvent = CType(System.Delegate.Remove(LibCalledEvent, del), LibCalledEventHandler)
                    End Try
                Next del
            Catch nullRefEx As System.NullReferenceException
                ' If no objects have subscribed to this event yet, then
                ' the EventDelegate will by nothing and therefore won't 
                'have an invocation list.
            End Try
        End Sub
    
        
    End Class
    Die Klasse RemoteObjectEventHelper macht nichts anderes als die Events an der Clientseite aufzufangen und erneut zu feuern, ich hab wo gelesen, dass das besser sie (weis allerdings ned warum)...
    Code:
    Imports System.Runtime.Remoting
    Imports System.Runtime.Remoting.Channels
    
    <Serializable()> _
    Public Class RemoteObjectEventHelper
        Inherits MarshalByRefObject
    
        Private mSource As MyRemotingObject
    
        Public Event RemoteObjectEvent(ByVal source As String)
    
        Public Overrides Function InitializeLifetimeService() As Object
            Return Nothing
        End Function
    
        Public Sub New(ByRef Value As MyRemotingObject)
            mSource = Value
            AddHandler mSource.LibCalled, AddressOf RemoteObjectHelper
            AddHandler mSource.stayAliveBroadcast, AddressOf RemoteBroadcasthelper
        End Sub
    
        Public Sub RemoteObjectHelper(ByVal source As String)
            RaiseEvent RemoteObjectEvent(source)
        End Sub
    
        Public Sub RemoteBroadcasthelper()
            RaiseEvent RemoteObjectBroadcastevent()
        End Sub
    End Class
    So, registriert wird der Server im Netz mit folgenden Code:
    Code:
      Dim objChannel As Channels.Tcp.TcpChannel
        Dim objremoting As MyRemotingObject
    
            Dim sProv As New Channels.BinaryServerFormatterSinkProvider
            Dim Properties As IDictionary = New Hashtable
            sProv.TypeFilterLevel = Runtime.Serialization.Formatters.TypeFilterLevel.Full
            Properties("port") = 50000
            objChannel = New Channels.Tcp.TcpChannel(Properties, Nothing, sProv)
            Channels.ChannelServices.RegisterChannel(objChannel, False)
            If Not RemotingConfiguration.IsActivationAllowed(GetType(MyRemotingObject)) Then
                RemotingConfiguration.RegisterWellKnownServiceType(GetType(MyRemotingObject), "MyObject", WellKnownObjectMode.Singleton)
            End If
            objremoting = CType(Activator.GetObject(GetType(MyRemotingObject), "tcp://localhost:50000/MyObject", WellKnownObjectMode.Singleton), MyRemotingObject)
    Und so wird er vom Client verwendet, hier seh ich evtl eine mögliche Fehlerquelle, ich kenn mit mit diesen BinaryServer/ClientSinkProvider zeugs ned gescheit aus, ich benutze auf der Clientseite auch den BinaryServerSinkProvider und nicht den BinaryClientSinkProvider, wie gesagt das ganze kommt zum Stillstand, wenn ich vom Client aus die Methode invokeEvent des Remoteobjekts aufrufe und der Client dabei aber selber auf dieses Event horcht.

    Code:
     Dim mychannel As Channels.Tcp.TcpChannel
        Dim objRemoting As MyRemotingObject
        Dim obj(0) As Object
        Public Delegate Sub mydelegate0(ByVal message As String)
        Dim mymethod0 As New mydelegate0(AddressOf WriteEntry)
    
    
        Private Sub client_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim RemoteType As New WellKnownClientTypeEntry(GetType(MyRemotingObject), "tcp://192.168.2.10:50000/MyObject")
            Dim sProv As New Channels.BinaryServerFormatterSinkProvider
            sProv.TypeFilterLevel = Runtime.Serialization.Formatters.TypeFilterLevel.Full
            Dim props As IDictionary = New Hashtable
            props("port") = 0
            mychannel = New Channels.Tcp.TcpChannel(props, Nothing, sProv)
            Channels.ChannelServices.RegisterChannel(mychannel, False)
            RemotingConfiguration.RegisterWellKnownClientType(RemoteType)
            objRemoting = Activator.GetObject(GetType(MyRemotingObject), "tcp://192.168.2.10:50000/MyObject")
    
            Dim mRemoteObjectEventHelper As RemoteObjectEventHelper
            mRemoteObjectEventHelper = New RemoteObjectEventHelper(objRemoting)
            AddHandler mRemoteObjectEventHelper.RemoteObjectEvent, AddressOf invoker
    
     Public Sub writeentry(ByVal obj As String)
            If ListBox1.Items.Count > 10 Then
                ListBox1.Items.Clear()
            End If
            ListBox1.Items.Add(obj)
        End Sub
    
        Public Sub invoker(ByVal objvar As String)
            obj(0) = objvar
            Me.Invoke(mymethod0, obj)
        End Sub
    
     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            objRemoting.invokeEvent("Es ist jetzt: " & Now.ToString)
        End Sub

    BEI FOLGENDEM CODE HÄNGT ALLES!!!!! ich möcht aber vom Client das Event auslösen und dabei auch selbst wieder mitbekommen!
    ----------------------------------------------------------------------------------------------
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    objRemoting.invokeEvent("Es ist jetzt: " & Now.ToString)
    End Sub
    ----------------------------------------------------------------------------------------------




    Das war jetzt ganz schön viel Code und Text aber vielleicht kann mir dann jemand besser weiterhelfen, bin wirklich für jede Hilfe dankbar...

    Danke schonmal

    loop2000

  • #2
    Hallo loop2000,

    zunächst: ich habe Deinen Beitrag nur ganz kurz überflogen, und Dein Beispielcode nicht angeschaut.

    Aber zu .NET Remoting mit Events könnte ich einen Erfahrungsbericht schreiben, ich beschränke mich aber auf folgende Aussage:
    Events über Remoting funktionieren nicht einwandfrei

    Wie eine gute Lösung aussieht, kann man bei Codeproject nachlesen (leider C#):
    Two-Way Remoting bei Codeproject.com

    Ich denke das ist wesentlich besser erklärt, als dass ich das jemals hier hinbekommen würde ;-)

    Grüße
    _ntr_

    Comment

    Working...
    X