跳转到内容

Creating Custom Transport Layer

此内容尚不支持你的语言。

Wails v3 allows you to provide a custom IPC transport layer while retaining all generated bindings and event communication. This enables you to replace the default HTTP fetch-based transport with WebSockets, custom protocols, or any other transport mechanism.

By default, Wails uses HTTP fetch requests from the frontend to communicate with the backend via /wails/runtime. The custom transport API allows you to:

  • Replace the HTTP transport with WebSockets, gRPC, or any custom protocol
  • Maintain full compatibility with Wails code generation
  • Keep all existing bindings, events, dialogs, and other Wails features
  • Implement your own connection management, authentication, and error handling
┌─────────────────────────────────────────────────┐
│ Frontend (TypeScript) │
│ - Generated bindings still work │
│ - Your custom client transport │
└──────────────────┬──────────────────────────────┘
│ Your Protocol (WebSocket/etc)
┌──────────────────▼──────────────────────────────┐
│ Backend (Go) │
│ - Your Transport implementation │
│ - Wails MessageProcessor │
│ - All existing Wails infrastructure │
└─────────────────────────────────────────────────┘

Create a custom transport by implementing the Transport interface:

package main
import (
"context"
"github.com/wailsapp/wails/v3/pkg/application"
)
type MyCustomTransport struct {
// Your fields
}
func (t *MyCustomTransport) Start(ctx context.Context, processor *application.MessageProcessor) error {
// Initialize your transport (WebSocket server, gRPC server, etc.)
// When you receive requests, call processor.HandleRuntimeCallWithIDs()
return nil
}
func (t *MyCustomTransport) Stop() error {
// Clean up your transport
return nil
}

Pass your custom transport to the application options:

func main() {
app := application.New(application.Options{
Name: "My App",
Transport: &MyCustomTransport{},
// ... other options
})
err := app.Run()
if err != nil {
log.Fatal(err)
}
}

If using a custom transport, you’ll need to modify the frontend runtime to use your transport instead of HTTP fetch. Implement RuntimeTransport interface that will be used to handle requests:

const { setTransport } = await import('/wails/runtime.js');
class MyRuntimeTransport {
call(objectID: number, method: number, windowName: string, args: any): Promise<any> {
// TODO: implement IPC call with your transport protocol
return resp;
}
}
const myTransport = new MyRuntimeTransport();
setTransport(myTransport);
  • The default HTTP transport continues to work if no custom transport is specified
  • Generated bindings remain unchanged - only the transport layer changes
  • Events, dialogs, clipboard, and all other Wails features work transparently
  • You’re responsible for error handling, reconnection logic, and security in your custom transport
  • The WebSocket example provided is for demonstration and may need hardening for production use
type Transport interface {
Start(ctx context.Context, messageProcessor *application.MessageProcessor) error
// JSClient returns the JavaScript shim that the runtime injects into the
// window so that frontend code can call into the transport.
JSClient() []byte
Stop() error
}

For browser-based deployments or when you want to serve both assets and IPC through your custom transport, implement the AssetServerTransport interface:

type AssetServerTransport interface {
Transport
// ServeAssets configures the transport to serve assets alongside IPC.
// The assetHandler is Wails' internal asset server that handles all assets,
// runtime.js, capabilities, flags, etc.
ServeAssets(assetHandler http.Handler) error
}

When to implement this interface:

  • Running the app in a browser instead of a webview
  • Serving assets over HTTP alongside your custom IPC transport
  • Building network-accessible applications

Example implementation:

func (t *MyTransport) ServeAssets(assetHandler http.Handler) error {
mux := http.NewServeMux()
// Mount your IPC endpoint
mux.HandleFunc("/my/ipc/endpoint", t.handleIPC)
// Mount Wails asset server for everything else
mux.Handle("/", assetHandler)
// Start HTTP server
t.httpServer.Handler = mux
go t.httpServer.ListenAndServe()
return nil
}

When ServeAssets() is called, the assetHandler provides:

  • All static assets (HTML, CSS, JS, images, etc.)
  • /wails/runtime.js - The Wails runtime library
  • transport.go - Core transport interfaces and types
  • messageprocessor.go - The underlying message processor that handles all Wails IPC