Geeigneten Server für meine Programme

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Morgen,

ich bin auf der Suche nach einem kostengünstigen Server für meine Programme - nur Server, Festplatte ist bereits vorhanden.
Dabei bin ich auf 2 Seiten gelandet, doch hätte gern mal 'ne Meinung, ob diese für mein Vorhaben geeignet sind:
1. https://www.bueromarkt-ag.de/nas-server ... QYQAvD_BwE
2. https://www.alternate.de/html/product/1 ... s0QAvD_BwE
3. Oder kann man nicht auf einen Raspberry Pi3 als Servern nutzen? Wie gut wäre dieser?

Mein Vorhaben:
Meine aktuellen Programme ist ein Cheat-Updater, bei der man sich einloggen muss und dann geprüft wird, ob eine neuere Version vorhanden ist und diese downloadet. Zugang erhalten nur die, die den Cheat schon gekauft haben.
Das zweite Programm ist ein sogenanntes "Script.Game.Interface" (eine GUI zum Bearbeiten des Cheats (Skripts) ), in der man sich ebenfalls einloggen muss und dann geprüft wird, ob neue Version vorhanden ist oder nicht
und diese downloaded.

Das Einloggen funktioniert momentan durch Web-Scrapping: man gibt sein Accountname & Passwort einer bestimmten Seite ein, das Programm versucht sich einzuloggen und eine Seite auszulesen, bei der die Accountnamen eingespeichert sind, die Zugang zu dem Programm erhalten dürfen.

Die Frage ist nur...
Welches Prinzip des Login's wäre beim Server sinnvoll.
Ich könnte ja ein Programm schreiben, dass die Käufe meines Shop's ausliest und mit den Infos eine Datenbank erstellt. Beim Login schreibt man dann nur seine Bestell-ID und loggt sich damit ein und das Programm schaut auf der Datenbank im Server, ob diese Bestell-ID auch vorhanden ist und ob das Ablaufdatum überschritten wurde (bezahlte Update-Abos).
Gleiche beim Versionscheck: schreibe ein Programm, welches alle Namen und "Zuletzt-Bearbeitet" aller verkauften Cheats/Programme in einer (neuen) Datenbank speichert und anhand dessen es überprüft, ob ein Update verfügbar ist.

Oder gibt es gar eine leichterer Lösung?
Klingt nämlich nach viel Aufwand und die Lizenzkosten (480€) möchte ich nun so schnell wie möglich wieder einbringen.
PS. Hoffe es kam verständlich rüber, musste beim Vorhaben ziemlich überlegen, wie man es machen und erklären könnte. :-D

Grüße,
xXSkyWalkerXx1
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@xXSkyWalkerXx1: Die ersten beiden Links führen zu NAS-Geräten. Die würde ich nicht als Webserver verwenden die im Internet öffentlich zugänglich sind. Sofern man sie überhaupt als Webserver verwenden kann.

Klar kann man einen Raspi als Webserver verwenden. Wie gut das funktioniert hängt von der Last ab die Du erwartest. Wenn da hunderte Benutzer gleichzeitig drauf zugreifen sollen, dann natürlich nicht, aber für den Anfang kann der durchaus eine Option sein. Wenn es dann so viele Kunden werden, dass der nicht mehr ausreicht, hast Du wahrscheinlich genug Geld für eine leistungsstärkere Lösung verdient.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ich schätze mal, dass mit Einmal eher glaube nur max. 10 zugreifen, habe zwar einige Kunden, aber es werden da nicht so viele mit einmal drauf zugreifen.
Aber gut, dann versuche ich es mit 'nem Raspberry Pi3. :)
Hmm, vllt verwende ich sogar mein aktuellen, den nutze ich nämlich nicht mehr, seitdem ich Python IDLE auf mein Windows Rechner habe.

Und wie sieht's hiermit aus?
Die Frage ist nur...
Welches Prinzip des Login's wäre beim Server sinnvoll.
Ich könnte ja ein Programm schreiben, dass die Käufe meines Shop's ausliest und mit den Infos eine Datenbank erstellt. Beim Login schreibt man dann nur seine Bestell-ID und loggt sich damit ein und das Programm schaut auf der Datenbank im Server, ob diese Bestell-ID auch vorhanden ist und ob das Ablaufdatum überschritten wurde (bezahlte Update-Abos).
Gleiche beim Versionscheck: schreibe ein Programm, welches alle Namen und "Zuletzt-Bearbeitet" aller verkauften Cheats/Programme in einer (neuen) Datenbank speichert und anhand dessen es überprüft, ob ein Update verfügbar ist.

Oder gibt es gar eine leichterer Lösung?
Klingt nämlich nach viel Aufwand und die Lizenzkosten (480€) möchte ich nun so schnell wie möglich wieder einbringen.
PS. Hoffe es kam verständlich rüber, musste beim Vorhaben ziemlich überlegen, wie man es machen und erklären könnte. :-D
...hält das eigentlich ein Raspberry Pi3 aus?
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja. Das war doch die Aussage von Blackjack? Was an seiner Antwort ist dir unklar?

Seit Dezember gibt es uebrigens das hier: https://wiki.qt.io/Qt_for_Python

Ggf. kannst du dir damit die Lizenzkosten sparen, das ist naemlich auch LGPL. Wenn es fuer dich funktioniert.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Hm, obwohl...ich denke mal es hat sich auch so erledigt. ^^

Danke für den Tip! *-* Downloade es bereits, versuch's gleich mal - wäre super wenn es funktionieren würde!
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Aber ich verstehe nicht, warum ich diesen Fehler bekomme: "self.app = QApplication(sys.argv) RuntimeError: Please destroy the QApplication singleton before creating a new QApplication instance."

Code: Alles auswählen

from PySide2.QtWidgets import QApplication, QMainWindow,QPushButton,QFrame,QHBoxLayout,QSplitter
from PySide2.QtCore import Qt
import sys

class SimpleWindow():
    def main(self):
        self.app = QApplication(sys.argv)
        self.window1 = QMainWindow()
        self.window1.setWindowTitle("Window_1")
        self.window1.setGeometry(700,400,240,300)

        self.swap_window = QPushButton("Push me to see the next windows")
        
        self.central_frame = QFrame()
        self.layout = QHBoxLayout()
        self.splitter = QSplitter()
        self.splitter.addWidget(self.swap_window)
        self.layout.addWidget(self.splitter)

        self.swap_window.clicked.connect(self.window_2)
        
        self.central_frame.setLayout(self.layout)
        self.window1.setCentralWidget(self.central_frame)
        self.window1.show()
        
    def window_2(self):
        self.window1.destroy()
        
        self.app = QApplication(sys.argv)
        self.window2 = QMainWindow()
        self.window2.setWindowTitle("Window_2")
        self.window2.setGeometry(700,400,240,300)

        self.window2.setCentralWidget(QFrame())
        self.window2.show()
        


ui = SimpleWindow()
ui.main()
sys.exit(ui.app.exec_())
Und bezüglich PySide2 , was die Lizenz angeht - so wie ich entnehmen konnte ("https://de.wikipedia.org/wiki/GNU_Lesse ... ic_License") , muss ich ja trotzdem den Quellcode zur Verfügung stellen (wenn vom Kunde gewünscht).
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@xXSkyWalkerXx1: Welchen Quellcode? Den den *Du* geschrieben hast *nicht*. Den von PySide2 und Qt schon. Aber da brauchst Du den Kunden ja nur auf die Webseite(n) von Qt verweisen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein, das musst du bei der LGPL nur wenn du PySide *selbst* veraendert hast. Der Unterschied zwischen GPL und LGPL ist genau der - L bedeutet "lesser" oder "library" und ist fuer diesen Anwendungsfall gedacht. Und das haben wir dir ehrlich gesagt schonmal erklaert.

Was du da gebaut hast mit einer main-Methode ist uebrigens grosser Mist. main ist eine FUNKTION in Python. Das, was du in deiner main machst AUSSER der App (dazu kommen wir gleich) gehoert in den Konstruktor (__init__). Weiterhin hast du eine Methode window_2, die dann ein Attribut window_2 anlegt, womit die Methode selbst kaputt ist. Macht man also nicht. Und jaaaaaa, ich weiss, das ist ja nur ein Testskript, und alles nicht so gemeint. Woher aber immer diese Ueberzeugung kommt, man wuerde es dann magisch richtig machen, wenn man *keinen* Testcode schreibt - das hat mir noch keiner erklaeren koennen. Du wirst den gleichen Kram wiederholen, den du schoen falsch geuebt hast beim testen... Fussballer trainieren ja auch kein Handball, und ploetzlich klappt das mit den Freistoessen von alleine.

Das app-Attribut gehoert also in die main-FUNKTION. FUNKTION. Und da an den Anfang. Und DANACH baust du dann dein SimpleWindow. Denn wenn du einfach ein Widget erzeugst, OHNE das es vorher ein App-Objekt gab, dann legt Qt automagisch eines an, und beschwert sich dann, so wie hier gezeigt.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Asu. Danke! Wenn ich mich nicht irre ging es nur um GPL - bin mir aber nicht sicher.

Wenn ich dich richtig vestanden habe, geht's dir bei "Weiterhin hast du eine Methode window_2, die dann ein Attribut window_2 anlegt, womit die Methode selbst kaputt ist." darum, dass ich eine Methode "window_2" und ein Attribut dessen "window_2"nannte? Wenn ja, dann verstehe ich nicht genau was du meinst, da ich deshalb das Attribut "window2" nannte.

Achsoo! Dann hatte ich das mit "QApplication" wohl nicht verstanden. Jetzt funktioniert es und weiß auch wie man das mit "QApplication" macht, eigentlich auch logisch...Danke!
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@xXSkyWalkerXx1: Methoden sind auch Attribute auf Objekten und wenn Du ein Attribut mit dem selben Namen wie eine Methode zuweist, dann gibt es danach logischerweise die Methode auf diesem Objekt nicht mehr, weil die durch den Wert ersetzt wurde:

Code: Alles auswählen

In [8]: class A:
   ...:     def test(self):
   ...:         self.test = 42
   ...: 

In [9]: a = A()

In [10]: a.test()

In [11]: a.test()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-fbd24be654b4> in <module>()
----> 1 a.test()

TypeError: 'int' object is not callable

In [12]: a.test
Out[12]: 42
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ja, ich verstehe schon, aber "window_2" =! "window2"...
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Oh, habe ich mich verlesen. Wir aendern die Beschwerde also zu undurchsichtigen und zu aehnlichen namen....
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ja, habe mich schon gewundert, warum du dich über gleiche Namen beschwerst. ^^
Aber was "ähnlich betrifft" - was wäre denn ein besserer Name (entweder für die Funktion oder für das Attr. QMainWindow)?
Glaube in beiden Funktionen den gleichen Namen für dieses Attr. und "self.window_1.destroy()" entfernen wäre besser, oder?
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na sowas wie open_next_window, und das ist die Taetigkeit, das Objekt heisst dann entweder next_window oder einfach window wenn du eh immer nur ein aktives hast.
Antworten