Перейти к содержимому

Мост Go-Frontend

Wails предоставляет прямой мост в памяти между Go и JavaScript, обеспечивая бесшовную коммуникацию без накладных расходов HTTP, границ процессов или узких мест сериализации.

Diagram

Ключевой момент: Никакого HTTP, никакого IPC, никаких границ процессов. Только прямые вызовы функций с проверкой типов.

При запуске вашего приложения Wails сканирует ваши сервисы:

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, "}),
},
})

Что делает Wails:

  1. Сканирует структуру на наличие экспортируемых методов
  2. Извлекает информацию о типах (параметры, возвращаемые типы)
  3. Создает реестр, сопоставляющий имена методов функциям
  4. Генерирует привязки TypeScript с полными определениями типов

Wails автоматически генерирует привязки TypeScript:

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

Сопоставление типов:

Тип GoТип TypeScript
stringstring
int, int32, int64number
float32, float64number
boolboolean
[]TT[]
map[string]TRecord<string, T>
structinterface
time.TimeDate
errorИсключение (выбрасывается)

Разработчик вызывает метод Go из 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

Что происходит:

  1. Вызов функции привязки - Greet("World")
  2. Создание сообщения - { service: "GreetService", method: "Greet", args: ["World"] }
  3. Отправка в мост - Через JavaScript-мост WebView
  4. Возврат Promise - Ожидание ответа

Мост получает сообщение и обрабатывает его:

Diagram

Безопасность: Вызываемы только зарегистрированные сервисы и экспортируемые методы.

Метод Go выполняется:

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

Контекст выполнения:

  • Выполняется в горутине (неблокирующий)
  • Имеет доступ ко всем возможностям Go (файловая система, сеть, базы данных)
  • Может свободно вызывать другой код Go
  • Возвращает результат или ошибку

Результат отправляется обратно в JavaScript:

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

Обработка ошибок:

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"
}

Типичные накладные расходы на вызов: <1мс

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

По сравнению с альтернативами:

  • HTTP/REST: 5-50мс (сетевой стек, сериализация)
  • IPC: 1-10мс (границы процессов, маршалинг)
  • Wails Bridge: <1мс (в памяти, прямой вызов)

Накладные расходы на вызов: ~1КБ (буфер сообщения)

Оптимизация без копирования: Большие данные (>1МБ) используют разделяемую память, где это возможно.

Вызовы выполняются параллельно:

  • Каждый вызов выполняется в своей собственной горутине
  • Несколько вызовов могут выполняться одновременно
  • Нет блокировок между вызовами
// 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",---
**Вопросы о мосте?** Задавайте их в [Discord](https://discord.gg/JDdSxwjhGf) или проверяйте [примеры привязок](https://github.com/wailsapp/wails/tree/master/v3/examples/binding).