-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient_events_mobile.go
More file actions
153 lines (142 loc) · 5.72 KB
/
Copy pathclient_events_mobile.go
File metadata and controls
153 lines (142 loc) · 5.72 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//go:build android || ios || (darwin && !standalone)
package ipc
import (
"context"
"encoding/json"
"github.com/getlantern/radiance/account"
"github.com/getlantern/radiance/config"
"github.com/getlantern/radiance/events"
"github.com/getlantern/radiance/peer"
"github.com/getlantern/radiance/unbounded"
"github.com/getlantern/radiance/vpn"
)
// AutoSelectedEvents streams auto-selection changes. Blocks until ctx is cancelled.
func (c *Client) AutoSelectedEvents(ctx context.Context, handler func(vpn.AutoSelectedEvent)) error {
// The bus subscription is not redundant with SSE: when the tunnel process is down,
// the client's fallback LocalBackend emits these events on the in-process bus.
events.SubscribeContext(ctx, handler)
if c.localOnly {
<-ctx.Done()
return ctx.Err()
}
return c.sseRetryLoop(ctx, serverAutoSelectedEventsEndpoint, func(data []byte) {
var evt vpn.AutoSelectedEvent
if err := json.Unmarshal(data, &evt); err == nil {
handler(evt)
}
})
}
// URLTestEvents streams URL-test completion notifications. An event is sent
// only when a test run produced usable latency results, for either the offline
// pre-warm run or the live auto-select probe. Blocks until ctx is cancelled.
func (c *Client) URLTestEvents(ctx context.Context, handler func(vpn.URLTestCompleteEvent)) error {
// The bus subscription is not redundant with SSE: when the tunnel process is down,
// the client's fallback LocalBackend emits these events on the in-process bus.
events.SubscribeContext(ctx, handler)
if c.localOnly {
<-ctx.Done()
return ctx.Err()
}
return c.sseRetryLoop(ctx, serverURLTestEventsEndpoint, func(data []byte) {
var evt vpn.URLTestCompleteEvent
if err := json.Unmarshal(data, &evt); err == nil {
handler(evt)
}
})
}
// ConfigEvents streams config-updated notifications. Payloads are empty — callers should treat each
// call as a "refresh" signal. Blocks until ctx is cancelled.
func (c *Client) ConfigEvents(ctx context.Context, handler func()) error {
// The bus subscription is not redundant with SSE: when the tunnel process is down,
// the client's fallback LocalBackend emits NewConfigEvents on the in-process bus.
events.SubscribeContext(ctx, func(config.NewConfigEvent) { handler() })
if c.localOnly {
<-ctx.Done()
return ctx.Err()
}
return c.sseRetryLoop(ctx, configEventsEndpoint, func([]byte) { handler() })
}
// VPNStatusEvents streams VPN status changes. Blocks until ctx is cancelled.
func (c *Client) VPNStatusEvents(ctx context.Context, handler func(vpn.StatusUpdateEvent)) error {
if c.localOnly {
<-ctx.Done()
return ctx.Err()
}
return c.sseRetryLoop(ctx, vpnStatusEventsEndpoint, func(data []byte) {
var evt vpn.StatusUpdateEvent
if err := json.Unmarshal(data, &evt); err == nil {
handler(evt)
}
})
}
// DataCapStream streams data-cap updates while the VPN is connected. Blocks until ctx is cancelled.
func (c *Client) DataCapStream(ctx context.Context, handler func(account.DataCapInfo)) error {
if c.localOnly {
<-ctx.Done()
return ctx.Err()
}
return c.dataCapStream(ctx, handler)
}
// PeerStatusEvents streams peer-share lifecycle phase changes (mapping_port
// → registering → verifying → serving on Start, stopping → idle on Stop,
// error on failure). Each frame is a peer.StatusEvent JSON whose .Status
// is the live snapshot at the moment the event fired — consumers SHOULD
// re-render on every frame rather than diffing, since events.Emit's
// per-callback goroutine can land Start phases out of order. Mobile builds
// may share a process with radiance (localOnly), in which case
// events.SubscribeContext delivers directly; otherwise the SSE retry loop
// is used. Blocks until ctx is cancelled.
func (c *Client) PeerStatusEvents(ctx context.Context, handler func(peer.StatusEvent)) error {
events.SubscribeContext(ctx, handler)
if c.localOnly {
<-ctx.Done()
return ctx.Err()
}
return c.sseRetryLoop(ctx, peerStatusEventsEndpoint, func(data []byte) {
var evt peer.StatusEvent
if err := json.Unmarshal(data, &evt); err == nil {
handler(evt)
}
})
}
// PeerConnectionEvents streams accept/close events for the local
// samizdat-in inbound. State is +1 on accept and -1 on close; Source is
// the remote "ip:port" string for geo-lookup / abuse attribution.
// Same mobile dual-path as PeerStatusEvents (localOnly delivers via
// the in-process event bus; otherwise the SSE retry loop is used).
// Blocks until ctx is cancelled.
func (c *Client) PeerConnectionEvents(ctx context.Context, handler func(peer.ConnectionEvent)) error {
events.SubscribeContext(ctx, handler)
if c.localOnly {
<-ctx.Done()
return ctx.Err()
}
return c.sseRetryLoop(ctx, peerConnectionEventsEndpoint, func(data []byte) {
var evt peer.ConnectionEvent
if err := json.Unmarshal(data, &evt); err == nil {
handler(evt)
}
})
}
// UnboundedConnectionEvents streams accept/close events for the local
// broflake widget proxy ("Unbounded" / Basic mode). The JSON shape
// matches peer.ConnectionEvent but the Go type is distinct — in-process
// subscribers must subscribe to both event types separately to see all
// peer activity. State is +1 on consumer accept, -1 on close; Source
// is the consumer's IP if broflake exposes it, otherwise empty. Same
// mobile dual-path: localOnly subscribes directly to the in-process
// event bus; otherwise the SSE retry loop is used. Blocks until ctx
// is cancelled.
func (c *Client) UnboundedConnectionEvents(ctx context.Context, handler func(unbounded.ConnectionEvent)) error {
events.SubscribeContext(ctx, handler)
if c.localOnly {
<-ctx.Done()
return ctx.Err()
}
return c.sseRetryLoop(ctx, unboundedConnectionEventsEndpoint, func(data []byte) {
var evt unbounded.ConnectionEvent
if err := json.Unmarshal(data, &evt); err == nil {
handler(evt)
}
})
}