socket fixed

This commit is contained in:
Username1548
2025-01-19 15:10:56 +07:00
parent ab7004f9fd
commit 7eaf0bc1bb
29 changed files with 489 additions and 1006 deletions

View File

@@ -1,105 +0,0 @@
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/initialization_cubit/initialization_state.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_cubit.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_cubit.dart';
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class InitializationCubit extends Cubit<InitializationState> {
final ChatRepository chatRepository;
bool wasInitialized = false;
InitializationCubit({required this.chatRepository}) : super(const InitializationState.loading());
Future<void> subscribeNotifications(int userId, PusherChannelsClient client) async {
final privateNotificationChannel = await client.privateChannel(
'private-message-events.$userId',
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
headers: {
'Authorization': 'Bearer ${await TokenStorage.getTokenFromStorage()}',
},
),
);
privateNotificationChannel.subscribe();
privateNotificationChannel.bindToAll().listen((event) {
sl<NotificationsCubit>().incrementCounter(event.name);
});
}
Future<void> subscribeChatMessages(int userId, PusherChannelsClient client) async {
final privateMessagesChannel = await client.privateChannel(
'private-new-chat-messages.$userId',
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
headers: {
'Authorization': 'Bearer ${await TokenStorage.getTokenFromStorage()}',
},
),
);
privateMessagesChannel.subscribe();
privateMessagesChannel.bindToAll().listen((event) {
sl<NewMessagesCubit>().incrementCounter();
});
}
Future<void> runInitialization() async {
if (!wasInitialized) {
wasInitialized = true;
try {
await TokenStorage.haveTokenInStorage();
final wsUrl = await chatRepository.getWebsocket();
final options = PusherChannelsOptions.fromHost(
scheme: 'wss',
key: wsUrl.key,
host: wsUrl.host,
shouldSupplyMetadataQueries: true,
metadata: PusherChannelsOptionsMetadata.byDefault(),
port: 443,
);
final client = PusherChannelsClient.websocket(
options: options,
connectionErrorHandler: (exception, trace, refresh) {
refresh();
},
minimumReconnectDelayDuration: const Duration(
seconds: 1,
),
defaultActivityDuration: const Duration(
seconds: 120,
),
activityDurationOverride: const Duration(
seconds: 120,
),
waitForPongDuration: const Duration(
seconds: 30,
),
);
await client.connect();
await subscribeNotifications(wsUrl.userId, client);
await subscribeChatMessages(wsUrl.userId, client);
emit(
InitializationState.success(
client: client,
),
);
} catch (e) {
emit(
InitializationState.error(
errorMessage: e.toString(),
),
);
rethrow;
}
}
}
}

View File

@@ -1,19 +0,0 @@
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'initialization_state.freezed.dart';
@freezed
abstract class InitializationState with _$InitializationState {
const factory InitializationState() = _InitializationState;
const factory InitializationState.loading() = InitializationStateLoading;
const factory InitializationState.success({
required PusherChannelsClient client,
}) = InitializationStateSuccess;
const factory InitializationState.error({
required String errorMessage,
}) = InitializationStateError;
}

View File

@@ -1,645 +0,0 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'initialization_state.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
/// @nodoc
mixin _$InitializationState {
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PusherChannelsClient client) success,
required TResult Function(String errorMessage) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PusherChannelsClient client)? success,
TResult? Function(String errorMessage)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PusherChannelsClient client)? success,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_InitializationState value) $default, {
required TResult Function(InitializationStateLoading value) loading,
required TResult Function(InitializationStateSuccess value) success,
required TResult Function(InitializationStateError value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_InitializationState value)? $default, {
TResult? Function(InitializationStateLoading value)? loading,
TResult? Function(InitializationStateSuccess value)? success,
TResult? Function(InitializationStateError value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_InitializationState value)? $default, {
TResult Function(InitializationStateLoading value)? loading,
TResult Function(InitializationStateSuccess value)? success,
TResult Function(InitializationStateError value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $InitializationStateCopyWith<$Res> {
factory $InitializationStateCopyWith(
InitializationState value, $Res Function(InitializationState) then) =
_$InitializationStateCopyWithImpl<$Res, InitializationState>;
}
/// @nodoc
class _$InitializationStateCopyWithImpl<$Res, $Val extends InitializationState>
implements $InitializationStateCopyWith<$Res> {
_$InitializationStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$InitializationStateImplCopyWith<$Res> {
factory _$$InitializationStateImplCopyWith(_$InitializationStateImpl value,
$Res Function(_$InitializationStateImpl) then) =
__$$InitializationStateImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitializationStateImplCopyWithImpl<$Res>
extends _$InitializationStateCopyWithImpl<$Res, _$InitializationStateImpl>
implements _$$InitializationStateImplCopyWith<$Res> {
__$$InitializationStateImplCopyWithImpl(_$InitializationStateImpl _value,
$Res Function(_$InitializationStateImpl) _then)
: super(_value, _then);
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitializationStateImpl implements _InitializationState {
const _$InitializationStateImpl();
@override
String toString() {
return 'InitializationState()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$InitializationStateImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PusherChannelsClient client) success,
required TResult Function(String errorMessage) error,
}) {
return $default();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PusherChannelsClient client)? success,
TResult? Function(String errorMessage)? error,
}) {
return $default?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PusherChannelsClient client)? success,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if ($default != null) {
return $default();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_InitializationState value) $default, {
required TResult Function(InitializationStateLoading value) loading,
required TResult Function(InitializationStateSuccess value) success,
required TResult Function(InitializationStateError value) error,
}) {
return $default(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_InitializationState value)? $default, {
TResult? Function(InitializationStateLoading value)? loading,
TResult? Function(InitializationStateSuccess value)? success,
TResult? Function(InitializationStateError value)? error,
}) {
return $default?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_InitializationState value)? $default, {
TResult Function(InitializationStateLoading value)? loading,
TResult Function(InitializationStateSuccess value)? success,
TResult Function(InitializationStateError value)? error,
required TResult orElse(),
}) {
if ($default != null) {
return $default(this);
}
return orElse();
}
}
abstract class _InitializationState implements InitializationState {
const factory _InitializationState() = _$InitializationStateImpl;
}
/// @nodoc
abstract class _$$InitializationStateLoadingImplCopyWith<$Res> {
factory _$$InitializationStateLoadingImplCopyWith(
_$InitializationStateLoadingImpl value,
$Res Function(_$InitializationStateLoadingImpl) then) =
__$$InitializationStateLoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitializationStateLoadingImplCopyWithImpl<$Res>
extends _$InitializationStateCopyWithImpl<$Res,
_$InitializationStateLoadingImpl>
implements _$$InitializationStateLoadingImplCopyWith<$Res> {
__$$InitializationStateLoadingImplCopyWithImpl(
_$InitializationStateLoadingImpl _value,
$Res Function(_$InitializationStateLoadingImpl) _then)
: super(_value, _then);
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitializationStateLoadingImpl implements InitializationStateLoading {
const _$InitializationStateLoadingImpl();
@override
String toString() {
return 'InitializationState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$InitializationStateLoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PusherChannelsClient client) success,
required TResult Function(String errorMessage) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PusherChannelsClient client)? success,
TResult? Function(String errorMessage)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PusherChannelsClient client)? success,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_InitializationState value) $default, {
required TResult Function(InitializationStateLoading value) loading,
required TResult Function(InitializationStateSuccess value) success,
required TResult Function(InitializationStateError value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_InitializationState value)? $default, {
TResult? Function(InitializationStateLoading value)? loading,
TResult? Function(InitializationStateSuccess value)? success,
TResult? Function(InitializationStateError value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_InitializationState value)? $default, {
TResult Function(InitializationStateLoading value)? loading,
TResult Function(InitializationStateSuccess value)? success,
TResult Function(InitializationStateError value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class InitializationStateLoading implements InitializationState {
const factory InitializationStateLoading() = _$InitializationStateLoadingImpl;
}
/// @nodoc
abstract class _$$InitializationStateSuccessImplCopyWith<$Res> {
factory _$$InitializationStateSuccessImplCopyWith(
_$InitializationStateSuccessImpl value,
$Res Function(_$InitializationStateSuccessImpl) then) =
__$$InitializationStateSuccessImplCopyWithImpl<$Res>;
@useResult
$Res call({PusherChannelsClient client});
}
/// @nodoc
class __$$InitializationStateSuccessImplCopyWithImpl<$Res>
extends _$InitializationStateCopyWithImpl<$Res,
_$InitializationStateSuccessImpl>
implements _$$InitializationStateSuccessImplCopyWith<$Res> {
__$$InitializationStateSuccessImplCopyWithImpl(
_$InitializationStateSuccessImpl _value,
$Res Function(_$InitializationStateSuccessImpl) _then)
: super(_value, _then);
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? client = null,
}) {
return _then(_$InitializationStateSuccessImpl(
client: null == client
? _value.client
: client // ignore: cast_nullable_to_non_nullable
as PusherChannelsClient,
));
}
}
/// @nodoc
class _$InitializationStateSuccessImpl implements InitializationStateSuccess {
const _$InitializationStateSuccessImpl({required this.client});
@override
final PusherChannelsClient client;
@override
String toString() {
return 'InitializationState.success(client: $client)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$InitializationStateSuccessImpl &&
(identical(other.client, client) || other.client == client));
}
@override
int get hashCode => Object.hash(runtimeType, client);
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$InitializationStateSuccessImplCopyWith<_$InitializationStateSuccessImpl>
get copyWith => __$$InitializationStateSuccessImplCopyWithImpl<
_$InitializationStateSuccessImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PusherChannelsClient client) success,
required TResult Function(String errorMessage) error,
}) {
return success(client);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PusherChannelsClient client)? success,
TResult? Function(String errorMessage)? error,
}) {
return success?.call(client);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PusherChannelsClient client)? success,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (success != null) {
return success(client);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_InitializationState value) $default, {
required TResult Function(InitializationStateLoading value) loading,
required TResult Function(InitializationStateSuccess value) success,
required TResult Function(InitializationStateError value) error,
}) {
return success(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_InitializationState value)? $default, {
TResult? Function(InitializationStateLoading value)? loading,
TResult? Function(InitializationStateSuccess value)? success,
TResult? Function(InitializationStateError value)? error,
}) {
return success?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_InitializationState value)? $default, {
TResult Function(InitializationStateLoading value)? loading,
TResult Function(InitializationStateSuccess value)? success,
TResult Function(InitializationStateError value)? error,
required TResult orElse(),
}) {
if (success != null) {
return success(this);
}
return orElse();
}
}
abstract class InitializationStateSuccess implements InitializationState {
const factory InitializationStateSuccess(
{required final PusherChannelsClient client}) =
_$InitializationStateSuccessImpl;
PusherChannelsClient get client;
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$InitializationStateSuccessImplCopyWith<_$InitializationStateSuccessImpl>
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$InitializationStateErrorImplCopyWith<$Res> {
factory _$$InitializationStateErrorImplCopyWith(
_$InitializationStateErrorImpl value,
$Res Function(_$InitializationStateErrorImpl) then) =
__$$InitializationStateErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String errorMessage});
}
/// @nodoc
class __$$InitializationStateErrorImplCopyWithImpl<$Res>
extends _$InitializationStateCopyWithImpl<$Res,
_$InitializationStateErrorImpl>
implements _$$InitializationStateErrorImplCopyWith<$Res> {
__$$InitializationStateErrorImplCopyWithImpl(
_$InitializationStateErrorImpl _value,
$Res Function(_$InitializationStateErrorImpl) _then)
: super(_value, _then);
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? errorMessage = null,
}) {
return _then(_$InitializationStateErrorImpl(
errorMessage: null == errorMessage
? _value.errorMessage
: errorMessage // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$InitializationStateErrorImpl implements InitializationStateError {
const _$InitializationStateErrorImpl({required this.errorMessage});
@override
final String errorMessage;
@override
String toString() {
return 'InitializationState.error(errorMessage: $errorMessage)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$InitializationStateErrorImpl &&
(identical(other.errorMessage, errorMessage) ||
other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType, errorMessage);
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$InitializationStateErrorImplCopyWith<_$InitializationStateErrorImpl>
get copyWith => __$$InitializationStateErrorImplCopyWithImpl<
_$InitializationStateErrorImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PusherChannelsClient client) success,
required TResult Function(String errorMessage) error,
}) {
return error(errorMessage);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PusherChannelsClient client)? success,
TResult? Function(String errorMessage)? error,
}) {
return error?.call(errorMessage);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PusherChannelsClient client)? success,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(errorMessage);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_InitializationState value) $default, {
required TResult Function(InitializationStateLoading value) loading,
required TResult Function(InitializationStateSuccess value) success,
required TResult Function(InitializationStateError value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_InitializationState value)? $default, {
TResult? Function(InitializationStateLoading value)? loading,
TResult? Function(InitializationStateSuccess value)? success,
TResult? Function(InitializationStateError value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_InitializationState value)? $default, {
TResult Function(InitializationStateLoading value)? loading,
TResult Function(InitializationStateSuccess value)? success,
TResult Function(InitializationStateError value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class InitializationStateError implements InitializationState {
const factory InitializationStateError({required final String errorMessage}) =
_$InitializationStateErrorImpl;
String get errorMessage;
/// Create a copy of InitializationState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$InitializationStateErrorImplCopyWith<_$InitializationStateErrorImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,139 @@
import 'dart:developer';
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/initialization_cubit/ws_service.dart';
import 'package:eatvio_app/core/token_storage.dart';
class WsManager {
final WsService wsService;
WsManager({required this.wsService});
PusherChannelsClient? client;
int? userId;
PrivateChannel? _privateNotificationChannel;
PrivateChannel? _privateMessagesChannel;
PrivateChannel? _privateDirectChatChannel;
Stream<ChannelReadEvent>? get newMessagesStream => _privateMessagesChannel?.bind('App\\Events\\ChatMessageUpdated');
// TODO: change name of event to a right one
Stream<ChannelReadEvent>? get newNotificationsStream => _privateNotificationChannel?.bind('App\\Events\\ChatMessageUpdated');
Stream<ChannelReadEvent>? get directChatStream => _privateDirectChatChannel?.bind('App\\Events\\ChatMessageUpdated');
Stream<ChannelReadEvent>? get clientTypingStream => _privateDirectChatChannel?.bind('client-typing');
Future<void> initialize() async {
if (this.client == null) {
try {
await TokenStorage.haveTokenInStorage();
final wsUrl = await wsService.getWebsocket();
final options = PusherChannelsOptions.fromHost(
scheme: 'wss',
key: wsUrl.key,
host: wsUrl.host,
shouldSupplyMetadataQueries: true,
metadata: PusherChannelsOptionsMetadata.byDefault(),
port: 443,
);
client = PusherChannelsClient.websocket(
options: options,
connectionErrorHandler: (exception, trace, refresh) {
refresh();
},
minimumReconnectDelayDuration: const Duration(
seconds: 1,
),
defaultActivityDuration: const Duration(
seconds: 30,
),
waitForPongDuration: const Duration(
seconds: 30,
),
);
await client?.connect();
this.client = client;
userId = wsUrl.userId;
await _initPrivateNotificationsChannel();
await _initPrivateMessagesChannel();
client?.lifecycleStream.listen((data) {
if (data == PusherChannelsClientLifeCycleState.establishedConnection) {
_unsubscribe();
_subscribe();
}
});
client?.eventStream.listen((event) {
log(event.rootObject.toString());
});
_subscribe();
} catch (e, st) {
log(e.toString(), stackTrace: st);
}
}
}
Future<void> _initPrivateNotificationsChannel() async {
final token = await TokenStorage.getTokenFromStorage();
_privateNotificationChannel = await client?.privateChannel(
'$newNotificationsChannelName.$userId',
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
headers: {
'Authorization': 'Bearer $token',
},
),
);
}
Future<void> _initPrivateMessagesChannel() async {
final token = await TokenStorage.getTokenFromStorage();
_privateMessagesChannel = await client?.privateChannel(
'$newMessagesChannelName.$userId',
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
headers: {
'Authorization': 'Bearer $token',
},
),
);
}
Future<void> initPrivateDirectChatChannel(String chatId) async {
final token = await TokenStorage.getTokenFromStorage();
_privateDirectChatChannel = await client?.privateChannel(
'$directChatChannelName.$chatId',
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
headers: {
'Authorization': 'Bearer $token',
},
),
);
}
void _subscribe() {
_privateMessagesChannel?.subscribe();
_privateNotificationChannel?.subscribe();
}
void _unsubscribe() {
_privateMessagesChannel?.unsubscribe();
_privateNotificationChannel?.unsubscribe();
}
void subscribeDirectChatChannel() {
_privateDirectChatChannel?.subscribe();
}
void unsubscribeDirectChatChannel() {
_privateDirectChatChannel?.unsubscribe();
}
}

View File

@@ -0,0 +1,15 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/chat/models/websocket_info_model.dart';
import 'package:retrofit/retrofit.dart';
part 'ws_service.g.dart';
@RestApi()
abstract class WsService {
factory WsService(Dio dio, {String baseUrl}) = _WsService;
@GET('/api/profile/ws/params')
Future<WebsocketInfoModel> getWebsocket();
}

View File

@@ -0,0 +1,86 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'ws_service.dart';
// **************************************************************************
// RetrofitGenerator
// **************************************************************************
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
class _WsService implements WsService {
_WsService(
this._dio, {
this.baseUrl,
this.errorLogger,
});
final Dio _dio;
String? baseUrl;
final ParseErrorLogger? errorLogger;
@override
Future<WebsocketInfoModel> getWebsocket() async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<WebsocketInfoModel>(Options(
method: 'GET',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/profile/ws/params',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
)));
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late WebsocketInfoModel _value;
try {
_value = WebsocketInfoModel.fromJson(_result.data!);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
return _value;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||
requestOptions.responseType == ResponseType.stream)) {
if (T == String) {
requestOptions.responseType = ResponseType.plain;
} else {
requestOptions.responseType = ResponseType.json;
}
}
return requestOptions;
}
String _combineBaseUrls(
String dioBaseUrl,
String? baseUrl,
) {
if (baseUrl == null || baseUrl.trim().isEmpty) {
return dioBaseUrl;
}
final url = Uri.parse(baseUrl);
if (url.isAbsolute) {
return url.toString();
}
return Uri.parse(dioBaseUrl).resolveUri(url).toString();
}
}