VueJS 용 SocketIO라이브러리는 vue-socket.io 사용했습니다.
reconnectionDelay는 reconnection시 delay설정입니다.
아래 코드는 500ms 입니다.
rememberUpgrade는 websocket으로 업그레이드가 되고난 후 reconnection시 websocket으로 바로 커넥트하는 옵션입니다.
import VueSocketIO from 'vue-socket.io'
const options = {
reconnectionDelay: 500,
reconnection: true,
rememberUpgrade: false,
autoConnect: false,
withCredentials: true,
// transports: ["websocket", "polling"],
transportOptions: {
polling: {
extraHeaders: {
"authorization": token
}
}
}
};
Vue.use(new VueSocketIO({
debug: true,
connection: SocketIO(`http://localhost:300/chat`, options)
}));
this.$socket.connect();
export default {
name: 'Chat',
data() {
return {
isConnected: false,
form: {
roomName: null,
},
isLoading: true,
message: null,
rooms: [],
activeRoom: null,
messages: [],
invitableUsers: [],
fileReader: null,
tempFile: null,
tempFileName: null,
allLoaded: false,
splicedSize: 1000 * 100, //100kb
};
},
sockets: {
connect() {
console.log('socket connected');
this.isConnected = true;
this.isLoading = false;
//소켓연결 후 채팅방리스트 가져오기
this.$socket.emit('listenRooms', null, (data) => {
var rooms = data.data || [];
if (rooms.length > 0) {
//첫번째 채팅방에 조인
this.joinRoom(rooms[0]);
this.rooms = rooms;
}
});
},
}
}
소켓이 연결되고 첫번째 방에 조인하고 rooms 업데이트 후 화면은 아래와 같습니다.
messages를 가져오는 부분은 joinRoom을 성공후 하면 될것습니다.
joinRoom(room) {
this.$socket.emit('joinRoom', room._id, (data) => {
console.log('joinRoom', data);
if (data) {
//방에 입장시 unReadMsgCount 초기화
room.unReadMsgCount = 0;
//messages 가져오기
this.getMessagesByRoom(room._id);
}
});
},
getMessagesByRoom(roomId, lastMessageId) {
console.log('getMessagesByRoom', lastMessageId);
//message list를 가져올때는 채팅방에 있는 마지막 메세지를 기준으로 더 오래된 메세지를 가져옵니다.
const payload = { roomId, lastMessageId };
this.$socket.emit('listenMessagesByRoom', payload, (data) => {
var messages = data.data;
console.log(messages);
//기본적으로 서버에서는 메세지 카운트를 10으로 설정해 두었습니다. 10개 미만일때 allLoaded = true로 해주어도 상관없습니다.
if (messages.length < 1) {
this.allLoaded = true;
}
if (lastMessageId) {
//keep scroll position
const previousScrollHeight = this.$refs.msg_history.scrollHeight;
this.messages = [...messages, ...this.messages];
this.$nextTick(() => {
const currentScrollHeight = this.$refs.msg_history.scrollHeight;
this.$refs.msg_history.scrollTo(
0,
currentScrollHeight - previousScrollHeight,
);
});
} else {
this.messages = messages;
if (messages.length > 0) {
//마지막으로 읽은 lastReadMessage 업데이트
this.updateReadMessage(messages[messages.length - 1]);
}
this.scrollToBottom();
}
});
},
messages 가져온후 화면은 이와 같습니다.