new change to use intaleq_map sdk 04-16-4
This commit is contained in:
101
packages/get/lib/get_connect/sockets/src/socket_notifier.dart
Normal file
101
packages/get/lib/get_connect/sockets/src/socket_notifier.dart
Normal file
@@ -0,0 +1,101 @@
|
||||
import 'dart:convert';
|
||||
|
||||
/// Signature for [SocketNotifier.addCloses].
|
||||
typedef CloseSocket = void Function(Close);
|
||||
|
||||
/// Signature for [SocketNotifier.addMessages].
|
||||
typedef MessageSocket = void Function(dynamic val);
|
||||
|
||||
/// Signature for [SocketNotifier.open].
|
||||
typedef OpenSocket = void Function();
|
||||
|
||||
/// Wrapper class to message and reason from SocketNotifier
|
||||
class Close {
|
||||
final String? message;
|
||||
final int? reason;
|
||||
|
||||
Close(this.message, this.reason);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Closed by server [$reason => $message]!';
|
||||
}
|
||||
}
|
||||
|
||||
/// This class manages the transmission of messages over websockets using
|
||||
/// GetConnect
|
||||
class SocketNotifier {
|
||||
List<void Function(dynamic)>? _onMessages = <MessageSocket>[];
|
||||
Map<String, void Function(dynamic)>? _onEvents = <String, MessageSocket>{};
|
||||
List<void Function(Close)>? _onCloses = <CloseSocket>[];
|
||||
List<void Function(Close)>? _onErrors = <CloseSocket>[];
|
||||
|
||||
late OpenSocket open;
|
||||
|
||||
/// subscribe to close events
|
||||
void addCloses(CloseSocket socket) {
|
||||
_onCloses!.add(socket);
|
||||
}
|
||||
|
||||
/// subscribe to error events
|
||||
void addErrors(CloseSocket socket) {
|
||||
_onErrors!.add((socket));
|
||||
}
|
||||
|
||||
/// subscribe to named events
|
||||
void addEvents(String event, MessageSocket socket) {
|
||||
_onEvents![event] = socket;
|
||||
}
|
||||
|
||||
/// subscribe to message events
|
||||
void addMessages(MessageSocket socket) {
|
||||
_onMessages!.add((socket));
|
||||
}
|
||||
|
||||
/// Dispose messages, events, closes and errors subscriptions
|
||||
void dispose() {
|
||||
_onMessages = null;
|
||||
_onEvents = null;
|
||||
_onCloses = null;
|
||||
_onErrors = null;
|
||||
}
|
||||
|
||||
/// Notify all subscriptions on [addCloses]
|
||||
void notifyClose(Close err) {
|
||||
for (var item in _onCloses!) {
|
||||
item(err);
|
||||
}
|
||||
}
|
||||
|
||||
/// Notify all subscriptions on [addMessages]
|
||||
void notifyData(dynamic data) {
|
||||
for (var item in _onMessages!) {
|
||||
item(data);
|
||||
}
|
||||
if (data is String) {
|
||||
_tryOn(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// Notify all subscriptions on [addErrors]
|
||||
void notifyError(Close err) {
|
||||
// rooms.removeWhere((key, value) => value.contains(_ws));
|
||||
for (var item in _onErrors!) {
|
||||
item(err);
|
||||
}
|
||||
}
|
||||
|
||||
void _tryOn(String message) {
|
||||
try {
|
||||
var msg = jsonDecode(message);
|
||||
final event = msg['type'];
|
||||
final data = msg['data'];
|
||||
if (_onEvents!.containsKey(event)) {
|
||||
_onEvents![event]!(data);
|
||||
}
|
||||
// ignore: avoid_catches_without_on_clauses
|
||||
} catch (_) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
116
packages/get/lib/get_connect/sockets/src/sockets_html.dart
Normal file
116
packages/get/lib/get_connect/sockets/src/sockets_html.dart
Normal file
@@ -0,0 +1,116 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
// ignore: avoid_web_libraries_in_flutter
|
||||
import 'dart:html';
|
||||
|
||||
import '../../../get_core/get_core.dart';
|
||||
import 'socket_notifier.dart';
|
||||
|
||||
class BaseWebSocket {
|
||||
String url;
|
||||
WebSocket? socket;
|
||||
SocketNotifier? socketNotifier = SocketNotifier();
|
||||
Duration ping;
|
||||
bool isDisposed = false;
|
||||
bool allowSelfSigned;
|
||||
|
||||
ConnectionStatus? connectionStatus;
|
||||
Timer? _t;
|
||||
BaseWebSocket(
|
||||
this.url, {
|
||||
this.ping = const Duration(seconds: 5),
|
||||
this.allowSelfSigned = true,
|
||||
}) {
|
||||
url = url.startsWith('https')
|
||||
? url.replaceAll('https:', 'wss:')
|
||||
: url.replaceAll('http:', 'ws:');
|
||||
}
|
||||
|
||||
void close([int? status, String? reason]) {
|
||||
socket?.close(status, reason);
|
||||
}
|
||||
|
||||
// ignore: use_setters_to_change_properties
|
||||
void connect() {
|
||||
try {
|
||||
connectionStatus = ConnectionStatus.connecting;
|
||||
socket = WebSocket(url);
|
||||
socket!.onOpen.listen((e) {
|
||||
socketNotifier?.open();
|
||||
_t = Timer?.periodic(ping, (t) {
|
||||
socket!.send('');
|
||||
});
|
||||
connectionStatus = ConnectionStatus.connected;
|
||||
});
|
||||
|
||||
socket!.onMessage.listen((event) {
|
||||
socketNotifier!.notifyData(event.data);
|
||||
});
|
||||
|
||||
socket!.onClose.listen((e) {
|
||||
_t?.cancel();
|
||||
|
||||
connectionStatus = ConnectionStatus.closed;
|
||||
socketNotifier!.notifyClose(Close(e.reason, e.code));
|
||||
});
|
||||
socket!.onError.listen((event) {
|
||||
_t?.cancel();
|
||||
socketNotifier!.notifyError(Close(event.toString(), 0));
|
||||
connectionStatus = ConnectionStatus.closed;
|
||||
});
|
||||
} on Exception catch (e) {
|
||||
_t?.cancel();
|
||||
socketNotifier!.notifyError(Close(e.toString(), 500));
|
||||
connectionStatus = ConnectionStatus.closed;
|
||||
// close(500, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
socketNotifier!.dispose();
|
||||
socketNotifier = null;
|
||||
isDisposed = true;
|
||||
}
|
||||
|
||||
void emit(String event, dynamic data) {
|
||||
send(jsonEncode({'type': event, 'data': data}));
|
||||
}
|
||||
|
||||
void on(String event, MessageSocket message) {
|
||||
socketNotifier!.addEvents(event, message);
|
||||
}
|
||||
|
||||
void onClose(CloseSocket fn) {
|
||||
socketNotifier!.addCloses(fn);
|
||||
}
|
||||
|
||||
void onError(CloseSocket fn) {
|
||||
socketNotifier!.addErrors(fn);
|
||||
}
|
||||
|
||||
void onMessage(MessageSocket fn) {
|
||||
socketNotifier!.addMessages(fn);
|
||||
}
|
||||
|
||||
// ignore: use_setters_to_change_properties
|
||||
void onOpen(OpenSocket fn) {
|
||||
socketNotifier!.open = fn;
|
||||
}
|
||||
|
||||
void send(dynamic data) {
|
||||
if (connectionStatus == ConnectionStatus.closed) {
|
||||
connect();
|
||||
}
|
||||
if (socket != null && socket!.readyState == WebSocket.OPEN) {
|
||||
socket!.send(data);
|
||||
} else {
|
||||
Get.log('WebSocket not connected, message $data not sent');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ConnectionStatus {
|
||||
connecting,
|
||||
connected,
|
||||
closed,
|
||||
}
|
||||
138
packages/get/lib/get_connect/sockets/src/sockets_io.dart
Normal file
138
packages/get/lib/get_connect/sockets/src/sockets_io.dart
Normal file
@@ -0,0 +1,138 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import '../../../get_core/get_core.dart';
|
||||
import 'socket_notifier.dart';
|
||||
|
||||
class BaseWebSocket {
|
||||
String url;
|
||||
WebSocket? socket;
|
||||
SocketNotifier? socketNotifier = SocketNotifier();
|
||||
bool isDisposed = false;
|
||||
Duration ping;
|
||||
bool allowSelfSigned;
|
||||
ConnectionStatus? connectionStatus;
|
||||
|
||||
BaseWebSocket(
|
||||
this.url, {
|
||||
this.ping = const Duration(seconds: 5),
|
||||
this.allowSelfSigned = true,
|
||||
});
|
||||
|
||||
void close([int? status, String? reason]) {
|
||||
socket?.close(status, reason);
|
||||
}
|
||||
|
||||
// ignore: use_setters_to_change_properties
|
||||
Future connect() async {
|
||||
if (isDisposed) {
|
||||
socketNotifier = SocketNotifier();
|
||||
}
|
||||
try {
|
||||
connectionStatus = ConnectionStatus.connecting;
|
||||
socket = allowSelfSigned
|
||||
? await _connectForSelfSignedCert(url)
|
||||
: await WebSocket.connect(url);
|
||||
|
||||
socket!.pingInterval = ping;
|
||||
socketNotifier?.open();
|
||||
connectionStatus = ConnectionStatus.connected;
|
||||
|
||||
socket!.listen((data) {
|
||||
socketNotifier!.notifyData(data);
|
||||
}, onError: (err) {
|
||||
socketNotifier!.notifyError(Close(err.toString(), 1005));
|
||||
}, onDone: () {
|
||||
connectionStatus = ConnectionStatus.closed;
|
||||
socketNotifier!
|
||||
.notifyClose(Close('Connection Closed', socket!.closeCode));
|
||||
}, cancelOnError: true);
|
||||
return;
|
||||
} on SocketException catch (e) {
|
||||
connectionStatus = ConnectionStatus.closed;
|
||||
socketNotifier!
|
||||
.notifyError(Close(e.osError!.message, e.osError!.errorCode));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
socketNotifier!.dispose();
|
||||
socketNotifier = null;
|
||||
isDisposed = true;
|
||||
}
|
||||
|
||||
void emit(String event, dynamic data) {
|
||||
send(jsonEncode({'type': event, 'data': data}));
|
||||
}
|
||||
|
||||
void on(String event, MessageSocket message) {
|
||||
socketNotifier!.addEvents(event, message);
|
||||
}
|
||||
|
||||
void onClose(CloseSocket fn) {
|
||||
socketNotifier!.addCloses(fn);
|
||||
}
|
||||
|
||||
void onError(CloseSocket fn) {
|
||||
socketNotifier!.addErrors(fn);
|
||||
}
|
||||
|
||||
void onMessage(MessageSocket fn) {
|
||||
socketNotifier!.addMessages(fn);
|
||||
}
|
||||
|
||||
// ignore: use_setters_to_change_properties
|
||||
void onOpen(OpenSocket fn) {
|
||||
socketNotifier!.open = fn;
|
||||
}
|
||||
|
||||
void send(dynamic data) async {
|
||||
if (connectionStatus == ConnectionStatus.closed) {
|
||||
await connect();
|
||||
}
|
||||
|
||||
if (socket != null) {
|
||||
socket!.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
Future<WebSocket> _connectForSelfSignedCert(String url) async {
|
||||
try {
|
||||
var r = Random();
|
||||
var key = base64.encode(List<int>.generate(8, (_) => r.nextInt(255)));
|
||||
var client = HttpClient(context: SecurityContext());
|
||||
client.badCertificateCallback = (cert, host, port) {
|
||||
Get.log(
|
||||
'BaseWebSocket: Allow self-signed certificate => $host:$port. ');
|
||||
return true;
|
||||
};
|
||||
|
||||
var request = await client.getUrl(Uri.parse(url));
|
||||
request.headers.add('Connection', 'Upgrade');
|
||||
request.headers.add('Upgrade', 'websocket');
|
||||
request.headers.add('Sec-WebSocket-Version', '13');
|
||||
request.headers.add('Sec-WebSocket-Key', key.toLowerCase());
|
||||
|
||||
var response = await request.close();
|
||||
// ignore: close_sinks
|
||||
var socket = await response.detachSocket();
|
||||
var webSocket = WebSocket.fromUpgradedSocket(
|
||||
socket,
|
||||
serverSide: false,
|
||||
);
|
||||
|
||||
return webSocket;
|
||||
} on Exception catch (_) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ConnectionStatus {
|
||||
connecting,
|
||||
connected,
|
||||
closed,
|
||||
}
|
||||
54
packages/get/lib/get_connect/sockets/src/sockets_stub.dart
Normal file
54
packages/get/lib/get_connect/sockets/src/sockets_stub.dart
Normal file
@@ -0,0 +1,54 @@
|
||||
import './socket_notifier.dart';
|
||||
|
||||
class BaseWebSocket {
|
||||
String url;
|
||||
Duration ping;
|
||||
bool allowSelfSigned;
|
||||
BaseWebSocket(
|
||||
this.url, {
|
||||
this.ping = const Duration(seconds: 5),
|
||||
this.allowSelfSigned = true,
|
||||
}) {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
Future connect() async {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void onOpen(OpenSocket fn) {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void onClose(CloseSocket fn) {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void onError(CloseSocket fn) {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void onMessage(MessageSocket fn) {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void on(String event, MessageSocket message) {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void close([int? status, String? reason]) {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void send(dynamic data) async {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
|
||||
void emit(String event, dynamic data) {
|
||||
throw 'To use sockets you need dart:io or dart:html';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user