MySQL Webservice

Operator_Jon

Erfahrenes Mitglied
Hallo Leute,

ich habe eine organisatorische Frage bezüglich Webservices unter ASP.NET:
Ich möchte einen Webservice schreiben, welcher verschiedene MySQL Operationen zur Verfügung stellt.

Jetzt habe ich eine "Connect()", eine "Verify()", eine "Read()" und eine "Disconnect()" Funktion geschrieben und gemerkt, dass wenn ich eine global gesetzte Verbindungsvariable per Connect() eine Verbindung aufbauen lasse, sie in Verify() und den anderen nicht mehr zur Verfügung steht.

Kann man das anders lösen oder MUSS ich zwingend pro Funktionsaufruf die Verbindung neu herstellen (Das ist etwas doof, weil ein Zugriff alle paar Sekunden stattfinden soll!)

Danke für eure Antworten,
schöne Grüße,
Jonathan


PS: Der Webservice wird von einem VB.NET Programm aufgerufen falls diese Information etwas hilft. Er dient als Schnittstelle, damit das lokale Programm die Verbindungsdaten nicht preisgibt, da .NET Programme ja so einfach auslesbar sind :(
 
Hi

Ja, das solltest du. Du solltest sicher gehen, dass du Stateless läufst. Du hast sonst das Problem, dass dir der Speicher zuläuft, wenn Disconnect nicht aufgerufen wird.
Biete entsprechende Methoden an, die immer einen definierten Zustand zurücklassen.
Du scheinst aber grad erst anzufangen mit dem Projekt oder? Dann würde ich dir empfehlen über einen WCF Service die Dienste zur Verfügung zu stellen und nicht mit einem "alten" WebService
 
Hi Nico,

vielen Dank für deine Antwort, das ergibt auf jeden Fall Sinn!
Ich werde mir die WCF-Service Geschichte auf jeden Fall in den nächsten Tagen ganz genau ansehen!

Denkst du denn das es generell der richtige Weg ist um eine Verbindung zur Datenbank zur Verfügung zu stellen? Es sollen max. 500 Clients die Möglichkeit haben auf einmal auf die DB zuzugreifen, jeder alle paar Sekunden, hast du eine Idee wie das bezüglich der Performance aussieht?

Danke nochmal und schöne Grüße,
Jonathan

/Editiert:
Hallo nochmal, also ich habe einige kurze Tests mit einem WCF-Service gemacht, bei denen ist es ja theoretisch möglich die Verbindung offen zu lassen.
Ich vermute aber mal das es sich hier genauso verhält, dass es sicherer ist für jeden Zugriff eine neue Verbindung herzustellen?

(Ich habe etwas weiter getestet und es scheint von der Performance her auch nicht unbedingt nötig zu sein :)! )

Schönen Gruß,
Jonathan
 
Zuletzt bearbeitet:
Hi

Ob es der Performance zuträglich ist bei 500 Clients hängt von der Architektur des Services ab. Es ist definitiv jedoch von Nachteil, wenn du Sessions cachen musst.
Der Ansatz einen Service zur Verfügung zustellen ist auf jeden Fall der Richtige. Das ist das Prinzip von Client-Server-Anwendungen. Der Server stellt Dienste zur Verfügung.
 
Hi Nico,

was meinst du mit der Architektur?
Also ich stelle es mir zurzeit so vor:
Der Benutzer startet das Programm, es erstellt eine Instanz des Services beim Start:
(Also das ganze natürlich nur als Beispiel)
Code:
client = New ServiceReference1.Service1Client
Dann verifiziert sich der Client und ruft einige Daten ab, die Daten kann er nach einmaliger Verifizierung immer wieder abrufen und auf neue Daten prüfen:
Code:
client.Verify(...)
client.getMessages()
Der Service ist folgendermaßen aufgebaut:
Code:
Public Class Service1
    Implements IService1

    Private myConnection As MySqlConnection
    Private myDataAdapter As MySqlDataAdapter
    Private myDataSet As DataSet

    Private strSQL As String
    Private iRecordCount As Integer

    Public VERIFIED As Boolean

    Public Sub New()
        VERIFIED = False
    End Sub

    Private Sub Connect()
        myConnection = New MySqlConnection("server=xxx;user id=xxx;password=xxx;database=xxx;pooling=false;")
        myConnection.Open()
    End Sub

    Private Sub Disconnect()
        myConnection.Close()
    End Sub

    Public Function Verify(...) As String Implements IService1.Verify
        Connect()

        '....
        'Prüfe die Datenbank ob Benutuzer autorisiert ist
        '...
        VERIFIED = True

        Disconnect()
    End Function


    Public Function getMessages() As String Implements IService1.getMessages
        If VERIFIED Then
            Connect()

             '....
             'Hole einige Daten aus der DB und gebe sie zurück
             '...

            Disconnect()
        Else
            Return ""
        End If
    End Function
End Class

(Ich werde die MySQL Funktionen noch in eine eigene Klasse auslagern denke ich!)

Nun meine Frage, ist es ein Problem, dass im Client nirgendwo
Code:
client.Close()
aufgerufen wird?

Passiert es dann auch, dass der Speicher zuläuft?


Vielen Dank,
Jonathan

PS: Die Funktionalität des Services ist mit den paar Funktionen schon beinahe erreicht, da kommt nicht mehr viel dazu!
 
Implementier zusätzlich das Interface IDisposable. Im Dispose räumst du auf, für den Fall, dass die Connection nicht geschlossen wird. (siehe auch Interface der DbConnection und DbAdapter-Klassen)

Die Frage mit dem Client.Close versteh ich nicht, die Methode gibts doch gar nicht :confused:

Anstatt der Methode Verifiy wäre es noch besser, wenn du den die Information in den Konstruktor geben würdest.

Dann sind aber zum Teil nur Feinheiten, im Groben scheint es so erstmal zu passen :)
 
Hi Nico,

vielen Dank für die Namen der Interfaces, ich wusste gar nicht, dass es die gibt :)!

client.Close() wird automatisch zur Verfügung gestellt, also im Client Programm das den Service aufruft! (Ich habe den Service als Service-Referenz hinzugefügt!)

Mit dem Konstruktor hast du recht, das werde ich auf jeden Fall so machen!!

Danke schon mal soweit!
Hast du vielleicht noch einige Anregungen was die Sicherheit anbetrifft?
Ich habe mir überlegt alle Kommunikationsdaten zu verschlüsseln, also einfach alles zwischen Client und Service. Ich schreibe den Client selbst, das heißt es soll ohnehin niemand auf den Service zugreifen können, außer diesen Programmen (kann man das eigentlich auch irgendwie einrichten, dass nur diese an die Kunden verteilten Programme den Service nutzen können?). Ich mache mir bei der Verschlüsselung allerdings Sorgen, weil man das Client Programm ja ganz einfach mit einem Reflector auslesen kann. Das bedeutet doch, dass jede noch so tolle Verschlüsselungsmethode nichts wert ist weil sie nachvollzogen werden kann :(!

Wenn du da noch einige Anregungen hättest, das wäre total super :)!
(Ich brauche keinen Code oder ähnliches, mir reichen Stichworte, sonst lerne ich ja nichts dabei ;) )

Schöne Grüße,
Jonathan
 
Hi Nico,

danke für den Link, das werde ich tun!
Unter der Annahme, dass man das Client Programm mit einem Reflector auslesen kann, versuche ich gerade mir eine Authentifizierungsmethode einfallen zu lassen, so dass wirklich nur meine Programme auf den Service zugreifen können. Mir fällt aber leider nichts ein, alles scheitert daran, dass der Code ausgelesen werden kann :(.
Hast du da eine Idee?

Was wären denn sonst noch für Sicherheitsaspekte zu beachten? Ich meine z.B. DOS-Attacken, lassen die sich irgendwie unterbinden durch bestimmte Routinen?

Danke für deine Hilfe,
schöne Grüße,
Jonathan
 
Ich habe es jetzt so gelöst, dass ich zusätzlich eine Verschlüsselungsroutine in den Webservice eingelagert habe und der Mechanismus so nicht im Client Programm zu sehen ist!

Gibt es denn eine Möglichkeit, den Webservice wirklich nur diesem spezifischen Programm zugänglich zu machen? Sie sozusagen untrennbar miteinander verbinden?

Vielleicht einen MD5 Hash der fertigen .exe mitsenden und den im Webservice prüfen?
(Was ja auch wieder an der Auslesbarkeit des Codes im Client Programm scheitert... Ich bin verzweifelt :( )
 
Zurück