Aller au contenu

Pont Go-Frontend

Wails fournit un pont direct en mémoire entre Go et JavaScript, permettant une communication fluide sans surcharge HTTP, sans limites de processus et sans goulots d’étranglement liés à la sérialisation.

Diagram

Point clé : Pas de HTTP, pas d’IPC, pas de limites de processus. Juste des appels de fonction directs avec sécurité des types.

Lorsque votre application démarre, Wails analyse vos services :

type GreetService struct {
prefix string
}
func (g *GreetService) Greet(name string) string {
return g.prefix + name + "!"
}
func (g *GreetService) Add(a, b int) int {
return a + b
}
// Register service
app := application.New(application.Options{
Services: []application.Service{
application.NewService(&GreetService{prefix: "Hello, "}),
},
})

Ce que fait Wails :

  1. Analyse la structure pour trouver les méthodes exportées
  2. Extrait les informations de type (paramètres, types de retour)
  3. Construit un registre mappant les noms de méthodes aux fonctions
  4. Génère les liaisons TypeScript avec les définitions de type complètes

2. Génération des liaisons (Au moment de la compilation)

Section intitulée « 2. Génération des liaisons (Au moment de la compilation) »

Wails génère automatiquement les liaisons TypeScript :

frontend/bindings/GreetService.ts
export function Greet(name: string): Promise<string>
export function Add(a: number, b: number): Promise<number>

Mappage des types :

Type GoType TypeScript
stringstring
int, int32, int64number
float32, float64number
boolboolean
[]TT[]
map[string]TRecord<string, T>
structinterface
time.TimeDate
errorException (levée)

Le développeur appelle la méthode Go depuis JavaScript :

import { Greet, Add } from './bindings/GreetService'
// Call Go from JavaScript
const greeting = await Greet("World")
console.log(greeting) // "Hello, World!"
const sum = await Add(5, 3)
console.log(sum) // 8

Ce qui se passe :

  1. Fonction de liaison appelée - Greet("World")
  2. Message créé - { service: "GreetService", method: "Greet", args: ["World"] }
  3. Envoyé au pont - Via le pont JavaScript de WebView
  4. Promise retournée - Attend la réponse

Le pont reçoit le message et le traite :

Diagram

Sécurité : Seuls les services enregistrés et les méthodes exportées sont appelables.

La méthode Go s’exécute :

func (g *GreetService) Greet(name string) string {
// This runs in Go
return g.prefix + name + "!"
}

Contexte d’exécution :

  • S’exécute dans un goroutine (non bloquant)
  • A accès à toutes les fonctionnalités Go (système de fichiers, réseau, bases de données)
  • Peut appeler d’autres code Go librement
  • Retourne le résultat ou une erreur

Le résultat est renvoyé à JavaScript :

// Promise resolves with result
const greeting = await Greet("World")
// greeting = "Hello, World!"

Gestion des erreurs :

func (g *GreetService) Divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
try {
const result = await Divide(10, 0)
} catch (error) {
console.error("Go error:", error) // "division by zero"
}

Surcharge d’appel typique : <1ms

Frontend Call → Bridge → Go Execution → Bridge → Frontend Response
↓ ↓ ↓ ↓ ↓
&lt;0.1ms &lt;0.1ms [varies] &lt;0.1ms &lt;0.1ms

Comparé aux alternatives :

  • HTTP/REST : 5-50ms (pile réseau, sérialisation)
  • IPC : 1-10ms (limites de processus, marshalling)
  • Wails Bridge : <1ms (en mémoire, appel direct)

Surcharge par appel : ~1KB (tampon de message)

Optimisation sans copie : Les données volumineuses (>1MB) utilisent la mémoire partagée lorsque cela est possible.

Les appels sont concurrents :

  • Chaque appel s’exécute dans son propre goroutine
  • Plusieurs appels peuvent s’exécuter simultanément
  • Pas de blocage entre les appels
// These run concurrently
const [result1, result2, result3] = await Promise.all([
SlowOperation1(),
SlowOperation2(),
SlowOperation3(),
])
// Go
func Example(
s string,
i int,
f float64,
b bool,
) (string, int, float64, bool) {
return s, i, f, b
}
// TypeScript (auto-generated)
function Example(
s: string,
i: number,
f: number,
b: boolean,
): Promise<[string, number, number, boolean]>
// Go
func Sum(numbers []int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
// TypeScript
function Sum(numbers: number[]): Promise<number>
// Usage
const total = await Sum([1, 2, 3, 4, 5]) // 15
// Go
func GetConfig() map[string]interface{} {
return map[string]interface{}{
"theme": "dark",
"fontSize": 14,
"enabled": true,
}
}
// TypeScript
function GetConfig(): Promise<Record<string, any>>
// Usage
const config = await GetConfig()
console.log(config.theme) // "dark"
// Go
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func GetUser(id int) (*User, error) {
return &User{
ID: id,
Name: "Alice",---
**Des questions sur le pont ?** Posez-les sur [Discord](https://discord.gg/JDdSxwjhGf) ou consultez les [exemples de liaisons](https://github.com/wailsapp/wails/tree/master/v3/examples/binding).