-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwebsocket.go
More file actions
77 lines (67 loc) · 1.77 KB
/
Copy pathwebsocket.go
File metadata and controls
77 lines (67 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package main
import (
"net/http"
"time"
"github.com/gorilla/websocket"
runtime "github.com/wailsapp/wails/v2/pkg/runtime"
)
// WebSocket support: a per-App registry of live connections. Each connection
// streams incoming text messages to the frontend via Wails runtime events
// "ws:message:<id>", and signals close via "ws:close:<id>".
// WSConnect dials a ws:// or wss:// URL and starts reading. It returns a
// connection id used to send/close and to scope the emitted events.
func (a *App) WSConnect(url string, headers map[string]string) (string, error) {
hdr := http.Header{}
for k, v := range headers {
hdr.Set(k, v)
}
dialer := websocket.Dialer{HandshakeTimeout: 15 * time.Second}
conn, _, err := dialer.Dial(url, hdr)
if err != nil {
return "", err
}
id := newID()
a.wsMu.Lock()
if a.wsConns == nil {
a.wsConns = make(map[string]*websocket.Conn)
}
a.wsConns[id] = conn
a.wsMu.Unlock()
go a.wsRead(id, conn)
return id, nil
}
func (a *App) wsRead(id string, conn *websocket.Conn) {
for {
_, msg, err := conn.ReadMessage()
if err != nil {
runtime.EventsEmit(a.ctx, "ws:close:"+id, err.Error())
a.wsMu.Lock()
delete(a.wsConns, id)
a.wsMu.Unlock()
_ = conn.Close()
return
}
runtime.EventsEmit(a.ctx, "ws:message:"+id, string(msg))
}
}
// WSSend writes a text message to the connection with the given id.
func (a *App) WSSend(id, msg string) error {
a.wsMu.Lock()
conn := a.wsConns[id]
a.wsMu.Unlock()
if conn == nil {
return websocket.ErrCloseSent
}
return conn.WriteMessage(websocket.TextMessage, []byte(msg))
}
// WSClose closes the connection with the given id.
func (a *App) WSClose(id string) error {
a.wsMu.Lock()
conn := a.wsConns[id]
delete(a.wsConns, id)
a.wsMu.Unlock()
if conn == nil {
return nil
}
return conn.Close()
}