I use Bloc and repositories, I'm going to use the socket in different places in the project. each api package has its own events but shares the same socket. I want to connect once and use it in multiple places and packages. Is that possible?
// use socket in multiple files
final socket = SocketApi().init();
In javascript I would export { socket }
package : https://pub.dev/packages/socket_io_client
UPDATE: socket init function can be called and connects multiple times even if the socket is static and checking if it's already connected
import 'dart:async';
import 'package:ngi_api/ngi_api.export.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;
class StreamSocketController<T> {
StreamSocketController() {
print('Init Stream controller ${T.toString()}');
}
final _socketResponse = StreamController<T>();
void Function(T) get addResponse => _socketResponse.sink.add;
Stream<T> get getResponse => _socketResponse.stream;
void dispose() {
_socketResponse.close();
}
}
class SocketApi {
// Factry constructor to retutn same static instance everytime you create any object.
factory SocketApi() {
return _socketApi;
}
// An internal private constructor to access it for only once for static instance of class.
SocketApi._internal();
static void init() {
print('socket init connected: ${socket.connected}');
if (socket.connected == false) {
socket.connect();
socket.on('server:connected', (dynamic data) {
print(
'socket instance created and connected',
);
socket.emit(
'user:connected',
<dynamic, dynamic>{'user': Environment.user},
);
});
socket.on('unauthorized', (dynamic data) {
print('Unauthorized');
});
socket.onError(
(dynamic error) => {print(error), print('socket error')},
);
socket.onDisconnect((dynamic data) {
print('socket instance disconnected');
});
} else {
print('socket instance already connected');
}
}
// A static private instance to access _socketApi from inside class only
static final SocketApi _socketApi = SocketApi._internal();
static IO.Socket socket = IO.io(
TcFleetTunEnvironment.socketURL,
IO.OptionBuilder()
.setTransports(['websocket'])
.disableAutoConnect()
.enableForceNewConnection()
.setTimeout(5000)
.setReconnectionDelay(10000)
.enableReconnection()
.setQuery(
<dynamic, dynamic>{'token': Environment.token},
)
.build(),
);
// All socket related functions.
static Stream<Asset> getAsset() async* {
final streamSocket = StreamSocketController<Asset>();
try {
socket.on('newMsg', (dynamic data) {
try {
streamSocket
.addResponse(Asset.fromJson(data as Map<String, dynamic>));
} catch (e, stackTrace) {
print('Exception newMsg');
print(e);
print(stackTrace);
print(data);
}
});
yield* streamSocket.getResponse.take(20);
} catch (e) {
print('Exception getAsset');
print(e);
} finally {
print('Stream controller asset closed');
socket.off('newMsg');
streamSocket.dispose();
}
}
}
//main
void main() async {
SocketApi.init();
SocketApi.init();
SocketApi.getAsset().listen(
(Asset data) {
print('Asset.1: ${data.name}');
},
cancelOnError: false,
onError: print,
onDone: () {
print('*** asset.1 stream controller Done ***');
},
);
}
this is the result if i call socketApi.init() multiple times, socket already connected never gets printed , instead a new connection is created
This is my dependencies file

