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.
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)...
So, registriert wird der Server im Netz mit folgenden Code:
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.
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
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
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
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)
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
Comment