Skip to content

Commit 9475743

Browse files
authored
allow use websocket (rustdesk#11677)
1. Enable the RustDesk client to use WebSocket for either controlling or being controlled. 2. Fix TCP sending `register_pk` frequently Note: 1. Because hbb_common directly uses `use_ws` to read config directly, rustdesk also directly reads config Signed-off-by: 21pages <sunboeasy@gmail.com>
1 parent 86bbdf7 commit 9475743

61 files changed

Lines changed: 413 additions & 64 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 22 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flutter/lib/consts.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,13 @@ const String kOptionDirectxCapture = "enable-directx-capture";
147147
const String kOptionAllowRemoteCmModification = "allow-remote-cm-modification";
148148
const String kOptionEnableTrustedDevices = "enable-trusted-devices";
149149

150+
// network options
151+
const String kOptionAllowWebSocket = "allow-websocket";
152+
150153
// buildin opitons
151154
const String kOptionHideServerSetting = "hide-server-settings";
152155
const String kOptionHideProxySetting = "hide-proxy-settings";
156+
const String kOptionHideWebSocketSetting = "hide-websocket-settings";
153157
const String kOptionHideRemotePrinterSetting = "hide-remote-printer-settings";
154158
const String kOptionHideSecuritySetting = "hide-security-settings";
155159
const String kOptionHideNetworkSetting = "hide-network-settings";

flutter/lib/desktop/pages/desktop_setting_page.dart

Lines changed: 84 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,11 +1475,70 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
14751475
bind.mainGetBuildinOption(key: kOptionHideServerSetting) == 'Y';
14761476
final hideProxy =
14771477
isWeb || bind.mainGetBuildinOption(key: kOptionHideProxySetting) == 'Y';
1478+
// final hideWebSocket = isWeb ||
1479+
// bind.mainGetBuildinOption(key: kOptionHideWebSocketSetting) == 'Y';
1480+
final hideWebSocket = true;
14781481

1479-
if (hideServer && hideProxy) {
1482+
if (hideServer && hideProxy && hideWebSocket) {
14801483
return Offstage();
14811484
}
14821485

1486+
// Helper function to create network setting ListTiles
1487+
Widget listTile({
1488+
required IconData icon,
1489+
required String title,
1490+
VoidCallback? onTap,
1491+
Widget? trailing,
1492+
bool showTooltip = false,
1493+
String tooltipMessage = '',
1494+
}) {
1495+
final titleWidget = showTooltip
1496+
? Row(
1497+
children: [
1498+
Tooltip(
1499+
waitDuration: Duration(milliseconds: 1000),
1500+
message: translate(tooltipMessage),
1501+
child: Row(
1502+
children: [
1503+
Text(
1504+
translate(title),
1505+
style: TextStyle(fontSize: _kContentFontSize),
1506+
),
1507+
SizedBox(width: 5),
1508+
Icon(
1509+
Icons.help_outline,
1510+
size: 14,
1511+
color: Theme.of(context)
1512+
.textTheme
1513+
.titleLarge
1514+
?.color
1515+
?.withOpacity(0.7),
1516+
),
1517+
],
1518+
),
1519+
),
1520+
],
1521+
)
1522+
: Text(
1523+
translate(title),
1524+
style: TextStyle(fontSize: _kContentFontSize),
1525+
);
1526+
1527+
return ListTile(
1528+
leading: Icon(icon, color: _accentColor),
1529+
title: titleWidget,
1530+
enabled: !locked,
1531+
onTap: onTap,
1532+
trailing: trailing,
1533+
shape: RoundedRectangleBorder(
1534+
borderRadius: BorderRadius.circular(10),
1535+
),
1536+
contentPadding: EdgeInsets.symmetric(horizontal: 16),
1537+
minLeadingWidth: 0,
1538+
horizontalTitleGap: 10,
1539+
);
1540+
}
1541+
14831542
return _Card(
14841543
title: 'Network',
14851544
children: [
@@ -1488,39 +1547,36 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
14881547
crossAxisAlignment: CrossAxisAlignment.start,
14891548
children: [
14901549
if (!hideServer)
1491-
ListTile(
1492-
leading: Icon(Icons.dns_outlined, color: _accentColor),
1493-
title: Text(
1494-
translate('ID/Relay Server'),
1495-
style: TextStyle(fontSize: _kContentFontSize),
1496-
),
1497-
enabled: !locked,
1550+
listTile(
1551+
icon: Icons.dns_outlined,
1552+
title: 'ID/Relay Server',
14981553
onTap: () => showServerSettings(gFFI.dialogManager),
1499-
shape: RoundedRectangleBorder(
1500-
borderRadius: BorderRadius.circular(10),
1501-
),
1502-
contentPadding: EdgeInsets.symmetric(horizontal: 16),
1503-
minLeadingWidth: 0,
1504-
horizontalTitleGap: 10,
15051554
),
1506-
if (!hideServer && !hideProxy)
1555+
if (!hideServer && (!hideProxy || !hideWebSocket))
15071556
Divider(height: 1, indent: 16, endIndent: 16),
15081557
if (!hideProxy)
1509-
ListTile(
1510-
leading:
1511-
Icon(Icons.network_ping_outlined, color: _accentColor),
1512-
title: Text(
1513-
translate('Socks5/Http(s) Proxy'),
1514-
style: TextStyle(fontSize: _kContentFontSize),
1515-
),
1516-
enabled: !locked,
1558+
listTile(
1559+
icon: Icons.network_ping_outlined,
1560+
title: 'Socks5/Http(s) Proxy',
15171561
onTap: changeSocks5Proxy,
1518-
shape: RoundedRectangleBorder(
1519-
borderRadius: BorderRadius.circular(10),
1562+
),
1563+
if (!hideProxy && !hideWebSocket)
1564+
Divider(height: 1, indent: 16, endIndent: 16),
1565+
if (!hideWebSocket)
1566+
listTile(
1567+
icon: Icons.web_asset_outlined,
1568+
title: 'Use WebSocket',
1569+
showTooltip: true,
1570+
tooltipMessage: 'websocket_tip',
1571+
trailing: Switch(
1572+
value: mainGetBoolOptionSync(kOptionAllowWebSocket),
1573+
onChanged: locked
1574+
? null
1575+
: (value) {
1576+
mainSetBoolOption(kOptionAllowWebSocket, value);
1577+
setState(() {});
1578+
},
15201579
),
1521-
contentPadding: EdgeInsets.symmetric(horizontal: 16),
1522-
minLeadingWidth: 0,
1523-
horizontalTitleGap: 10,
15241580
),
15251581
],
15261582
),

flutter/lib/mobile/pages/settings_page.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
8080
var _enableDirectIPAccess = false;
8181
var _enableRecordSession = false;
8282
var _enableHardwareCodec = false;
83+
var _allowWebSocket = false;
8384
var _autoRecordIncomingSession = false;
8485
var _autoRecordOutgoingSession = false;
8586
var _allowAutoDisconnect = false;
@@ -91,6 +92,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
9192
var _hideServer = false;
9293
var _hideProxy = false;
9394
var _hideNetwork = false;
95+
var _hideWebSocket = false;
9496
var _enableTrustedDevices = false;
9597

9698
_SettingsState() {
@@ -105,6 +107,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
105107
bind.mainGetOptionSync(key: kOptionEnableRecordSession));
106108
_enableHardwareCodec = option2bool(kOptionEnableHwcodec,
107109
bind.mainGetOptionSync(key: kOptionEnableHwcodec));
110+
_allowWebSocket = mainGetBoolOptionSync(kOptionAllowWebSocket);
108111
_autoRecordIncomingSession = option2bool(kOptionAllowAutoRecordIncoming,
109112
bind.mainGetOptionSync(key: kOptionAllowAutoRecordIncoming));
110113
_autoRecordOutgoingSession = option2bool(kOptionAllowAutoRecordOutgoing,
@@ -120,6 +123,8 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
120123
_hideProxy = bind.mainGetBuildinOption(key: kOptionHideProxySetting) == 'Y';
121124
_hideNetwork =
122125
bind.mainGetBuildinOption(key: kOptionHideNetworkSetting) == 'Y';
126+
_hideWebSocket =
127+
true; //bind.mainGetBuildinOption(key: kOptionHideWebSocketSetting) == 'Y';
123128
_enableTrustedDevices = mainGetBoolOptionSync(kOptionEnableTrustedDevices);
124129
}
125130

@@ -667,6 +672,21 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
667672
onPressed: (context) {
668673
changeSocks5Proxy();
669674
}),
675+
if (!disabledSettings && !_hideNetwork && !_hideWebSocket)
676+
SettingsTile.switchTile(
677+
title: Text(translate('Use WebSocket')),
678+
initialValue: _allowWebSocket,
679+
onToggle: isOptionFixed(kOptionAllowWebSocket)
680+
? null
681+
: (v) async {
682+
await mainSetBoolOption(kOptionAllowWebSocket, v);
683+
final newValue =
684+
await mainGetBoolOption(kOptionAllowWebSocket);
685+
setState(() {
686+
_allowWebSocket = newValue;
687+
});
688+
},
689+
),
670690
SettingsTile(
671691
title: Text(translate('Language')),
672692
leading: Icon(Icons.translate),

flutter/lib/models/web_model.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,15 @@ class PlatformFFI {
4949
}
5050

5151
bool registerEventHandler(
52-
String eventName, String handlerName, HandleEvent handler) {
52+
String eventName, String handlerName, HandleEvent handler,
53+
{bool replace = false}) {
5354
debugPrint('registerEventHandler $eventName $handlerName');
5455
var handlers = _eventHandlers[eventName];
5556
if (handlers == null) {
5657
_eventHandlers[eventName] = {handlerName: handler};
5758
return true;
5859
} else {
59-
if (handlers.containsKey(handlerName)) {
60+
if (!replace && handlers.containsKey(handlerName)) {
6061
return false;
6162
} else {
6263
handlers[handlerName] = handler;

flutter/lib/web/bridge.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,5 +1852,49 @@ class RustdeskImpl {
18521852
throw UnimplementedError("sessionGetConnToken");
18531853
}
18541854

1855+
String mainGetPrinterNames({dynamic hint}) {
1856+
return '';
1857+
}
1858+
1859+
Future<void> sessionPrinterResponse(
1860+
{required UuidValue sessionId,
1861+
required int id,
1862+
required String path,
1863+
required String printerName,
1864+
dynamic hint}) {
1865+
throw UnimplementedError("sessionPrinterResponse");
1866+
}
1867+
1868+
Future<String> mainGetCommon({required String key, dynamic hint}) {
1869+
throw UnimplementedError("mainGetCommon");
1870+
}
1871+
1872+
String mainGetCommonSync({required String key, dynamic hint}) {
1873+
throw UnimplementedError("mainGetCommonSync");
1874+
}
1875+
1876+
Future<void> mainSetCommon(
1877+
{required String key, required String value, dynamic hint}) {
1878+
throw UnimplementedError("mainSetCommon");
1879+
}
1880+
1881+
Future<String> sessionHandleScreenshot(
1882+
{required UuidValue sessionId, required String action, dynamic hint}) {
1883+
throw UnimplementedError("sessionHandleScreenshot");
1884+
}
1885+
1886+
String? sessionGetCommonSync(
1887+
{required UuidValue sessionId,
1888+
required String key,
1889+
required String param,
1890+
dynamic hint}) {
1891+
throw UnimplementedError("sessionGetCommonSync");
1892+
}
1893+
1894+
Future<void> sessionTakeScreenshot(
1895+
{required UuidValue sessionId, required int display, dynamic hint}) {
1896+
throw UnimplementedError("sessionTakeScreenshot");
1897+
}
1898+
18551899
void dispose() {}
18561900
}

src/client.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use hbb_common::{
4646
anyhow::{anyhow, Context},
4747
bail,
4848
config::{
49-
self, Config, LocalConfig, PeerConfig, PeerInfoSerde, Resolution, CONNECT_TIMEOUT,
49+
self, use_ws, Config, LocalConfig, PeerConfig, PeerInfoSerde, Resolution, CONNECT_TIMEOUT,
5050
READ_TIMEOUT, RELAY_PORT, RENDEZVOUS_PORT, RENDEZVOUS_SERVERS,
5151
},
5252
fs::JobType,
@@ -216,7 +216,8 @@ impl Client {
216216
if hbb_common::is_ip_str(peer) {
217217
return Ok((
218218
(
219-
connect_tcp(check_port(peer, RELAY_PORT + 1), CONNECT_TIMEOUT).await?,
219+
connect_tcp_local(check_port(peer, RELAY_PORT + 1), None, CONNECT_TIMEOUT)
220+
.await?,
220221
true,
221222
None,
222223
),
@@ -226,7 +227,11 @@ impl Client {
226227
// Allow connect to {domain}:{port}
227228
if hbb_common::is_domain_port_str(peer) {
228229
return Ok((
229-
(connect_tcp(peer, CONNECT_TIMEOUT).await?, true, None),
230+
(
231+
connect_tcp_local(peer, None, CONNECT_TIMEOUT).await?,
232+
true,
233+
None,
234+
),
230235
(0, "".to_owned()),
231236
));
232237
}
@@ -291,7 +296,7 @@ impl Client {
291296
log::info!("#{} punch attempt with {}, id: {}", i, my_addr, peer);
292297
let mut msg_out = RendezvousMessage::new();
293298
use hbb_common::protobuf::Enum;
294-
let nat_type = if interface.is_force_relay() {
299+
let nat_type = if interface.is_force_relay() || use_ws() || Config::is_proxy() {
295300
NatType::SYMMETRIC
296301
} else {
297302
NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT)

0 commit comments

Comments
 (0)