5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-03 06:20:48 +08:00

Bridge working for calls. Notify TBD

This commit is contained in:
Lea Anthony 2021-02-08 06:36:13 +11:00
parent e4b03f510b
commit 7c22cbcf38
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
17 changed files with 378 additions and 74 deletions

View File

@ -3,12 +3,12 @@
"browser": true, "browser": true,
"es6": true, "es6": true,
"amd": true, "amd": true,
"node": true, "node": true
}, },
"extends": "eslint:recommended", "extends": "eslint:recommended",
"parserOptions": { "parserOptions": {
"ecmaVersion": 2016, "ecmaVersion": 2016,
"sourceType": "module", "sourceType": "module"
}, },
"rules": { "rules": {
"indent": [ "indent": [

View File

@ -54,7 +54,6 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
var debugBinaryProcess *process.Process = nil var debugBinaryProcess *process.Process = nil
var buildFrontend bool = false var buildFrontend bool = false
var extensionsThatTriggerARebuild = strings.Split(extensions, ",") var extensionsThatTriggerARebuild = strings.Split(extensions, ",")
println(extensionsThatTriggerARebuild)
// Setup signal handler // Setup signal handler
quitChannel := make(chan os.Signal, 1) quitChannel := make(chan os.Signal, 1)

View File

@ -7,6 +7,7 @@ require (
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/fatih/structtag v1.2.0 github.com/fatih/structtag v1.2.0
github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify v1.4.9
github.com/gorilla/websocket v1.4.1
github.com/imdario/mergo v0.3.11 github.com/imdario/mergo v0.3.11
github.com/jackmordaunt/icns v1.0.0 github.com/jackmordaunt/icns v1.0.0
github.com/leaanthony/clir v1.0.4 github.com/leaanthony/clir v1.0.4

View File

@ -231,7 +231,5 @@ func (a *App) Run() error {
return err return err
} }
println("Desktop.Run() finished")
return nil return nil
} }

View File

@ -232,8 +232,6 @@ func (a *App) Run() error {
return err return err
} }
println("Desktop.Run() finished")
return nil return nil
} }

View File

@ -1,32 +1,56 @@
package bridge package bridge
import ( import (
"context"
"log" "log"
"net/http" "net/http"
"sync"
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
) )
type Bridge struct { type Bridge struct {
upgrader websocket.Upgrader upgrader websocket.Upgrader
server *http.Server server *http.Server
myLogger *logger.Logger myLogger *logger.Logger
bindings string
dispatcher *messagedispatcher.Dispatcher
mu sync.Mutex
sessions map[string]*session
ctx context.Context
cancel context.CancelFunc
} }
func NewBridge(myLogger *logger.Logger) *Bridge { func NewBridge(myLogger *logger.Logger) *Bridge {
result := &Bridge{ result := &Bridge{
myLogger: myLogger, myLogger: myLogger,
upgrader: websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}, upgrader: websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }},
sessions: make(map[string]*session),
} }
myLogger.SetLogLevel(1)
ctx, cancel := context.WithCancel(context.Background())
result.ctx = ctx
result.cancel = cancel
result.server = &http.Server{Addr: ":34115"} result.server = &http.Server{Addr: ":34115"}
http.HandleFunc("/bridge", result.wsBridgeHandler) http.HandleFunc("/bridge", result.wsBridgeHandler)
return result return result
} }
func (b *Bridge) Run(dispatcher *messagedispatcher.Dispatcher, bindingDump string, debug bool) error { func (b *Bridge) Run(dispatcher *messagedispatcher.Dispatcher, bindings string, debug bool) error {
// Ensure we cancel the context when we shutdown
defer b.cancel()
b.bindings = bindings
b.dispatcher = dispatcher
b.myLogger.Info("Bridge mode started.") b.myLogger.Info("Bridge mode started.")
@ -44,18 +68,32 @@ func (b *Bridge) wsBridgeHandler(w http.ResponseWriter, r *http.Request) {
log.Print("upgrade:", err) log.Print("upgrade:", err)
return return
} }
defer c.Close()
for {
mt, message, err := c.ReadMessage()
if err != nil { if err != nil {
log.Println("read:", err) http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
break
}
log.Printf("recv: %s", message)
err = c.WriteMessage(mt, message)
if err != nil {
log.Println("write:", err)
break
}
} }
b.myLogger.Info("Connection from frontend accepted [%s].", c.RemoteAddr().String())
b.startSession(c)
}
func (b *Bridge) startSession(conn *websocket.Conn) {
// Create a new session for this connection
s := newSession(conn, b.bindings, b.dispatcher, b.myLogger, b.ctx)
// Setup the close handler
conn.SetCloseHandler(func(int, string) error {
b.myLogger.Info("Connection dropped [%s].", s.Identifier())
b.mu.Lock()
delete(b.sessions, s.Identifier())
b.mu.Unlock()
return nil
})
b.mu.Lock()
go s.start(len(b.sessions) == 0)
b.sessions[s.Identifier()] = s
b.mu.Unlock()
} }

View File

@ -0,0 +1,121 @@
package bridge
import (
"github.com/wailsapp/wails/v2/pkg/options/dialog"
)
type BridgeClient struct {
session *session
}
func (b BridgeClient) Quit() {
b.session.log.Info("Quit unsupported in Bridge mode")
}
func (b BridgeClient) NotifyEvent(message string) {
//b.session.sendMessage("n" + message)
b.session.log.Info("NotifyEvent: %s", message)
b.session.log.Info("NotifyEvent unsupported in Bridge mode")
}
func (b BridgeClient) CallResult(message string) {
b.session.sendMessage("c" + message)
}
func (b BridgeClient) OpenDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
b.session.log.Info("OpenDialog unsupported in Bridge mode")
}
func (b BridgeClient) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
b.session.log.Info("SaveDialog unsupported in Bridge mode")
}
func (b BridgeClient) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
b.session.log.Info("MessageDialog unsupported in Bridge mode")
}
func (b BridgeClient) WindowSetTitle(title string) {
b.session.log.Info("WindowSetTitle unsupported in Bridge mode")
}
func (b BridgeClient) WindowShow() {
b.session.log.Info("WindowShow unsupported in Bridge mode")
}
func (b BridgeClient) WindowHide() {
b.session.log.Info("WindowHide unsupported in Bridge mode")
}
func (b BridgeClient) WindowCenter() {
b.session.log.Info("WindowCenter unsupported in Bridge mode")
}
func (b BridgeClient) WindowMaximise() {
b.session.log.Info("WindowMaximise unsupported in Bridge mode")
}
func (b BridgeClient) WindowUnmaximise() {
b.session.log.Info("WindowUnmaximise unsupported in Bridge mode")
}
func (b BridgeClient) WindowMinimise() {
b.session.log.Info("WindowMinimise unsupported in Bridge mode")
}
func (b BridgeClient) WindowUnminimise() {
b.session.log.Info("WindowUnminimise unsupported in Bridge mode")
}
func (b BridgeClient) WindowPosition(x int, y int) {
b.session.log.Info("WindowPosition unsupported in Bridge mode")
}
func (b BridgeClient) WindowSize(width int, height int) {
b.session.log.Info("WindowSize unsupported in Bridge mode")
}
func (b BridgeClient) WindowSetMinSize(width int, height int) {
b.session.log.Info("WindowSetMinSize unsupported in Bridge mode")
}
func (b BridgeClient) WindowSetMaxSize(width int, height int) {
b.session.log.Info("WindowSetMaxSize unsupported in Bridge mode")
}
func (b BridgeClient) WindowFullscreen() {
b.session.log.Info("WindowFullscreen unsupported in Bridge mode")
}
func (b BridgeClient) WindowUnFullscreen() {
b.session.log.Info("WindowUnFullscreen unsupported in Bridge mode")
}
func (b BridgeClient) WindowSetColour(colour int) {
b.session.log.Info("WindowSetColour unsupported in Bridge mode")
}
func (b BridgeClient) DarkModeEnabled(callbackID string) {
b.session.log.Info("DarkModeEnabled unsupported in Bridge mode")
}
func (b BridgeClient) SetApplicationMenu(menuJSON string) {
b.session.log.Info("SetApplicationMenu unsupported in Bridge mode")
}
func (b BridgeClient) SetTrayMenu(trayMenuJSON string) {
b.session.log.Info("SetTrayMenu unsupported in Bridge mode")
}
func (b BridgeClient) UpdateTrayMenuLabel(JSON string) {
b.session.log.Info("UpdateTrayMenuLabel unsupported in Bridge mode")
}
func (b BridgeClient) UpdateContextMenu(contextMenuJSON string) {
b.session.log.Info("UpdateContextMenu unsupported in Bridge mode")
}
func newBridgeClient(session *session) *BridgeClient {
return &BridgeClient{
session: session,
}
}

View File

@ -0,0 +1,145 @@
package bridge
import (
"context"
_ "embed"
"log"
"runtime"
"time"
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
"github.com/gorilla/websocket"
"github.com/wailsapp/wails/v2/internal/logger"
)
//go:embed darwin.js
var darwinRuntime string
// session represents a single websocket session
type session struct {
bindings string
conn *websocket.Conn
//eventManager interfaces.EventManager
log *logger.Logger
//ipc interfaces.IPCManager
// Mutex for writing to the socket
shutdown chan bool
writeChan chan []byte
done bool
// context
ctx context.Context
// client
client *messagedispatcher.DispatchClient
}
func newSession(conn *websocket.Conn, bindings string, dispatcher *messagedispatcher.Dispatcher, logger *logger.Logger, ctx context.Context) *session {
result := &session{
conn: conn,
bindings: bindings,
log: logger,
shutdown: make(chan bool),
writeChan: make(chan []byte, 100),
ctx: ctx,
}
result.client = dispatcher.RegisterClient(newBridgeClient(result))
return result
}
// Identifier returns a string identifier for the remote connection.
// Taking the form of the client's <ip address>:<port>.
func (s *session) Identifier() string {
if s.conn != nil {
return s.conn.RemoteAddr().String()
}
return ""
}
func (s *session) sendMessage(msg string) error {
if !s.done {
s.writeChan <- []byte(msg)
}
return nil
}
func (s *session) start(firstSession bool) {
s.log.SetLogLevel(1)
s.log.Info("Connected to frontend.")
go s.writePump()
var wailsRuntime string
switch runtime.GOOS {
case "darwin":
wailsRuntime = darwinRuntime
default:
log.Fatal("platform not supported")
}
bindingsMessage := "window.wailsbindings = `" + s.bindings + "`;"
s.log.Info(bindingsMessage)
bootstrapMessage := bindingsMessage + wailsRuntime
s.sendMessage("b" + bootstrapMessage)
for {
messageType, buffer, err := s.conn.ReadMessage()
if messageType == -1 {
return
}
if err != nil {
s.log.Error("Error reading message: %v", err)
continue
}
message := string(buffer)
s.log.Debug("Got message: %#v\n", message)
// Dispatch message as normal
s.client.DispatchMessage(message)
if s.done {
break
}
}
}
// Shutdown
func (s *session) Shutdown() {
s.conn.Close()
s.done = true
s.log.Info("session %v exit", s.Identifier())
}
// writePump pulls messages from the writeChan and sends them to the client
// since it uses a channel to read the messages the socket is protected without locks
func (s *session) writePump() {
s.log.Debug("Session %v - writePump start", s.Identifier())
defer s.log.Debug("Session %v - writePump shutdown", s.Identifier())
for {
select {
case <-s.ctx.Done():
s.Shutdown()
return
case msg, ok := <-s.writeChan:
s.conn.SetWriteDeadline(time.Now().Add(1 * time.Second))
if !ok {
s.log.Debug("writeChan was closed!")
s.conn.WriteMessage(websocket.CloseMessage, []byte{})
return
}
if err := s.conn.WriteMessage(websocket.TextMessage, msg); err != nil {
s.log.Debug(err.Error())
return
}
}
}
}

View File

@ -169,7 +169,6 @@ func (a *Application) Run(incomingDispatcher Dispatcher, bindings string, debug
// Yes - Save memory reference and run app, cleaning up afterwards // Yes - Save memory reference and run app, cleaning up afterwards
a.saveMemoryReference(unsafe.Pointer(app)) a.saveMemoryReference(unsafe.Pointer(app))
C.Run(app, 0, nil) C.Run(app, 0, nil)
println("Back in ffenestri.go")
} else { } else {
// Oh no! We couldn't initialise the application // Oh no! We couldn't initialise the application
a.logger.Fatal("Cannot initialise Application.") a.logger.Fatal("Cannot initialise Application.")

File diff suppressed because one or more lines are too long

View File

@ -65,7 +65,7 @@ export function SetBindings(bindingsMap) {
window.backend[packageName][structName][methodName] = function () { window.backend[packageName][structName][methodName] = function () {
// No timeout by default // No timeout by default
var timeout = 0; let timeout = 0;
// Actual function // Actual function
function dynamic() { function dynamic() {
@ -89,19 +89,3 @@ export function SetBindings(bindingsMap) {
}); });
}); });
} }
// /**
// * Determines if the given identifier is valid Javascript
// *
// * @param {boolean} name
// * @returns
// */
// function isValidIdentifier(name) {
// // Don't xss yourself :-)
// try {
// new Function('var ' + name);
// return true;
// } catch (e) {
// return false;
// }
// }

View File

@ -13,6 +13,7 @@ import { Error } from './log';
import { SendMessage } from 'ipc'; import { SendMessage } from 'ipc';
// Defines a single listener with a maximum number of times to callback // Defines a single listener with a maximum number of times to callback
/** /**
* The Listener class defines a listener! :-) * The Listener class defines a listener! :-)
* *
@ -43,7 +44,7 @@ class Listener {
} }
} }
var eventListeners = {}; let eventListeners = {};
/** /**
* Registers an event listener that will be invoked `maxCallbacks` times before being destroyed * Registers an event listener that will be invoked `maxCallbacks` times before being destroyed
@ -96,7 +97,7 @@ export function Once(eventName, callback) {
function notifyListeners(eventData) { function notifyListeners(eventData) {
// Get the event name // Get the event name
var eventName = eventData.name; let eventName = eventData.name;
// Check if we have any listeners for this event // Check if we have any listeners for this event
if (eventListeners[eventName]) { if (eventListeners[eventName]) {
@ -110,7 +111,7 @@ function notifyListeners(eventData) {
// Get next listener // Get next listener
const listener = eventListeners[eventName][count]; const listener = eventListeners[eventName][count];
var data = eventData.data; let data = eventData.data;
// Do the callback // Do the callback
const destroy = listener.Callback(data); const destroy = listener.Callback(data);
@ -120,7 +121,7 @@ function notifyListeners(eventData) {
} }
} }
// Update callbacks with new list of listners // Update callbacks with new list of listeners
eventListeners[eventName] = newEventListenerList; eventListeners[eventName] = newEventListenerList;
} }
} }

View File

@ -62,6 +62,4 @@ export function Init() {
// Do platform specific Init // Do platform specific Init
Platform.Init(); Platform.Init();
window.wailsloader.runtime = true;
} }

View File

@ -27,7 +27,7 @@ export function Init() {
// Setup drag handler // Setup drag handler
// Based on code from: https://github.com/patr0nus/DeskGap // Based on code from: https://github.com/patr0nus/DeskGap
window.addEventListener('mousedown', function (e) { window.addEventListener('mousedown', function (e) {
var currentElement = e.target; let currentElement = e.target;
while (currentElement != null) { while (currentElement != null) {
if (currentElement.hasAttribute('data-wails-no-drag')) { if (currentElement.hasAttribute('data-wails-no-drag')) {
break; break;

View File

@ -22,7 +22,7 @@ function init() {
overlayHTML: overlayHTML:
'<div class="wails-reconnect-overlay"><div class="wails-reconnect-overlay-content"><div class="wails-reconnect-overlay-loadingspinner"></div></div></div>', '<div class="wails-reconnect-overlay"><div class="wails-reconnect-overlay-content"><div class="wails-reconnect-overlay-loadingspinner"></div></div></div>',
overlayCSS: overlayCSS:
'.wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:linear-gradient(45deg,rgb(0 0 0 / 60%) 0%,rgb(4 0 255 / 60%) 100%);font-family:sans-serif;display:none;z-index:999999}.wails-reconnect-overlay-content{text-align:center;width:10em;position:relative;margin:5% auto 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAflBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAAAAABAQEEBAQAAAAAAAAEBAQAAAADAwMAAAABAQEAAAAAAAAAAAAAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWCC3waAAAAKXRSTlMALgUMIBk0+xEqJs70Xhb3lu3EjX2EZTlv5eHXvbarQj3cdmpXSqOeUDwaqNAAAAKCSURBVEjHjZTntqsgEIUPVVCwtxg1vfD+L3hHRe8K6snZf+KKn8OewvzsSSeXLruLnz+KHs0gr6DkT3xsRkU6VVn4Ha/UxLe1Z4y64i847sykPBh/AvQ7ry3eFN70oKrfcBJYvm/tQ1qxP4T3emXPeXAkvodPUvtdjbhk+Ft4c0hslTiXVOzxOJ15NWUblQhRsdu3E1AfCjj3Gdm18zSOsiH8Lk4TB480ksy62fiqNo4OpyU8O21l6+hyRtS6z8r1pHlmle5sR1/WXS6Mq2Nl+YeKt3vr+vdH/q4O68tzXuwkiZmngYb4R8Co1jh0+Ww2UTyWxBvtyxLO7QVjO3YOD/lWZpbXDGellFG2Mws58mMnjVZSn7p+XvZ6IF4nn02OJZV0aTO22arp/DgLPtrgpVoi6TPbZm4XQBjY159w02uO0BDdYsfrOEi0M2ulRXlCIPAOuN1NOVhi+riBR3dgwQplYsZRZJLXq23Mlo5njkbY0rZFu3oiNIYG2kqsbVz67OlNuZZIOlfxHDl0UpyRX86z/OYC/3qf1A1xTrMp/PWWM4ePzf8DDp1nesQRpcFk7BlwdzN08ZIALJpCaciQXO0f6k4dnuT/Ewg4l7qSTNzm2SykdHn6GJ12mWc6aCNj/g1cTXpB8YFfr0uVc96aFkkqiIiX4nO+salKwGtIkvfB+Ja8DxMeD3hIXP5mTOYPB4eVT0+32I5ykvPZjesnkGgIREgYnmLrPb0PdV3hoLup2TjcGBPM4mgsfF5BrawZR4/GpzYQzQfrUZCf0TCWYo2DqhdhTJBQ6j4xqmmLN5LjdRIY8LWExiFUsSrza/nmFBqw3I9tEZB9h0lIQSO9if8DkISDAj8CDawAAAAASUVORK5CYII=);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#fff #eee0 #fff #eee0;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg); opacity}}', '.wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;backdrop-filter: blur(20px) saturate(160%) contrast(45%) brightness(140%);display:none;z-index:999999}.wails-reconnect-overlay-content{position:relative;top:50%;transform:translateY(-50%);margin: 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAflBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAAAAABAQEEBAQAAAAAAAAEBAQAAAADAwMAAAABAQEAAAAAAAAAAAAAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWCC3waAAAAKXRSTlMALgUMIBk0+xEqJs70Xhb3lu3EjX2EZTlv5eHXvbarQj3cdmpXSqOeUDwaqNAAAAKCSURBVEjHjZTntqsgEIUPVVCwtxg1vfD+L3hHRe8K6snZf+KKn8OewvzsSSeXLruLnz+KHs0gr6DkT3xsRkU6VVn4Ha/UxLe1Z4y64i847sykPBh/AvQ7ry3eFN70oKrfcBJYvm/tQ1qxP4T3emXPeXAkvodPUvtdjbhk+Ft4c0hslTiXVOzxOJ15NWUblQhRsdu3E1AfCjj3Gdm18zSOsiH8Lk4TB480ksy62fiqNo4OpyU8O21l6+hyRtS6z8r1pHlmle5sR1/WXS6Mq2Nl+YeKt3vr+vdH/q4O68tzXuwkiZmngYb4R8Co1jh0+Ww2UTyWxBvtyxLO7QVjO3YOD/lWZpbXDGellFG2Mws58mMnjVZSn7p+XvZ6IF4nn02OJZV0aTO22arp/DgLPtrgpVoi6TPbZm4XQBjY159w02uO0BDdYsfrOEi0M2ulRXlCIPAOuN1NOVhi+riBR3dgwQplYsZRZJLXq23Mlo5njkbY0rZFu3oiNIYG2kqsbVz67OlNuZZIOlfxHDl0UpyRX86z/OYC/3qf1A1xTrMp/PWWM4ePzf8DDp1nesQRpcFk7BlwdzN08ZIALJpCaciQXO0f6k4dnuT/Ewg4l7qSTNzm2SykdHn6GJ12mWc6aCNj/g1cTXpB8YFfr0uVc96aFkkqiIiX4nO+salKwGtIkvfB+Ja8DxMeD3hIXP5mTOYPB4eVT0+32I5ykvPZjesnkGgIREgYnmLrPb0PdV3hoLup2TjcGBPM4mgsfF5BrawZR4/GpzYQzQfrUZCf0TCWYo2DqhdhTJBQ6j4xqmmLN5LjdRIY8LWExiFUsSrza/nmFBqw3I9tEZB9h0lIQSO9if8DkISDAj8CDawAAAAASUVORK5CYII=);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#f00 #eee0 #f00 #eee0;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg); opacity}}',
log: function (message) { log: function (message) {
// eslint-disable-next-line // eslint-disable-next-line
console.log( console.log(
@ -34,6 +34,19 @@ function init() {
}; };
} }
function setupIPCBridge() {
// darwin
window.webkit = {
messageHandlers: {
external: {
postMessage: (message) => {
window.wailsbridge.websocket.send(message);
}
}
}
};
}
// Adapted from webview - thanks zserge! // Adapted from webview - thanks zserge!
function injectCSS(css) { function injectCSS(css) {
const elem = document.createElement('style'); const elem = document.createElement('style');
@ -116,6 +129,7 @@ function startBridge() {
// Handles incoming websocket connections // Handles incoming websocket connections
function handleConnect() { function handleConnect() {
window.wailsbridge.log('Connected to backend'); window.wailsbridge.log('Connected to backend');
setupIPCBridge();
hideReconnectOverlay(); hideReconnectOverlay();
clearInterval(window.wailsbridge.connectTimer); clearInterval(window.wailsbridge.connectTimer);
window.wailsbridge.websocket.onclose = handleDisconnect; window.wailsbridge.websocket.onclose = handleDisconnect;
@ -132,7 +146,7 @@ function startBridge() {
connect(); connect();
} }
// Try to connect to the backend every 300ms (default value). // Try to connect to the backend every 1s (default value).
// Change this value in the main wailsbridge object. // Change this value in the main wailsbridge object.
function connect() { function connect() {
window.wailsbridge.connectTimer = setInterval(function () { window.wailsbridge.connectTimer = setInterval(function () {
@ -154,37 +168,37 @@ function startBridge() {
// As a bridge we ignore js and css injections // As a bridge we ignore js and css injections
switch (message.data[0]) { switch (message.data[0]) {
// Wails library - inject! // Wails library - inject!
case 'w': case 'b':
addScript(message.data.slice(1)); message = message.data.slice(1)
addScript(message);
window.wailsbridge.log('Loaded Wails Runtime');
// Now wails runtime is loaded, wails for the ready event // Now wails runtime is loaded, wails for the ready event
// and callback to the main app // and callback to the main app
window.wails.Events.On('wails:loaded', function () { // window.wails.Events.On('wails:loaded', function () {
window.wailsbridge.log('Wails Ready');
if (window.wailsbridge.callback) { if (window.wailsbridge.callback) {
window.wailsbridge.log('Notifying application'); window.wailsbridge.log('Notifying application');
window.wailsbridge.callback(window.wails); window.wailsbridge.callback(window.wails);
} }
}); // });
window.wailsbridge.log('Loaded Wails Runtime');
break; break;
// Notifications // // Notifications
case 'n': // case 'n':
addScript(message.data.slice(1), true); // addScript(message.data.slice(1), true);
break; // break;
// Binding // // Binding
case 'b': // case 'b':
const binding = message.data.slice(1); // const binding = message.data.slice(1);
//log("Binding: " + binding) // //log("Binding: " + binding)
window.wails._.NewBinding(binding); // window.wails._.NewBinding(binding);
break; // break;
// Call back // // Call back
case 'c': case 'c':
const callbackData = message.data.slice(1); const callbackData = message.data.slice(1);
window.wails._.Callback(callbackData); window.wails._.Callback(callbackData);
break; break;
default: default:
window.wails.Log.Error('Unknown message type received: ' + message.data[0]); window.wailsbridge.log('Unknown message: ' + message.data);
} }
} }

View File

@ -21,7 +21,7 @@ function ready(callback) {
// If window.wails exists, we are ready // If window.wails exists, we are ready
if( window.wails ) { if( window.wails ) {
return callback; return callback();
} }
// If not we need to setup the bridge // If not we need to setup the bridge

View File

@ -50,12 +50,20 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
wailsJS := fs.RelativePath("../../../internal/runtime/assets/desktop_" + platform + ".js") wailsJS := fs.RelativePath("../assets/desktop_" + platform + ".js")
runtimeData, err := ioutil.ReadFile(wailsJS) runtimeData, err := ioutil.ReadFile(wailsJS)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
// Copy this file to bridge directory for embedding
bridgeDir := fs.RelativePath("../../bridge/" + platform + ".js")
println("Copying", wailsJS, "to", bridgeDir)
err = fs.CopyFile(wailsJS, bridgeDir)
if err != nil {
log.Fatal(err)
}
// Convert to C structure // Convert to C structure
runtimeC := ` runtimeC := `
// runtime.c (c) 2019-Present Lea Anthony. // runtime.c (c) 2019-Present Lea Anthony.