


Eine minimalistische Passwort-Manager-Desktop-App: ein Ausflug in das Wails-Framework von Golang (Teil 2)
Dec 30, 2024 am 09:50 AMHallo nochmal, Programmierer! Im ersten Teil dieser kurzen Serie haben wir die Erstellung und den Betrieb einer Desktop-Anwendung zum Speichern und Verschlüsseln unserer mit dem Wails-Framework erstellten Passw?rter gesehen. Wir haben auch eine Beschreibung des Go-Backends erstellt und wie wir es an die Frontend-Seite binden.
In diesem Teil besch?ftigen wir uns mit der Benutzeroberfl?che. Wie wir in diesem Beitrag erkl?rt haben, k?nnen wir mit Wails jedes beliebige Web-Framework, sogar Vanilla JS, zum Erstellen unserer GUI verwenden. Wie gesagt, es scheint, dass die Macher von Wails eine Vorliebe für Svelte haben, weil sie es immer als ihre erste Wahl erw?hnen. Die Wails-CLI (in ihrer aktuellen Version) generiert das Gerüst mit Svelte3, wenn wir darum bitten, ein Projekt mit Svelte Typescript zu erstellen (wails init -n myproject -t svelte-ts). Wie ich Ihnen bereits gesagt habe, wenn Sie lieber Svelte5 (und seine neuen Funktionen) verwenden m?chten, habe ich ein Bash-Skript, das seine Erstellung automatisiert (in jedem Fall muss die Wails-CLI installiert sein). Darüber hinaus wird Taildwindcss Daisyui hinzugefügt, was mir eine perfekte Kombination für das Interface-Design zu sein scheint.
Die Wahrheit ist, dass ich zuerst mit Vanilla Js und Vue gearbeitet habe, dann mit React und sogar mit dieser seltsamen Bibliothek, die für viele HTMX (was ich sagen muss, dass ich es liebe ??). Aber Svelte sorgt dafür, dass man sich von Anfang an verliebt, und ich muss sagen, dass ich es zum ersten Mal beim Experimentieren mit Wails verwendet habe (und ich verspreche, es auch weiterhin zu verwenden …). Aber so komfortabel ein Webframework auch ist, wir müssen Backend-Entwickler daran erinnern, dass das Frontend nicht so einfach ist?!!
Aber kommen wir zum Punkt.
I – Ein Blick auf die Frontend-Struktur
Wenn Sie ein Web-Framework verwendet haben, werden Sie schnell erkennen, dass die Wails-CLI unter der Haube ViteJs verwendet:
... . ├── index.html ├── package.json ├── package.json.md5 ├── package-lock.json ├── postcss.config.js ├── README.md ├── src │?? ├── App.svelte │?? ├── assets │?? │?? ├── fonts │?? │?? │?? ├── nunito-v16-latin-regular.woff2 │?? │?? │?? └── OFL.txt │?? │?? └── images │?? │?? └── logo-universal.png │?? ├── lib │?? │?? ├── BackBtn.svelte │?? │?? ├── BottomActions.svelte │?? │?? ├── EditActions.svelte │?? │?? ├── EntriesList.svelte │?? │?? ├── Language.svelte │?? │?? ├── popups │?? │?? │?? ├── alert-icons.ts │?? │?? │?? └── popups.ts │?? │?? ├── ShowPasswordBtn.svelte │?? │?? └── TopActions.svelte │?? ├── locales │?? │?? ├── en.json │?? │?? └── es.json │?? ├── main.ts │?? ├── pages │?? │?? ├── About.svelte │?? │?? ├── AddPassword.svelte │?? │?? ├── Details.svelte │?? │?? ├── EditPassword.svelte │?? │?? ├── Home.svelte │?? │?? ├── Login.svelte │?? │?? └── Settings.svelte │?? ├── style.css │?? └── vite-env.d.ts ├── svelte.config.js ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── wailsjs ├── go │?? ├── main │?? │?? ├── App.d.ts │?? │?? └── App.js │?? └── models.ts └── runtime ├── package.json ├── runtime.d.ts └── runtime.js ...
Wenn Sie ein von Vite generiertes Webframework verwendet haben, werden Sie von seinen Konfigurationsdateien nicht überrascht sein. Hier verwende ich Svelte5 (plus die Konfiguration von Taildwindcss Daisyui), was mein eigenes Bash-Skript generiert, wie ich Ihnen bereits gesagt habe. Wir verwenden auch TypeScript, was die Entwicklung des Frontends erleichtert, sodass Sie auch dessen Konfigurationen sehen k?nnen.
Aber das Wichtigste in dieser Erkl?rung ist der Inhalt des Ordners wailsjs. Hier hat die von Wails erstellte Zusammenstellung ihre Wirkung entfaltet. Im Unterordner ?go“ werden die in Js/Ts ?übersetzten“ Methoden des Backend-Teils gespeichert, der mit dem Frontend interagieren muss. Beispielsweise gibt es in main/App.js (oder seiner TypeScript-Version, main/App.d.ts) alle exportierten (?ffentlichen) Methoden der App-Struktur:
... . ├── index.html ├── package.json ├── package.json.md5 ├── package-lock.json ├── postcss.config.js ├── README.md ├── src │?? ├── App.svelte │?? ├── assets │?? │?? ├── fonts │?? │?? │?? ├── nunito-v16-latin-regular.woff2 │?? │?? │?? └── OFL.txt │?? │?? └── images │?? │?? └── logo-universal.png │?? ├── lib │?? │?? ├── BackBtn.svelte │?? │?? ├── BottomActions.svelte │?? │?? ├── EditActions.svelte │?? │?? ├── EntriesList.svelte │?? │?? ├── Language.svelte │?? │?? ├── popups │?? │?? │?? ├── alert-icons.ts │?? │?? │?? └── popups.ts │?? │?? ├── ShowPasswordBtn.svelte │?? │?? └── TopActions.svelte │?? ├── locales │?? │?? ├── en.json │?? │?? └── es.json │?? ├── main.ts │?? ├── pages │?? │?? ├── About.svelte │?? │?? ├── AddPassword.svelte │?? │?? ├── Details.svelte │?? │?? ├── EditPassword.svelte │?? │?? ├── Home.svelte │?? │?? ├── Login.svelte │?? │?? └── Settings.svelte │?? ├── style.css │?? └── vite-env.d.ts ├── svelte.config.js ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── wailsjs ├── go │?? ├── main │?? │?? ├── App.d.ts │?? │?? └── App.js │?? └── models.ts └── runtime ├── package.json ├── runtime.d.ts └── runtime.js ...
Sie alle geben ein Versprechen zurück. Wenn das Versprechen eine als Rückgabetyp verwendete Go-Struktur ?umschlie?t“ oder die entsprechende Funktion einen Argumenttyp annimmt, gibt es ein Modul (models.ts, in diesem Fall typisiert, da wir TypeScript verwenden), das die dem Go entsprechende Klasse enth?lt Struktur und ihr Konstruktor in einem Namespace.
Darüber hinaus enth?lt der Laufzeit-Unterordner alle Methoden aus dem Laufzeitpaket von Go, die es uns erm?glichen, das Fenster und die Ereignisse zu manipulieren, die vom bzw. an das Backend abgeh?rt oder ausgegeben werden.
Der Ordner src enth?lt die Dateien, die von Vite kompiliert werden, um sie wie in jeder Webanwendung in ?frontend/dist“ zu speichern (und in die endgültige ausführbare Datei einzubetten). Beachten Sie, dass style.css die grundlegende Tailwind-Konfiguration sowie alle CSS-Klassen enth?lt, die wir verwenden müssen, da wir Tailwindcss verwenden. Ein Vorteil der Verwendung von Web-Technologie für die Benutzeroberfl?che besteht au?erdem darin, dass wir problemlos eine oder mehrere Schriftarten (Ordner-Assets/Schriftarten) verwenden oder austauschen k?nnen.
Um diese übersicht abzuschlie?en, beachten Sie, dass wir beim Kompilieren im Entwicklungsmodus (wails dev) nicht nur das Hot-Reloading erm?glichen, sondern auch die vorgenommenen ?nderungen (sowohl im Backend als auch im Frontend) beobachten k?nnen im Anwendungsfenster selbst, aber auch in einem Webbrowser über die Adresse http://localhost:34115, da ein Webserver gestartet wird. Dadurch k?nnen Sie Ihre bevorzugten Browser-Entwicklungserweiterungen verwenden. Allerdings muss man sagen, dass Wails selbst uns einige sehr nützliche Entwicklungstools zur Verfügung stellt, wenn wir mit der rechten Maustaste auf das Anwendungsfenster klicken (nur im Entwicklungsmodus) und ?Element prüfen“ w?hlen:
II – Und jetzt… ein Tauchgang in HTML, CSS und JavaScript?
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL // This file is automatically generated. DO NOT EDIT import {models} from '../models'; export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>; export function CheckMasterPassword(arg1:string):Promise<boolean>; export function DeleteEntry(arg1:string):Promise<void>; export function Drop():Promise<void>; export function GetAllEntries():Promise<Array<models.PasswordEntry>>; export function GetEntryById(arg1:string):Promise<models.PasswordEntry>; export function GetLanguage():Promise<string>; export function GetMasterPassword():Promise<boolean>; export function GetPasswordCount():Promise<number>; export function SaveLanguage(arg1:string):Promise<void>; export function SaveMasterPassword(arg1:string):Promise<string>; export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Wie Sie sehen k?nnen, gibt es 4 JavaScript-Pakete, die ich zu Svelte hinzugefügt habe (au?er dem bereits erw?hnten Tailwindcss Daisyui):
- Svelte-Copy, um das Kopieren von Benutzername und Passwort in die Zwischenablage zu erleichtern.
- svelte-i18n, für die i18n-Verarbeitung, d. h. dem Benutzer erm?glichen, die Sprache der Anwendung zu ?ndern.
- svelte-spa-router, eine kleine Routing-Bibliothek für Svelte, die den Wechsel der Ansichten im Anwendungsfenster erleichtert, da es sich in diesem Fall nicht lohnt, das ?offizielle“ Routing von zu verwenden SvelteKit.
- sweetalert2, im Grunde genommen verwenden Sie es, um Modalit?ten/Dialogfelder einfach und schnell zu erstellen.
Der Einstiegspunkt jedes SPA ist die Datei main.js (oder main.ts), also fangen wir damit an:
... . ├── index.html ├── package.json ├── package.json.md5 ├── package-lock.json ├── postcss.config.js ├── README.md ├── src │?? ├── App.svelte │?? ├── assets │?? │?? ├── fonts │?? │?? │?? ├── nunito-v16-latin-regular.woff2 │?? │?? │?? └── OFL.txt │?? │?? └── images │?? │?? └── logo-universal.png │?? ├── lib │?? │?? ├── BackBtn.svelte │?? │?? ├── BottomActions.svelte │?? │?? ├── EditActions.svelte │?? │?? ├── EntriesList.svelte │?? │?? ├── Language.svelte │?? │?? ├── popups │?? │?? │?? ├── alert-icons.ts │?? │?? │?? └── popups.ts │?? │?? ├── ShowPasswordBtn.svelte │?? │?? └── TopActions.svelte │?? ├── locales │?? │?? ├── en.json │?? │?? └── es.json │?? ├── main.ts │?? ├── pages │?? │?? ├── About.svelte │?? │?? ├── AddPassword.svelte │?? │?? ├── Details.svelte │?? │?? ├── EditPassword.svelte │?? │?? ├── Home.svelte │?? │?? ├── Login.svelte │?? │?? └── Settings.svelte │?? ├── style.css │?? └── vite-env.d.ts ├── svelte.config.js ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── wailsjs ├── go │?? ├── main │?? │?? ├── App.d.ts │?? │?? └── App.js │?? └── models.ts └── runtime ├── package.json ├── runtime.d.ts └── runtime.js ...
Ich habe die Dinge hervorgehoben, die ich dem von der Wails-CLI generierten Skelett hinzugefügt habe. Die svelte-i18n-Bibliothek erfordert, dass JSON-Dateien, die übersetzungen enthalten, in der Datei main.js/ts registriert werden, w?hrend gleichzeitig die Sprache Fallback/Initial festgelegt wird (obwohl wir Ich werde sehen, das wird sp?ter basierend auf den Pr?ferenzen des Benutzers manipuliert. Die JSON-Dateien mit den übersetzungen haben das Format:
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL // This file is automatically generated. DO NOT EDIT import {models} from '../models'; export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>; export function CheckMasterPassword(arg1:string):Promise<boolean>; export function DeleteEntry(arg1:string):Promise<void>; export function Drop():Promise<void>; export function GetAllEntries():Promise<Array<models.PasswordEntry>>; export function GetEntryById(arg1:string):Promise<models.PasswordEntry>; export function GetLanguage():Promise<string>; export function GetMasterPassword():Promise<boolean>; export function GetPasswordCount():Promise<number>; export function SaveLanguage(arg1:string):Promise<void>; export function SaveMasterPassword(arg1:string):Promise<string>; export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Ich finde, dass das System dieser Bibliothek einfach und praktisch ist, um übersetzungen von Svelte-Anwendungen zu erleichtern (weitere Informationen finden Sie in der Dokumentation):
/* package.json */ ... }, "dependencies": { "svelte-copy": "^2.0.0", "svelte-i18n": "^4.0.1", "svelte-spa-router": "^4.0.1", "sweetalert2": "^11.14.5" } ...
Sie k?nnen auch Websites wie diese verwenden, die Ihnen bei der übersetzung von JSON-Dateien in verschiedene Sprachen helfen. Das Problem besteht jedoch darin, dass Sie beim Füllen Ihrer .svelte-Dateien mit $format den überblick manuell behalten müssen, was mühsam und fehleranf?llig ist. Ich kenne keine M?glichkeit, diese Aufgabe zu automatisieren. Wenn es jemand wei?, würde es mich interessieren, wenn Sie es mir mitteilen würden. Ansonsten müsste ich mir eine Art Skript ausdenken, um diese Aufgabe zu erledigen.
Der n?chste Schritt beim Aufbau der Schnittstelle ist, wie in jeder Svelte-Anwendung, die App.svelte-Datei:
/* main.ts */ import { mount } from 'svelte' import './style.css' import App from './App.svelte' import { addMessages, init } from "svelte-i18n"; // ? ? import en from './locales/en.json'; // ? ? import es from './locales/es.json'; // ? ? addMessages('en', en); // ? ? addMessages('es', es); // ? ? init({ fallbackLocale: 'en', // ? ? initialLocale: 'en', // ? ? }); const app = mount(App, { target: document.getElementById('app')!, }) export default app
Hier verwenden wir GetMasterPassword, eine Bindung, die beim Kompilieren der Anwendung automatisch generiert und als ?ffentliche Methode der Struktur-App deklariert wurde (siehe erster Teil dieser Serie). Diese Funktion fragt die Datenbank ab und betrachtet den Benutzer für den Fall, dass darin ein Master-Passwort registriert ist, als bereits registriert (sie gibt ein Versprechen zurück, das einen booleschen Wert umschlie?t) und fordert ihn auf, das Passwort einzugeben, um ihm Zugriff auf den Rest zu gew?hren der Ansichten. Wenn in der Datenbank kein Master-Passwort vorhanden ist, gilt der Benutzer als ?neu“ und wird gebeten, sein eigenes Passwort zu generieren, um die Anwendung zum ersten Mal zu betreten.
Abschlie?end tun wir beim Mounten der Login.svelte-Komponente etwas, das für den Rest der Anwendung wichtig ist. Obwohl die svelte-i18n-Bibliothek uns zwingt, den anf?nglichen Sprachcode zu deklarieren, wie wir bereits gesehen haben, fordern wir beim Mounten von Login.svelte die Datenbank auf (mithilfe der GetLanguage-Bindung), zu überprüfen, ob ein Sprachcode gespeichert ist. Falls die Datenbank eine leere Zeichenfolge zurückgibt, d. h. wenn keine Sprache als Pr?ferenz des Benutzers konfiguriert ist, verwendet svelte-i18n den als initialLocale konfigurierten Wert. Wenn stattdessen eine Sprache konfiguriert ist, wird diese Sprache festgelegt (locale.set(result);) und das Ereignis ?change_titles“ ausgegeben, an das die übersetzten Titel der Titelleiste und der nativen Dialoge der App übergeben werden damit das Backend Folgendes verarbeiten kann:
/* frontend/src/locales/en.json */ { "language": "Language", "app_title": "Nu-i uita ? minimalist password store", "select_directory": "Select the directory where to save the data export", "select_file": "Select the backup file to import", "master_password": "Master Password ?", "generate": "Generate", "insert": "Insert", "login": "Login", ... } /* frontend/src/locales/es.json */ { "language": "Idioma", "app_title": "Nu-i uita ? almacén de contrase?as minimalista", "select_directory": "Selecciona el directorio donde guardar los datos exportados", "select_file": "Selecciona el archivo de respaldo que deseas importar", "master_password": "Contrase?a Maestra ?", "generate": "Generar", "insert": "Insertar", "login": "Inciar sesión", ... }
Das Folgende ist die Logik für die Handhabung der Anmeldung:
... . ├── index.html ├── package.json ├── package.json.md5 ├── package-lock.json ├── postcss.config.js ├── README.md ├── src │?? ├── App.svelte │?? ├── assets │?? │?? ├── fonts │?? │?? │?? ├── nunito-v16-latin-regular.woff2 │?? │?? │?? └── OFL.txt │?? │?? └── images │?? │?? └── logo-universal.png │?? ├── lib │?? │?? ├── BackBtn.svelte │?? │?? ├── BottomActions.svelte │?? │?? ├── EditActions.svelte │?? │?? ├── EntriesList.svelte │?? │?? ├── Language.svelte │?? │?? ├── popups │?? │?? │?? ├── alert-icons.ts │?? │?? │?? └── popups.ts │?? │?? ├── ShowPasswordBtn.svelte │?? │?? └── TopActions.svelte │?? ├── locales │?? │?? ├── en.json │?? │?? └── es.json │?? ├── main.ts │?? ├── pages │?? │?? ├── About.svelte │?? │?? ├── AddPassword.svelte │?? │?? ├── Details.svelte │?? │?? ├── EditPassword.svelte │?? │?? ├── Home.svelte │?? │?? ├── Login.svelte │?? │?? └── Settings.svelte │?? ├── style.css │?? └── vite-env.d.ts ├── svelte.config.js ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── wailsjs ├── go │?? ├── main │?? │?? ├── App.d.ts │?? │?? └── App.js │?? └── models.ts └── runtime ├── package.json ├── runtime.d.ts └── runtime.js ...
Einfach ausgedrückt: newPassword, der an die Eingabe gebundene Status, der abruft, was der Benutzer eingibt, wird zun?chst von onLogin überprüft, um festzustellen, ob es mindestens 6 Zeichen enth?lt und ob es sich bei allen um ASCII-Zeichen handelt. d.h. sie sind nur 1 Byte lang (siehe den Grund dafür in Teil I dieser Serie) durch diese kleine Funktion const isAscii = (str: string): boolean => /^[x00-x7F] $/.test(str);. Wenn die Prüfung fehlschl?gt, kehrt die Funktion zurück und zeigt dem Benutzer eine Warnung Toast an. Wenn anschlie?end kein Master-Passwort in der Datenbank gespeichert ist (isLogin = false), wird der Benutzertyp unabh?ngig von der SaveMasterPassword-Funktion (einer von Wails generierten Bindung) gespeichert. Wenn das Versprechen erfolgreich gel?st wird (gibt eine uuid-Zeichenfolge als Id des in der Datenbank gespeicherten Datensatzes zurück), wird der Benutzer vom svelte-spa-router zur Home-Ansicht weitergeleitet Push-Methode der Bibliothek. Umgekehrt, wenn das Passwort die Prüfung auf L?nge und Abwesenheit von Nicht-ASCII-Zeichen besteht und es ein Master-Passwort in der Datenbank gibt (isLogin = true), dann überprüft die CheckMasterPassword-Funktion seine Identit?t anhand des gespeicherten Passworts und entweder bringt den Benutzer zur Home-Ansicht (Versprechen mit ?true“ aufgel?st) oder es wird ein Toast angezeigt, der darauf hinweist, dass das eingegebene Passwort falsch war.
Die zentrale Ansicht der Anwendung und gleichzeitig die komplexeste ist die Home-Ansicht. Sein HTML ist eigentlich in 3 Komponenten unterteilt: eine obere Schaltfl?chenleiste mit einer Sucheingabe (TopActions-Komponente), eine untere Schaltfl?chenleiste (BottomActions-Komponente) und einen zentralen Bereich, in dem die Gesamtzahl der gespeicherten Passworteintr?ge oder die Liste dieser angezeigt wird ein scrollbares Fenster (EntriesList-Komponente):
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL // This file is automatically generated. DO NOT EDIT import {models} from '../models'; export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>; export function CheckMasterPassword(arg1:string):Promise<boolean>; export function DeleteEntry(arg1:string):Promise<void>; export function Drop():Promise<void>; export function GetAllEntries():Promise<Array<models.PasswordEntry>>; export function GetEntryById(arg1:string):Promise<models.PasswordEntry>; export function GetLanguage():Promise<string>; export function GetMasterPassword():Promise<boolean>; export function GetPasswordCount():Promise<number>; export function SaveLanguage(arg1:string):Promise<void>; export function SaveMasterPassword(arg1:string):Promise<string>; export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Das hei?t, es macht den Suchstatus (searchTerms) zu einem leeren String, sodass dieser zurückgesetzt wird, wenn Suchbegriffe vorhanden sind und somit die gesamte Liste angezeigt wird. Und andererseits schaltet es den showList-Status um (props isEntriesList in TopActions), sodass die übergeordnete Komponente die Liste ein- oder ausblendet.
Wie wir im Diagramm oben sehen k?nnen, haben beide untergeordneten Komponenten dieselben props mit dem searchTerms-Status der übergeordneten Komponente. Die TopActions-Komponente erfasst die Eingaben des Benutzers und übergibt sie als Status an die übergeordnete Komponente Home, die sie wiederum als props an ihre untergeordnete Komponente EntriesList.
weitergibtDie Hauptlogik der Anzeige der vollst?ndigen Liste oder einer nach den vom Benutzer eingegebenen Suchbegriffen gefilterten Liste wird erwartungsgem?? von der EntriesList-Komponente ausgeführt:
... . ├── index.html ├── package.json ├── package.json.md5 ├── package-lock.json ├── postcss.config.js ├── README.md ├── src │?? ├── App.svelte │?? ├── assets │?? │?? ├── fonts │?? │?? │?? ├── nunito-v16-latin-regular.woff2 │?? │?? │?? └── OFL.txt │?? │?? └── images │?? │?? └── logo-universal.png │?? ├── lib │?? │?? ├── BackBtn.svelte │?? │?? ├── BottomActions.svelte │?? │?? ├── EditActions.svelte │?? │?? ├── EntriesList.svelte │?? │?? ├── Language.svelte │?? │?? ├── popups │?? │?? │?? ├── alert-icons.ts │?? │?? │?? └── popups.ts │?? │?? ├── ShowPasswordBtn.svelte │?? │?? └── TopActions.svelte │?? ├── locales │?? │?? ├── en.json │?? │?? └── es.json │?? ├── main.ts │?? ├── pages │?? │?? ├── About.svelte │?? │?? ├── AddPassword.svelte │?? │?? ├── Details.svelte │?? │?? ├── EditPassword.svelte │?? │?? ├── Home.svelte │?? │?? ├── Login.svelte │?? │?? └── Settings.svelte │?? ├── style.css │?? └── vite-env.d.ts ├── svelte.config.js ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── wailsjs ├── go │?? ├── main │?? │?? ├── App.d.ts │?? │?? └── App.js │?? └── models.ts └── runtime ├── package.json ├── runtime.d.ts └── runtime.js ...
Wie gesagt, es werden 2 Requisiten empfangen (listCounter und search) und ein Status wird beibehalten (Eintr?ge zulassen: models.PasswordEntry[] = $state([]);). Beim Mounten der Komponente auf Wunsch des Benutzers wird das Backend nach der vollst?ndigen Liste der gespeicherten Passworteintr?ge gefragt. Sind keine Suchbegriffe vorhanden, werden diese im Bundesland gespeichert; Wenn dies der Fall ist, wird eine einfache Filterung des erhaltenen Arrays durchgeführt und es wird im Status:
gespeichert
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL // This file is automatically generated. DO NOT EDIT import {models} from '../models'; export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>; export function CheckMasterPassword(arg1:string):Promise<boolean>; export function DeleteEntry(arg1:string):Promise<void>; export function Drop():Promise<void>; export function GetAllEntries():Promise<Array<models.PasswordEntry>>; export function GetEntryById(arg1:string):Promise<models.PasswordEntry>; export function GetLanguage():Promise<string>; export function GetMasterPassword():Promise<boolean>; export function GetPasswordCount():Promise<number>; export function SaveLanguage(arg1:string):Promise<void>; export function SaveMasterPassword(arg1:string):Promise<string>; export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
In der angezeigten Liste kann der Benutzer 2 Aktionen ausführen. Die erste besteht darin, die Details der Eingabe anzuzeigen, die ausgeführt wird, wenn er auf die entsprechende Schaltfl?che klickt: onclick={() => push(`/details/${entry.Id}`)}. Im Grunde rufen wir die Push-Methode der Routing-Bibliothek auf, um den Benutzer zur Detailansicht zu führen, übergeben aber den Parameter Id, der dem betreffenden Element entspricht.
Die andere Aktion, die der Benutzer ausführen kann, besteht darin, ein Element aus der Liste zu l?schen. Wenn er auf den entsprechenden Button klickt, wird ihm ein Best?tigungs-Popup angezeigt, das die Funktion showAlert aufruft. Diese Funktion ruft wiederum showWarning auf, was eigentlich eine Abstraktionsschicht über der Sweetalert2-Bibliothek ist (alle Funktionen, die die Sweetalert2-Bibliothek aufrufen, befinden sich in frontend/src/lib/popups/popups.ts). Wenn der Benutzer die L?schaktion best?tigt, wird die Bindung ?DeleteEntry“ aufgerufen (um sie aus der Datenbank zu l?schen). Wenn wiederum das von ihr zurückgegebene Versprechen aufgel?st wird, wird ?deleteItem“ aufgerufen (um sie aus dem im Eintragsstatus gespeicherten Array zu l?schen). :
/* package.json */ ... }, "dependencies": { "svelte-copy": "^2.0.0", "svelte-i18n": "^4.0.1", "svelte-spa-router": "^4.0.1", "sweetalert2": "^11.14.5" } ...
Die andere Komponente der Home-Ansicht (BottomActions) ist viel einfacher: Sie empf?ngt keine Requisiten und ist darauf beschr?nkt, den Benutzer zu verschiedenen Ansichten (Einstellungen, Info oder AddPassword) weiterzuleiten.
Die Ansichten ?AddPassword“ und ?EditPassword“ haben eine sehr ?hnliche Logik und ?hneln auch der Ansicht ?Anmelden“. Beide erlauben es dem Benutzer nicht, am Anfang und Ende seiner Texteingabe Leerzeichen einzugeben, und folgen der gleichen Richtlinie wie die Anmeldeansicht, wonach Passw?rter mindestens 6 ASCII-Zeichen lang sein müssen. Was sie im Wesentlichen auszeichnet, ist, dass sie die von Wails generierten Links als relevant für die Aktion bezeichnen, die sie ausführen müssen:
/* main.ts */ import { mount } from 'svelte' import './style.css' import App from './App.svelte' import { addMessages, init } from "svelte-i18n"; // ? ? import en from './locales/en.json'; // ? ? import es from './locales/es.json'; // ? ? addMessages('en', en); // ? ? addMessages('es', es); // ? ? init({ fallbackLocale: 'en', // ? ? initialLocale: 'en', // ? ? }); const app = mount(App, { target: document.getElementById('app')!, }) export default app
Die andere Ansicht, die etwas komplex ist, sind die Einstellungen. Dies verfügt über eine Sprachkomponente, die als props languageName von ihrer übergeordneten Komponente (Einstellungen) erh?lt:
/* frontend/src/locales/en.json */ { "language": "Language", "app_title": "Nu-i uita ? minimalist password store", "select_directory": "Select the directory where to save the data export", "select_file": "Select the backup file to import", "master_password": "Master Password ?", "generate": "Generate", "insert": "Insert", "login": "Login", ... } /* frontend/src/locales/es.json */ { "language": "Idioma", "app_title": "Nu-i uita ? almacén de contrase?as minimalista", "select_directory": "Selecciona el directorio donde guardar los datos exportados", "select_file": "Selecciona el archivo de respaldo que deseas importar", "master_password": "Contrase?a Maestra ?", "generate": "Generar", "insert": "Insertar", "login": "Inciar sesión", ... }
Der HTML-Code für diese Komponente ist eine einzelne Auswahl, die die Sprachauswahl des Benutzers übernimmt. In seinem onchange-Ereignis erh?lt es eine Funktion (handleChange), die drei Dinge tut:
- Legt die Sprache im Frontend mithilfe der Svelte-i18n-Bibliothek fest
- gibt ein Ereignis (?change_titles“) aus, damit die Wails-Laufzeit den Titel der Titelleiste der Anwendung und die Titel der Dialogfelder Verzeichnis ausw?hlen und Datei ausw?hlen entsprechend ?ndert zur vorherigen Aktion
- Speichert die vom Benutzer ausgew?hlte Sprache in der Datenbank, sodass die Anwendung beim n?chsten Start mit dieser Sprache konfiguriert ge?ffnet wird.
Zurück zur Einstellungsansicht: Der gesamte Betrieb wird durch eine Reihe von Ereignissen gesteuert, die an das Backend gesendet und von diesem empfangen werden. Am einfachsten ist die Schaltfl?che ?Beenden“: Wenn der Benutzer darauf klickt, wird ein Beendigungsereignis ausgel?st und im Backend abgeh?rt, und die Anwendung wird geschlossen (onclick={() => EventsEmit("quit")}). Ein Tipp informiert den Benutzer darüber, dass die Escape-Taste (Verknüpfung) die gleiche Aktion ausführt, wie wir bereits erkl?rt haben.
Die Reset-Taste ruft eine Funktion auf, die ein Popup-Fenster anzeigt:
... . ├── index.html ├── package.json ├── package.json.md5 ├── package-lock.json ├── postcss.config.js ├── README.md ├── src │?? ├── App.svelte │?? ├── assets │?? │?? ├── fonts │?? │?? │?? ├── nunito-v16-latin-regular.woff2 │?? │?? │?? └── OFL.txt │?? │?? └── images │?? │?? └── logo-universal.png │?? ├── lib │?? │?? ├── BackBtn.svelte │?? │?? ├── BottomActions.svelte │?? │?? ├── EditActions.svelte │?? │?? ├── EntriesList.svelte │?? │?? ├── Language.svelte │?? │?? ├── popups │?? │?? │?? ├── alert-icons.ts │?? │?? │?? └── popups.ts │?? │?? ├── ShowPasswordBtn.svelte │?? │?? └── TopActions.svelte │?? ├── locales │?? │?? ├── en.json │?? │?? └── es.json │?? ├── main.ts │?? ├── pages │?? │?? ├── About.svelte │?? │?? ├── AddPassword.svelte │?? │?? ├── Details.svelte │?? │?? ├── EditPassword.svelte │?? │?? ├── Home.svelte │?? │?? ├── Login.svelte │?? │?? └── Settings.svelte │?? ├── style.css │?? └── vite-env.d.ts ├── svelte.config.js ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── wailsjs ├── go │?? ├── main │?? │?? ├── App.d.ts │?? │?? └── App.js │?? └── models.ts └── runtime ├── package.json ├── runtime.d.ts └── runtime.js ...
Wenn der Benutzer die Aktion akzeptiert, wird die Drop-Bindung aufgerufen, die alle Sammlungen in der Datenbank bereinigt, und wenn das zurückgegebene Versprechen aufgel?st wird, wird der Benutzer zur Anmeldeansicht weitergeleitet und angezeigt ein Modal, das den Erfolg der Aktion angibt.
Die anderen beiden verbleibenden Aktionen sind einander ?hnlich, schauen wir uns also Daten importieren an.
Wenn der Benutzer auf die entsprechende Schaltfl?che klickt, wird ein Ereignis ausgegeben (onclick={() => EventsEmit("import_data")}), auf das im Backend gewartet wird. Nach dem Empfang wird das native Dialogfeld Datei ausw?hlen ge?ffnet, damit der Benutzer die Sicherungsdatei ausw?hlen kann. Wenn der Benutzer die Datei ausw?hlt, enth?lt die Variable mit dem Pfad (fileLocation) keinen leeren String und dies l?st ein Ereignis im Backend (?enter_password“) aus, das nun im Frontend abgeh?rt wird, um wiederum ein Ereignis anzuzeigen Neues Popup-Fenster, in dem Sie nach dem Master-Passwort gefragt werden, das beim Export verwendet wurde. Auch hier gibt das Frontend ein weiteres Ereignis (?Passwort“) aus, das das vom Benutzer eingegebene Master-Passwort tr?gt. Wenn dieses neue Ereignis im Backend empfangen wird, führt es die ImportDump-Methode des DB-Pakets aus, die die Arbeit des Lesens und Wiederherstellens der Daten in der DB aus der vom Benutzer ausgew?hlten Sicherungsdatei ausführt. Als Ergebnis wird ein neues Ereignis (?imported_data“) ausgegeben, das das Ergebnis (erfolgreich oder nicht erfolgreich) seiner Ausführung als angeh?ngte Daten tr?gt. Wenn das Frontend das Ereignis empf?ngt, muss es nur zwei Aufgaben ausführen:
- Wenn das Ergebnis erfolgreich war, stellen Sie die Sprache ein, die in der Sicherungsdatei gespeichert wurde, und zeigen Sie ein Modal an, das den Erfolg der Aktion anzeigt
- Wenn der Import aus irgendeinem Grund nicht durchgeführt werden konnte, zeigen Sie den Fehler und seine Ursache an.
All dies ist in der Codelogik viel einfacher zu erkennen, als mit Worten zu erkl?ren?:
... . ├── index.html ├── package.json ├── package.json.md5 ├── package-lock.json ├── postcss.config.js ├── README.md ├── src │?? ├── App.svelte │?? ├── assets │?? │?? ├── fonts │?? │?? │?? ├── nunito-v16-latin-regular.woff2 │?? │?? │?? └── OFL.txt │?? │?? └── images │?? │?? └── logo-universal.png │?? ├── lib │?? │?? ├── BackBtn.svelte │?? │?? ├── BottomActions.svelte │?? │?? ├── EditActions.svelte │?? │?? ├── EntriesList.svelte │?? │?? ├── Language.svelte │?? │?? ├── popups │?? │?? │?? ├── alert-icons.ts │?? │?? │?? └── popups.ts │?? │?? ├── ShowPasswordBtn.svelte │?? │?? └── TopActions.svelte │?? ├── locales │?? │?? ├── en.json │?? │?? └── es.json │?? ├── main.ts │?? ├── pages │?? │?? ├── About.svelte │?? │?? ├── AddPassword.svelte │?? │?? ├── Details.svelte │?? │?? ├── EditPassword.svelte │?? │?? ├── Home.svelte │?? │?? ├── Login.svelte │?? │?? └── Settings.svelte │?? ├── style.css │?? └── vite-env.d.ts ├── svelte.config.js ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── wailsjs ├── go │?? ├── main │?? │?? ├── App.d.ts │?? │?? └── App.js │?? └── models.ts └── runtime ├── package.json ├── runtime.d.ts └── runtime.js ...
Es ist erw?hnenswert, dass die Wails-Laufzeitfunktion, die Listener im Frontend registriert (EventsOn), eine Funktion zurückgibt, die bei Aufruf den Listener l?scht. Es ist praktisch, diese Listener abzubrechen, wenn die Komponente zerst?rt wird. ?hnlich wie React kann der onMount-Hook diese Listener ?bereinigen“, indem er sie dazu bringt, eine Bereinigungsfunktion zurückzugeben, die in diesem Fall alle von EventsOn zurückgegebenen Funktionen aufruft, die wir vorsorglich separat gespeichert haben Variablen:
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH ? MODIWL // This file is automatically generated. DO NOT EDIT import {models} from '../models'; export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>; export function CheckMasterPassword(arg1:string):Promise<boolean>; export function DeleteEntry(arg1:string):Promise<void>; export function Drop():Promise<void>; export function GetAllEntries():Promise<Array<models.PasswordEntry>>; export function GetEntryById(arg1:string):Promise<models.PasswordEntry>; export function GetLanguage():Promise<string>; export function GetMasterPassword():Promise<boolean>; export function GetPasswordCount():Promise<number>; export function SaveLanguage(arg1:string):Promise<void>; export function SaveMasterPassword(arg1:string):Promise<string>; export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Um diese überprüfung des Frontend-Teils unserer Anwendung abzuschlie?en, bleibt nur noch etwas über die About-Komponente zu sagen. Dies hat wenig Logik, da es sich auf die Anzeige von Informationen über die Anwendung beschr?nkt, wie es in einem About üblich ist. Es sollte jedoch gesagt werden, dass die Ansicht, wie wir sehen k?nnen, einen Link zum Anwendungs-Repository anzeigt. Offensichtlich würde uns ein Ankertag () auf einer normalen Webseite dazu veranlassen, zum entsprechenden Link zu navigieren, aber in einer Desktop-Anwendung würde dies nicht passieren, wenn Wails in seiner Laufzeit keine spezielle Funktion (BrowserOpenURL) dafür h?tte :
/* package.json */ ... }, "dependencies": { "svelte-copy": "^2.0.0", "svelte-i18n": "^4.0.1", "svelte-spa-router": "^4.0.1", "sweetalert2": "^11.14.5" } ...
Dadurch wird die Bin?rdatei im Ordner build/bin erstellt. Wenn Sie jedoch andere Build-Optionen ausw?hlen oder Cross-Compiling durchführen m?chten, sollten Sie sich die Wails-CLI-Dokumentation ansehen.
Für diese Anwendung habe ich sie, glaube ich, bereits im ersten Teil dieser Serie erw?hnt, ich habe mich nur auf die Kompilierung für Windows und Linux konzentriert. Um diese Aufgaben (die sich aufgrund von Tests wiederholen) auf komfortable Weise auszuführen, habe ich einige kleine Skripte und ein Makefile erstellt, das sie ?koordiniert“.
Der Befehl make create-bundles erstellt für die Linux-Version eine .tar.xz-komprimierte Datei mit der Anwendung und einem Makefile, das als ?Installer“ fungiert, der die ausführbare Datei installiert, einen Desktop-Eintrag zum Erstellen eines Eintrags im Startmenü und das entsprechende Anwendungssymbol. Für die Windows-Version wird die Bin?rdatei einfach als .zip in einem Ordner namens dist/ komprimiert. Wenn Sie jedoch einen plattformübergreifenden automatisierten Build bevorzugen, verfügt Wails über Github-Aktionen, mit denen Sie die generierten Artefakte hochladen k?nnen (Standardoption). zu Ihrem Repository.
Beachten Sie, dass, wenn Sie den Befehl make create-bundles verwenden, wenn Sie ihn ausführen, die Wails-Befehle wails build -clean -upx (im Fall von Linux) oder wails build -skipbindings -s -platform windows/amd64 aufgerufen werden. upx (im Fall von Windows). Das Flag -upx bezieht sich auf die Komprimierung der Bin?rdatei mit dem Dienstprogramm UPX, das Sie auf Ihrem Computer installiert haben sollten. Ein Teil des Geheimnisses der geringen Gr??e der ausführbaren Datei liegt in der hervorragenden Komprimierungsleistung, die dieses Dienstprogramm leistet.
Beachten Sie abschlie?end, dass die Build-Skripte das aktuelle Repository-Tag automatisch zur Info-Ansicht hinzufügen und nach dem Build seinen Wert auf den Standardwert (DEV_VERSION) zurücksetzen.
Puh! Diese beiden Beitr?ge waren am Ende l?nger als ich dachte! Aber ich hoffe, dass sie Ihnen gefallen haben und dass sie Ihnen vor allem dabei helfen, über neue Projekte nachzudenken. Etwas im Programmieren zu lernen funktioniert so…
Denken Sie daran, dass Sie den gesamten Anwendungscode in diesem GitHub-Repository finden.
Ich bin sicher, wir sehen uns in anderen Beitr?gen. Viel Spa? beim Codieren ?!!
Das obige ist der detaillierte Inhalt vonEine minimalistische Passwort-Manager-Desktop-App: ein Ausflug in das Wails-Framework von Golang (Teil 2). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Hei?e KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?er Artikel

Hei?e Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Golang wird haupts?chlich für die Back-End-Entwicklung verwendet, kann aber auch eine indirekte Rolle im Front-End-Bereich spielen. Die Konstruktionsziele konzentrieren sich auf leistungsstarke, gleichzeitige Programmierungen und Systeme auf Systemebene und eignen sich zum Erstellen von Back-End-Anwendungen wie API-Servern, Microservices, verteilten Systemen, Datenbankoperationen und CLI-Tools. Obwohl Golang nicht die Mainstream-Sprache für das Web-Front-End ist, kann er über Gopherjs in JavaScript zusammengestellt werden, auf WebAssembly über Tinygo ausgeführt werden oder HTML-Seiten mit einer Vorlagenmotor zur Teilnahme an der Front-End-Entwicklung erzeugen. Die moderne Front-End-Entwicklung muss jedoch noch auf JavaScript/Typecript und sein ?kosystem beruhen. Daher eignet sich Golang besser für die Auswahl der Technologiestapel mit Hochleistungs-Backend als Kern.

Um ein GraphQLAPI in Go zu erstellen, wird empfohlen, die GQLGen -Bibliothek zur Verbesserung der Entwicklungseffizienz zu verwenden. 1. W?hlen Sie zun?chst die entsprechende Bibliothek wie GQLGen aus, die die automatische Codegenerierung basierend auf dem Schema unterstützt. 2. Definieren Sie dann GraphQlSchema, beschreiben Sie das API -Struktur und das Abfrageportal, z. B. das Definieren von Post -Typen und Abfragemethoden; 3. Initialisieren Sie dann das Projekt und generieren Sie grundlegende Code, um die Gesch?ftslogik in Resolver zu implementieren. 4. Schlie?lich verbinden Sie GraphQlHandler mit HTTPServer und testen Sie die API über den integrierten Spielplatz. Zu den Anmerkungen geh?ren Feldnamenspezifikationen, Fehlerbehandlung, Leistungsoptimierung und Sicherheitseinstellungen, um die Projektwartung sicherzustellen

Der Schlüssel zur Installation von GO besteht darin, die richtige Version auszuw?hlen, Umgebungsvariablen zu konfigurieren und die Installation zu überprüfen. 1. Gehen Sie zur offiziellen Website, um das Installationspaket des entsprechenden Systems herunterzuladen. Windows verwendet .msi -Dateien, macOS. PKG -Dateien, Linux verwendet .tar.gz -Dateien und entpackt sie in /usr /lokales Verzeichnis. 2. Konfigurieren Sie Umgebungsvariablen, bearbeiten Sie ~/.bashrc oder ~/.zshrc in Linux/macOS, um Pfad und GOPath hinzuzufügen, und Windows -Set -Pfad, um die Systemeigenschaften zu verfolgen. 3.. Verwenden Sie das Regierungsbefehl, um die Installation zu überprüfen, und führen Sie das Testprogramm Hello.go aus, um zu best?tigen, dass die Zusammenstellung und Ausführung normal ist. Pfadeinstellungen und Schleifen w?hrend des gesamten Prozesses

Sync.waitGroup wird verwendet, um auf eine Gruppe von Goroutinen zu warten, um die Aufgabe zu erledigen. Sein Kern besteht darin, drei Methoden zusammenzuarbeiten: hinzufügen, fertig und warten. 1.Add (n) Stellen Sie die Anzahl der Goroutiner fest, um zu warten; 2.Done () wird am Ende jeder Goroutine bezeichnet, und die Anzahl wird um eins reduziert; 3.wait () blockiert die Hauptkorutine, bis alle Aufgaben erledigt sind. Beachten Sie bitte, dass Sie bei der Verwendung au?erhalb der Goroutine doppelte Warten vermeiden, und stellen Sie sicher, dass der Don aufgerufen wird. Es wird empfohlen, es mit Aufhebung zu verwenden. Es ist h?ufig bei der gleichzeitigen Krabbeln von Webseiten, der Stapeldatenverarbeitung und anderer Szenarien und kann den Parallelit?tsprozess effektiv steuern.

Durch die Verwendung von GO -Einbettenpaket k?nnen statische Ressourcen einfach in bin?re und für Webdienste geeignet einbetten, um HTML, CSS, Bilder und andere Dateien zu verpacken. 1. Deklarieren Sie die eingebettete Ressource zum Hinzufügen // Go: Einbetten Sie einen Kommentar vor der Variablen ein, z. B. das Einbettung einer einzelnen Datei hello.txt; 2. Es kann in das gesamte Verzeichnis wie static/*eingebettet werden und die Multi-File-Verpackung durch Einbettung.Fs realisieren; 3.. Es wird empfohlen, den Festplattenlastmodus über Geb?ude- oder Umgebungsvariablen zu wechseln, um die Effizienz zu verbessern. 4. Achten Sie auf Pfadgenauigkeit, Einschr?nkungen der Dateigr??en und schreibgeschützte Merkmale eingebetteter Ressourcen. Die rationale Verwendung von Einbetten kann die Bereitstellung vereinfachen und die Projektstruktur optimieren.

Der Kern der Audio- und Videoverarbeitung liegt darin, die grundlegenden Prozess- und Optimierungsmethoden zu verstehen. 1. Der grundlegende Prozess umfasst Akquisition, Codierung, übertragung, Decodierung und Wiedergabe, und jeder Link hat technische Schwierigkeiten. 2. H?ufige Probleme wie Audio- und Video -Aberration, Verz?gerungsverz?gerung, Schallger?usch, verschwommenes Bild usw. k?nnen durch synchrone Einstellung, Codierungsoptimierung, Rauschverringerungsmodul, Parameteranpassung usw. gel?st werden; 3.. Es wird empfohlen, FFMPEG, OpenCV, Webrtc, Gstreamer und andere Tools zu verwenden, um Funktionen zu erzielen. 4. In Bezug auf das Leistungsmanagement sollten wir auf die Beschleunigung der Hardware, die angemessene Einstellung der Aufl?sungsrahmenquoten, die Kontrollverkehr und Speicher -Leckage -Probleme achten. Wenn Sie diese wichtigen Punkte beherrschen, werden die Entwicklungseffizienz und die Benutzererfahrung verbessert.

Es ist nicht schwierig, einen in Go geschriebenen Webserver zu erstellen. Der Kern liegt in der Verwendung des NET/HTTP -Pakets zur Implementierung grundlegender Dienste. 1. Verwenden Sie Net/HTTP, um den einfachsten Server zu starten: Registrieren Sie die Verarbeitungsfunktionen und h?ren Sie Ports über einige Codezeilen an. 2. Routing -Management: Verwenden Sie ServeMux, um mehrere Schnittstellenpfade für eine einfache strukturierte Verwaltung zu organisieren. 3. H?ufige Praktiken: Gruppenrouting nach funktionalen Modulen und verwenden Bibliotheken von Drittanbietern, um eine komplexe übereinstimmung zu unterstützen. 4. Statischer Dateidienst: Geben Sie HTML-, CSS- und JS -Dateien über http.FileServer an; 5. Leistung und Sicherheit: Aktivieren Sie HTTPS, begrenzen Sie die Gr??e des Anforderungsorganisation und stellen Sie Zeitüberschreitungen ein, um die Sicherheit und Leistung zu verbessern. Nach dem Beherrschen dieser Schlüsselpunkte ist es einfacher, die Funktionalit?t zu erweitern.

Der Zweck von Select Plus -Standard besteht darin, das Ausw?hlen zu erm?glichen, ein Standardverhalten durchzuführen, wenn keine anderen Zweige bereit sind, um das Programmblockieren zu vermeiden. 1. Beim Empfangen von Daten aus dem Kanal ohne Blockierung, wenn der Kanal leer ist, wird direkt die Standardzweigung eingegeben. 2. In Kombination mit der Zeit. Nach oder Ticker versuchen Sie, Daten regelm??ig zu senden. Wenn der Kanal voll ist, wird er nicht blockiert und überspringt. 3. Verhindern Sie Deadlocks, vermeiden Sie das Programm, das nicht sicher ist, ob der Kanal geschlossen ist. Beachten Sie bei der Verwendung, dass die Standardzweig sofort ausgeführt wird und nicht missbraucht wird, und standardm??ig und der Fall sind sich gegenseitig ausschlie?lich und werden nicht gleichzeitig ausgeführt.
