Как мгновенно отобразить полученные сообщения в виджете Flutter ChatBox с помощью Socket.IOAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как мгновенно отобразить полученные сообщения в виджете Flutter ChatBox с помощью Socket.IO

Сообщение Anonymous »

Я создаю приложение для чата, используя Flutter и Socket.IO. У меня есть виджет ChatBox, где пользователи могут отправлять и получать сообщения. Однако я столкнулся с проблемой, когда полученные сообщения не отображаются сразу. Кроме того, сообщения отображаются неправильно.
Вот моя текущая реализация:

< div class="snippet-code">

Код: Выделить всё

class ChatBox extends StatefulWidget {
const ChatBox({super.key, required this.liveID, required this.username});

final int liveID;
final String username;

@override
State createState() => _ChatBoxState();
}

class _ChatBoxState extends State {
final TextEditingController _messageController = TextEditingController();
bool _showEmojiPicker = false;
late IO.Socket socket;
int? currentUserID;
String? currentUsername;
List _messages = [];
final StreamController _streamController = StreamController();
Stream get messagesStream => _streamController.stream;

void _onEmojiSelected(Emoji emoji) {
_messageController
..text += emoji.emoji
..selection = TextSelection.fromPosition(
TextPosition(offset: _messageController.text.length),
);
}

void _onBackspacePressed() {
_messageController
..text = _messageController.text.characters.skipLast(1).toString()
..selection = TextSelection.fromPosition(
TextPosition(offset: _messageController.text.length),
);
}

@override
void initState() {
super.initState();
_loadCurrentUserID();
_initializeSocket();
}

@override
void dispose() {
_messageController.dispose();
_streamController.close();
socket.disconnect();
super.dispose();
}

Future _loadCurrentUserID() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
currentUserID = prefs.getInt('loginUserId');
currentUsername = prefs.getString('username'); // Assuming you have stored the username
});
}

void _initializeSocket() {
socket = IO.io('https://socket.example.com', {
'transports': ['websocket'],
'autoConnect': false,
});

socket.connect();

socket.onConnect((_) {
debugPrint('connected to websocket');
});

socket.onDisconnect((_) {
debugPrint('disconnected from websocket');
});

socket.on('chat_list_message', (data) {
debugPrint('Received message: $data');
_streamController.add(data);
// setState(() {
//   if (data is Map && data['message'] is List && data['message'].isNotEmpty) {
//     for (var messageObj in data['message']) {
//       if (messageObj is Map &&  messageObj.containsKey('message')) {
//         String messageContent = messageObj['message'];
//         _messages.add(ChatMessage(
//           userID: messageObj['userID'],
//           liveID: messageObj['liveID'],
//           message: messageContent,
//           username: messageObj['username'],
//         ));
//         debugPrint('Received Message: $messageContent');
//       } else {
//         debugPrint('Unexpected message object: $messageObj');
//       }
//     }
//   }
// });
});

socket.onError((error) {
debugPrint('Socket error: $error');
});
}

void _sendMessage() {
String message = _messageController.text.trim();
if (message.isNotEmpty) {
final newMessage = {
'userID': currentUserID,
'liveID': widget.liveID,
'message': message,
'username': currentUsername ?? 'Unknown',
'time': DateTime.now().toIso8601String(),
};
setState(() {
_messages.add(ChatMessage.fromJson(newMessage));
});
socket.emit('add_chat_message', newMessage);
_messageController.clear();
}
}

@override
Widget build(BuildContext context) {
return BlocListener(
listener: (context, state) {
if (state is ChatDataLiveSuccess) {
setState(() {
_messages = state.allChatDataLives ?? [];
});
} else if (state is ChatDataLiveFail) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.message)),
);
}
},
child: SizedBox(
height: 150,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: Divider(
color: Theme.of(context).primaryColor,
height: 1,
thickness: 1.5,
),
),
const SizedBox(width: 8.0),
Text(
'New Message',
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodySmall,
maxLines: 1,
),
const SizedBox(width: 8.0),
Expanded(
child: Divider(
color: Theme.of(context).primaryColor,
height: 1,
thickness: 1.5,
),
),
],
),
),
Expanded(
child: ListView.builder(
itemCount: _messages.length,
itemBuilder: (context, index) {
final message = _messages[index];
return Row(
children: [
const SizedBox(width: 20),
Text(
'${widget.username} : ',
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium,
maxLines: 1,
),
const SizedBox(width: 10),
Text(
message.message ?? '',
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodySmall,
maxLines: 1,
),
],
);
},
),
),
Container(
margin: const EdgeInsets.only(left: 12.0, top: 12),
child: Row(
children: [
Expanded(
child: TextField(
controller: _messageController,
decoration: const InputDecoration(
hintText: 'Type your message...',
border: OutlineInputBorder(),
),
),
),
const SizedBox(width: 8.0),
IconButton(
icon:  const Icon(Icons.emoji_emotions),
onPressed: () {
setState(() {
_showEmojiPicker = !_showEmojiPicker;
});
},
),
IconButton(
icon: const Icon(Icons.send),
onPressed: () {
_sendMessage();
},
),
],
),
),
Offstage(
offstage: !_showEmojiPicker,
child: SizedBox(
height: 250,
child: EmojiPicker(
onEmojiSelected: (category, emoji) {
_onEmojiSelected(emoji);
},
onBackspacePressed: _onBackspacePressed,
config: const Config(
height: 200,
checkPlatformCompatibility: true,
emojiViewConfig: EmojiViewConfig(
emojiSizeMax: 32,
),
swapCategoryAndBottomBar: false,
),
),
),
),
],
),
),
);
}
}


Внесенные изменения:
Правильно Анализ данных: при получении событияchat_list_message я проанализировал каждое сообщение в списке и добавил его в _messages.
Немедленное обновление пользовательского интерфейса: использовал setState, чтобы гарантировать немедленное обновление пользовательского интерфейса при получении новых сообщений. .
Правильное отображение: отрегулировано отображение сообщений, чтобы они правильно отображались в дереве виджетов.
Если у вас возникнут какие-либо дополнительные проблемы или вам понадобится подробнее, спрашивайте!

Подробнее здесь: https://stackoverflow.com/questions/786 ... -with-sock
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»