[VueJS] 채팅 어플리케이션 시리즈1

shw·2021년 4월 28일
0
post-custom-banner

1. import 'vue-socket.io' 라이브러리

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)
}));

2. 소켓연결 및 rooms 가져오기

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 업데이트 후 화면은 아래와 같습니다.

3.room에 해당하는 messages가져오기

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 가져온후 화면은 이와 같습니다.

post-custom-banner

0개의 댓글