Go-フロントエンドブリッジ
直接のGo-JavaScript通信
Section titled “直接のGo-JavaScript通信”Wailsは、GoとJavaScriptの間に直接のメモリ内ブリッジを提供し、HTTPのオーバーヘッド、プロセスの境界、シリアライズのボトルネックなしでシームレスな通信を可能にします。
重要なポイント: HTTPもIPCもプロセスの境界もありません。直接の関数呼び出しと型安全性のみです。
仕組み:ステップバイステップ
Section titled “仕組み:ステップバイステップ”1. サービス登録(起動時)
Section titled “1. サービス登録(起動時)”アプリケーションが起動すると、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 serviceapp := application.New(application.Options{ Services: []application.Service{ application.NewService(&GreetService{prefix: "Hello, "}), },})Wailsが行うこと:
- 構造体をスキャンしてエクスポートされたメソッドを検出
- 型情報を抽出(パラメータ、戻り値の型)
- レジストリを構築してメソッド名を関数にマッピング
- 完全な型定義を含むTypeScriptバインディングを生成
2. バインディング生成(ビルド時)
Section titled “2. バインディング生成(ビルド時)”WailsはTypeScriptバインディングを自動的に生成します:
export function Greet(name: string): Promise<string>export function Add(a: number, b: number): Promise<number>型マッピング:
| Goの型 | TypeScriptの型 |
|---|---|
string | string |
int, int32, int64 | number |
float32, float64 | number |
bool | boolean |
[]T | T[] |
map[string]T | Record<string, T> |
struct | interface |
time.Time | Date |
error | 例外(スロー) |
3. フロントエンド呼び出し(実行時)
Section titled “3. フロントエンド呼び出し(実行時)”開発者がJavaScriptからGoのメソッドを呼び出します:
import { Greet, Add } from './bindings/GreetService'
// Call Go from JavaScriptconst greeting = await Greet("World")console.log(greeting) // "Hello, World!"
const sum = await Add(5, 3)console.log(sum) // 8何が起こるか:
- バインディング関数が呼び出される -
Greet("World") - メッセージが作成される -
{ service: "GreetService", method: "Greet", args: ["World"] } - ブリッジに送信される - WebViewのJavaScriptブリッジ経由
- Promiseが返される - 応答を待機
4. ブリッジ処理(実行時)
Section titled “4. ブリッジ処理(実行時)”ブリッジはメッセージを受信して処理します:
セキュリティ: 登録されたサービスとエクスポートされたメソッドのみが呼び出し可能です。
5. Goの実行(実行時)
Section titled “5. Goの実行(実行時)”Goのメソッドが実行されます:
func (g *GreetService) Greet(name string) string { // This runs in Go return g.prefix + name + "!"}実行コンテキスト:
- ゴルーチンで実行(ノンブロッキング)
- すべてのGoの機能にアクセス可能(ファイルシステム、ネットワーク、データベース)
- 他のGoコードを自由に呼び出せる
- 結果またはエラーを返す
6. 応答(実行時)
Section titled “6. 応答(実行時)”結果がJavaScriptに戻されます:
// Promise resolves with resultconst 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"}パフォーマンス特性
Section titled “パフォーマンス特性”典型的な呼び出しオーバーヘッド: <1ms
Frontend Call → Bridge → Go Execution → Bridge → Frontend Response ↓ ↓ ↓ ↓ ↓ <0.1ms <0.1ms [varies] <0.1ms <0.1ms他の選択肢との比較:
- HTTP/REST: 5-50ms(ネットワークスタック、シリアライズ)
- IPC: 1-10ms(プロセスの境界、マーシャリング)
- Wailsブリッジ: <1ms(メモリ内、直接呼び出し)
呼び出しあたりのオーバーヘッド: 約1KB(メッセージバッファ)
ゼロコピー最適化: 大きなデータ(>1MB)は可能な限り共有メモリを使用します。
呼び出しは並行です:
- 各呼び出しは独自のゴルーチンで実行
- 複数の呼び出しを同時に実行可能
- 呼び出し間のブロッキングなし
// These run concurrentlyconst [result1, result2, result3] = await Promise.all([ SlowOperation1(), SlowOperation2(), SlowOperation3(),])サポートされている型
Section titled “サポートされている型”プリミティブ型
Section titled “プリミティブ型”// Gofunc 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]>スライスと配列
Section titled “スライスと配列”// Gofunc Sum(numbers []int) int { total := 0 for _, n := range numbers { total += n } return total}// TypeScriptfunction Sum(numbers: number[]): Promise<number>
// Usageconst total = await Sum([1, 2, 3, 4, 5]) // 15// Gofunc GetConfig() map[string]interface{} { return map[string]interface{}{ "theme": "dark", "fontSize": 14, "enabled": true, }}// TypeScriptfunction GetConfig(): Promise<Record<string, any>>
// Usageconst config = await GetConfig()console.log(config.theme) // "dark"// Gotype 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) を確認してください。