Toon posts:

[VB.NET] Remoting, een complex object retourneren

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoe kan ik mvb Remoting een complex object retourneren.

Ik zie alleen maar eenvoudige voorbeelden met strings en int's maar ik wil een eigen object van een server terug krijgen. In dit geval probeer ik een collection object (complex type) te ontvangen. Maar het zou natuurlijk ook met een eigen class-object moeten kunnen.


Voorbeeld server:

De Class
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Public Class SimpleClass : Inherits MarshalByRefObject

    Public Function GetDateTime() As Date
        Return Now()
    End Function

    Public Function Hello() As Collection
        Dim lvobjCollection As New Collection
        lvobjCollection.Add("Test")
        lvobjCollection.Add("Test2")

        Return lvobjCollection
    End Function
End Class

Het Form
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Tcp

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
    Friend WithEvents Label1 As System.Windows.Forms.Label

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Label1 = New System.Windows.Forms.Label
        Me.SuspendLayout()
        '
        'Label1
        '
        Me.Label1.Location = New System.Drawing.Point(8, 8)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(360, 40)
        Me.Label1.TabIndex = 1
        Me.Label1.Text = "Label1"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(392, 54)
        Me.Controls.Add(Me.Label1)
        Me.Name = "Form1"
        Me.Text = "Simple Remoting Server"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            Dim channel As New TcpChannel(9999)
            ChannelServices.RegisterChannel(channel)
            RemotingConfiguration.ApplicationName = "SimpleRemotingServer"
            Dim t As Type = Type.GetType("Server.SimpleClass")
            RemotingConfiguration.RegisterWellKnownServiceType(t, "SimpleClass", WellKnownObjectMode.SingleCall)
            
            Label1.Text = "SimpleClass registered." & vbCrLf & "Remoting running..."
        Catch ex As Exception
            Label1.Text = "Remoting initilization failed."
        End Try
    End Sub

    
End Class


VOORBEELD CLIENT
Dezelfde class als van Server

Het Form
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Tcp

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
    Friend WithEvents DateTimeButton As System.Windows.Forms.Button
    Friend WithEvents HelloButton As System.Windows.Forms.Button

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents Button1 As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.DateTimeButton = New System.Windows.Forms.Button
        Me.HelloButton = New System.Windows.Forms.Button
        Me.Button1 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'DateTimeButton
        '
        Me.DateTimeButton.Location = New System.Drawing.Point(60, 17)
        Me.DateTimeButton.Name = "DateTimeButton"
        Me.DateTimeButton.Size = New System.Drawing.Size(85, 25)
        Me.DateTimeButton.TabIndex = 1
        Me.DateTimeButton.Text = "GetDateTime"
        '
        'HelloButton
        '
        Me.HelloButton.Location = New System.Drawing.Point(171, 17)
        Me.HelloButton.Name = "HelloButton"
        Me.HelloButton.Size = New System.Drawing.Size(85, 25)
        Me.HelloButton.TabIndex = 2
        Me.HelloButton.Text = "Hello"
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(280, 24)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(24, 24)
        Me.Button1.TabIndex = 3
        Me.Button1.Text = "Button1"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(324, 57)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.HelloButton)
        Me.Controls.Add(Me.DateTimeButton)
        Me.Name = "Form1"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "Remoting Client"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Dim sc As SimpleClass

    Private Sub DateTimeButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DateTimeButton.Click
        If Not Initialize() Then Return

        MsgBox(sc.GetDateTime(), MsgBoxStyle.DefaultButton1, "GetDateTime()")
    End Sub

    Private Sub HelloButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HelloButton.Click
        If Not Initialize() Then Return
        MsgBox(sc.Hello.Item(1), MsgBoxStyle.DefaultButton1)
        'MsgBox(sc.Hello(), MsgBoxStyle.DefaultButton1, "Hello()")
    End Sub

    Public Function Initialize() As Boolean
        If sc Is Nothing Then
            Dim chan As New TcpChannel()
            ChannelServices.RegisterChannel(chan)
            Dim t As Type = Type.GetType("Server.SimpleClass")
            sc = Activator.GetObject(t, "tcp://localhost:9999/SimpleClass")
            If sc Is Nothing Then
                MsgBox("Could not initialize the remoting client. Check your configuration.")
                Return False
            End If
            
        End If

        Return True
    End Function   
End Class



Ik zit al de hele dag te zoek naar goed voorbeelden van remoting in VB.NET maar ik kom overal hetzelfde simpele voorbeeld tegen. Deze heb ik geprobeerd aan te passen.

Kan iemand me vertellen waar ik op moet letten of een aantal termen geven waarop ik verder kan zoeken.

  • vogeltje
  • Registratie: December 2001
  • Laatst online: 10-08-2025
het lijkt mij dat een object serializable moet zijn, voordat je em uberhaupt kunt versturen via welke .NET Remoting techniek dan ook. Dus probeer dat maar eens.

en post de volgende keer maar gewoon enkel de relevante code....al die user interface code heeft weinig met Remoting te maken ;)

[ Voor 30% gewijzigd door vogeltje op 24-03-2005 23:13 ]

binnenkort een hele dikke casemod :P


  • whoami
  • Registratie: December 2000
  • Laatst online: 09-05 01:02
Serializable is the magic word

[Serializable] en ISerializable

En zo'n lap code, daar begin ik niet aan hoor..... Zeker niet als het irrelevante code is.

wat vogeltje dus ook al zei

https://fgheysels.github.io/


Verwijderd

Topicstarter
Sorry voor de hoeveelheid code maar ik wilde graag volledig zijn. Jullie weten wat relevant is in deze kwestie ik een stuk minder.

Wat betreft het serializen dacht ik dat het alleen voor webservices geldt ??

Ik wil graag dat het hele object gewoon op de server bestaat en dat ik alleen een referentie naar het object op de client haal. De uitvoer van een method bijvoorbeeld een collection class of een willekeurige andere "complexe" class. Hoe kan ik uberhaupt een collection class serializen. Uiteraard heb ik al geprobeerd om dit keyword voor de class te zetten.

Wat is het verschil tussen [Serializable] en ISerializable en <Serializeble()>
Wanneer moet ik wat gebruiken.

  • whoami
  • Registratie: December 2000
  • Laatst online: 09-05 01:02
Verwijderd schreef op vrijdag 25 maart 2005 @ 23:32:

Wat betreft het serializen dacht ik dat het alleen voor webservices geldt ??
Of het nu om webservices of om remoting gaat, het object dat jij wilt returnen moet over een 'channel' passeren.
Om dit te kunnen realiseren moet jouw object 'serializable' zijn. Als jij via je .NET remoting object een object wilt returnen, dan gaat de server jouw object gaan serializen (geheugen -> persisten), en moet het op de client weer gedeserialized worden (persistance -> geheugen)
Er moet dus een of andere manier bestaan om dat te werk te stelligen, en dat is via serializing.
Ik wil graag dat het hele object gewoon op de server bestaat en dat ik alleen een referentie naar het object op de client haal. De uitvoer van een method bijvoorbeeld een collection class of een willekeurige andere "complexe" class. Hoe kan ik uberhaupt een collection class serializen. Uiteraard heb ik al geprobeerd om dit keyword voor de class te zetten.
Je kan zowel een collection als een enkel object laten serializen.
Echter, als je een collection wilt serializen, zal ieder type object dat in jouw collection zit, serializable moeten zijn.
Wat is het verschil tussen [Serializable] en ISerializable en <Serializeble()>
Wanneer moet ik wat gebruiken.
Als je een class markeert met het [Serializable] attribute (C# notatie; in VB.NET schrijf je dat als <Serializable()>, dat is al een verschil verklaart), dan zal een Formatter ervoor zorgen dat alle public properties automatisch geserialized worden. Op die manier heb je dus niet veel werk om een class serializable te maken; echter, je hebt dan wel niet veel controle over wat er precies moet geserialized worden. Het kan dus zijn dat er bepaalde members (bv een private member waar je geen public property voor hebt), niet geserialized worden.
Daarom heb je ook nog die ISerializable interface. Als je die implementeert, dan moet je een method gaan overriden (GetObjectData geloof ik), en in die method ga je dan gaan zeggen wat er nu precies moet geserialized worden.
Daarnaast moet je dan ook nog een constructor hebben die ervoor kan zorgen dat er ook kan gedeserialized worden.
Als je ISerializable implementeert, moet je je class ook wel het [Serializable] attribute geven.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Bedankt !! Hiermee kom ik al wat verder.
Daarom heb je ook nog die ISerializable interface. Als je die implementeert, dan moet je een method gaan overriden (GetObjectData geloof ik), en in die method ga je dan gaan zeggen wat er nu precies moet geserialized worden.
Daarnaast moet je dan ook nog een constructor hebben die ervoor kan zorgen dat er ook kan gedeserialized worden.
Als je ISerializable implementeert, moet je je class ook wel het [Serializable] attribute geven.
Heeft u hier misschien een eenvoudig voorbeeld van?
Met de MSDN library kom ik er niet uit.

  • whoami
  • Registratie: December 2000
  • Laatst online: 09-05 01:02
Ff uit de losse pols

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[Serializable]
public class Werknemer : ISerializable
{
     private string _naam;
     private int     _id;
     private Decimal _loon;

     public string Naam
     {
         get
         {
           ...
         }
         set
         {
            ...
         }
     }

     public int Id
     {
          get
          {
          }
     }

    ...
     public Werknemer() {}

     protected Werknemer(SerializationInfo info, StreamingContext context )
     {
           _naam = info.GetString ("wnaam");
           _id = info.GetInt32("wid");
           _loon = info.GetDecimal("wloon");
     }
   
     protected void GetObjectData( SerializationInfo info, StreamingContext context)
     {
          info.AddValue ("wnaam", _naam);
          info.AddValue ("wid", _id);
          info.AddValue("wloon", _loon);
     }
}

Hier heb je dus een simpele class die serializable is.
De GetObjectData method zorgt ervoor dat instances van deze class kunnen geserialized worden, en de protected constructor die 2 argumenten neemt, zorgt ervoor dat jouw class weer kan gedeserialized worden.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Dus als ik het goed begrijp betekent het dit.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[Serializable]
public class Werknemer : ISerializable
{
     'Declaratie vars     
     private string _naam;
     private int     _id;
     private Decimal _loon;

     'Propertys get en let
     public string Naam
     {
         get
         {
           ...
         }
         set
         {
            ...
         }
     }

     public int Id
     {
          get
          {
          }
     }

    ...
     'DEZE SNAP IK EVEN NIET
     public Werknemer() {}

     'Functie voor het deserializen (moet hier ook void of function?)
     protected Werknemer(SerializationInfo info, StreamingContext context )
     {
           _naam = info.GetString ("wnaam");
           _id = info.GetInt32("wid");
           _loon = info.GetDecimal("wloon");
     }
   
     'Functie voor het serializen
     protected void GetObjectData( SerializationInfo info, StreamingContext context)
     {
          info.AddValue ("wnaam", _naam);
          info.AddValue ("wid", _id);
          info.AddValue("wloon", _loon);
     }
}


Moeten deze functies dan ook nog ergens worden aangeroepen of gebeurt dit automatisch?

Het object collection heb ik opzichzelf niet gemaakt dus kan ik dit er niet voor doen?
De objecten die ik aan de collection toevoeg uiteraard wel!
Is dat dan voldoende?

Ik kom ook veel de "inherits marshalbyrefobject" tegen waneer moet ik die dan gebruiken.

  • whoami
  • Registratie: December 2000
  • Laatst online: 09-05 01:02
Hmm, blijkbaar heb je nog niet echt veel kennis over gewoon 'OO' ?
Daar waar je gezet hebt 'dit snap ik even niet', dat is een constructor (zoek ff op dat woord). Die 'functie' voor het deserializen is ook een destructor.
De method en constructor die zorgen voor serializing/deserializing worden aangeroepen door de Formatter (Zoek eens op BinaryFormatter en SoapFormatting). Het aanroepen van die methods gebeurt automatisch; als je remoting gebruikt, dan hoef je enkel aan te geven welke formatter je wilt gebruiken.
inherits MarshalByRefObject wil zeggen dat een class afgeleid is van MarshalByRefObj. Een dergelijke class is een class die 'remotable' is; dwz, een object van deze class kan in een andere 'context' draaien, bv op een andere pc, en deze kan je dan vanaf een client gaan aanspreken.

https://fgheysels.github.io/

Pagina: 1