socket_io를 사용하여 특정 이벤트 발생시 서버에서 연결하고 있는 클라이언트들에게 데이터를 전달하도록 했다.
https://pub.dev/packages/socket_io_client/install
_socket = _io.io(
'ex) http://localhost:3000',
<String, dynamic>{
'transports': ['websocket'],
'forceNew': true,
});
상세내용은 주석 참고
class LiveChatList extends StatefulWidget {
final _io.Socket socket;
const LiveChatList({
Key? key,
required this.socket,
}) : super(key: key);
@override
_LiveChatListState createState() => _LiveChatListState();
}
class _LiveChatListState extends State<LiveChatList> {
//새로운 채팅 올때마다 추가하기위한 StreamController
final StreamController<LiveChatObject> _streamController =
StreamController<LiveChatObject>();
//메세지 리스트 (노출할 채팅목록이 있는 리스트)
final List<LiveChatObject> _messageList = [];
//채팅리스트 scrollController
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
//이전 채팅 목록 가져오기
WidgetsBinding.instance!.addPostFrameCallback((_) {
widget.socket.emit('chats');
widget.socket.on('CHATS', (data) {
Iterable list = data['CA'];
//Json정보를 받아올 채팅 구조(LiveChatObject)의 리스트형태로 변환
var beforeChats =
list.map((i) => LiveChatObject.fromJson(i)).toList();
setState(() {
//받아온 이전 채팅목록을 messageList에 추가
beforeChats.forEach((chatData) {
_messageList.add(chatData);
});
});
});
});
//새로운 채팅 올때마다 messageList에 추가
widget.socket.on('MSSG', (data) {
_streamController.sink.add(LiveChatObject.fromJson(data));
setState(() {
_messageList.add(LiveChatObject.fromJson(data));
});
});
}
@override
void dispose() {
super.dispose();
_scrollController.dispose();
_streamController.close();
}
@override
Widget build(BuildContext context) {
// build마다 채팅 스크롤 맨 밑으로
if (_messageList.isNotEmpty ) {
SchedulerBinding.instance!.addPostFrameCallback((_) {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 50),
curve: Curves.easeOut,
);
});
}
return
Container(
margin: EdgeInsets.fromLTRB(0, 0, 0, 7),
height: 170,
padding: EdgeInsets.fromLTRB(0, 5, 5, 5),
child: ListView.builder(
shrinkWrap: true,
padding: EdgeInsets.zero,
controller: _scrollController,
itemCount: _messageList.length,
itemBuilder: (BuildContext context, int index) {
return _messageList[index].PMO != null
ShoppyLiveChatText(
nickname: _messageList[index].NI,
message: _messageList[index].MG,
empFlag: false,
isPMO: false);
},
),
),
)
);
}
}