Skip to content

Commit bd7f275

Browse files
committed
feat: use cupertino http and websocket implementation
1 parent 6a86752 commit bd7f275

File tree

6 files changed

+81
-1
lines changed

6 files changed

+81
-1
lines changed

packages/supabase/lib/src/realtime_client_options.dart

+19
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,29 @@ class RealtimeClientOptions {
1717
/// the timeout to trigger push timeouts
1818
final Duration? timeout;
1919

20+
/// The WebSocket implementation to use
21+
final WebSocketTransport? webSocketTransport;
22+
2023
/// {@macro realtime_client_options}
2124
const RealtimeClientOptions({
2225
this.eventsPerSecond,
2326
this.logLevel,
2427
this.timeout,
28+
this.webSocketTransport,
2529
});
30+
31+
RealtimeClientOptions copyWith({
32+
int? eventsPerSecond,
33+
RealtimeLogLevel? logLevel,
34+
Duration? timeout,
35+
WebSocketTransport? webSocketTransport,
36+
}) {
37+
return RealtimeClientOptions(
38+
// ignore: deprecated_member_use_from_same_package
39+
eventsPerSecond: eventsPerSecond ?? this.eventsPerSecond,
40+
logLevel: logLevel ?? this.logLevel,
41+
timeout: timeout ?? this.timeout,
42+
webSocketTransport: webSocketTransport ?? this.webSocketTransport,
43+
);
44+
}
2645
}

packages/supabase/lib/src/supabase_client.dart

+1
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ class SupabaseClient {
329329
'apikey': _supabaseKey,
330330
},
331331
headers: {'apikey': _supabaseKey, ...headers},
332+
transport: options.webSocketTransport,
332333
logLevel: options.logLevel,
333334
httpClient: _authHttpClient,
334335
timeout: options.timeout ?? RealtimeConstants.defaultTimeout,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import 'dart:io';
2+
3+
import 'package:cupertino_http/cupertino_http.dart';
4+
import 'package:http/http.dart' as http;
5+
import 'package:supabase_flutter/supabase_flutter.dart';
6+
import 'package:web_socket_channel/adapter_web_socket_channel.dart';
7+
import 'package:web_socket_channel/web_socket_channel.dart';
8+
9+
/// For iOS and macOS this returns a `CupertinoClient` and [http.Client] for the
10+
/// rest of the platforms.
11+
///
12+
/// This is used to make HTTP requests use the platform's native HTTP client.
13+
http.Client getPlatformHttpClient() {
14+
if (Platform.isIOS || Platform.isMacOS) {
15+
return CupertinoClient.defaultSessionConfiguration();
16+
} else {
17+
return http.Client();
18+
}
19+
}
20+
21+
/// For iOS and macOS this returns a `CupertinoWebSocket` wrapped in a
22+
/// `AdapterWebSocketChannel` and `null` for the rest of the platforms.
23+
///
24+
/// It may return `null` because the differentiation for the other platforms
25+
/// is done in [RealtimeClient].
26+
WebSocketChannel? getPlatformWebSocketChannel(String url) {
27+
if (Platform.isIOS || Platform.isMacOS) {
28+
return AdapterWebSocketChannel(
29+
CupertinoWebSocket.connect(Uri.parse(url)),
30+
);
31+
}
32+
return null;
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import 'package:http/http.dart' as http;
2+
import 'package:web_socket_channel/web_socket_channel.dart';
3+
4+
http.Client getPlatformHttpClient() {
5+
return http.Client();
6+
}
7+
8+
WebSocketChannel? getPlatformWebSocketChannel(String url) {
9+
return null;
10+
}

packages/supabase_flutter/lib/src/supabase.dart

+16-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import 'package:supabase_flutter/src/flutter_go_true_client_options.dart';
1111
import 'package:supabase_flutter/src/local_storage.dart';
1212
import 'package:supabase_flutter/src/supabase_auth.dart';
1313

14+
import 'platform_http_io.dart'
15+
if (dart.library.js_interop) 'platform_http_web.dart';
1416
import 'version.dart';
1517

1618
final _log = Logger('supabase.supabase_flutter');
@@ -114,6 +116,13 @@ class Supabase with WidgetsBindingObserver {
114116
),
115117
);
116118
}
119+
if (realtimeClientOptions.webSocketTransport == null) {
120+
final platformWebSocketChannel = getPlatformWebSocketChannel(url);
121+
if (platformWebSocketChannel != null) {
122+
realtimeClientOptions = realtimeClientOptions.copyWith(
123+
webSocketTransport: (url, headers) => platformWebSocketChannel);
124+
}
125+
}
117126
_instance._init(
118127
url,
119128
anonKey,
@@ -192,10 +201,16 @@ class Supabase with WidgetsBindingObserver {
192201
...Constants.defaultHeaders,
193202
if (customHeaders != null) ...customHeaders
194203
};
204+
final Client platformHttpClient;
205+
if (httpClient != null) {
206+
platformHttpClient = httpClient;
207+
} else {
208+
platformHttpClient = getPlatformHttpClient();
209+
}
195210
client = SupabaseClient(
196211
supabaseUrl,
197212
supabaseAnonKey,
198-
httpClient: httpClient,
213+
httpClient: platformHttpClient,
199214
headers: headers,
200215
realtimeClientOptions: realtimeClientOptions,
201216
postgrestOptions: postgrestOptions,

packages/supabase_flutter/pubspec.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ dependencies:
2323
shared_preferences: ^2.0.0
2424
logging: ^1.2.0
2525
web: '>=0.5.0 <2.0.0'
26+
cupertino_http: ^2.0.0
27+
web_socket_channel: '>=2.3.0 <4.0.0'
2628

2729
dev_dependencies:
2830
dart_jsonwebtoken: ^2.4.1

0 commit comments

Comments
 (0)