Vue如何构建实时聊天和即时通讯应用?

2024年06月19日 建站教程

创建Vuex Store

import Vue from 'vue'
import Vuex from 'vuex'
import io from 'socket.io-client'
 
Vue.use(Vuex)
 
export default new Vuex.Store({
  state: {
    user: {
      id: null,
      name: null
    },
    rooms: [],
    activeRoomId: null,
    messages: []
  },
  mutations: {
    setUser(state, user) {
      state.user = user
    },
    setRooms(state, rooms) {
      state.rooms = rooms
    },
    setActiveRoomId(state, roomId) {
      state.activeRoomId = roomId
    },
    addMessage(state, message) {
      state.messages.push(message)
    },
    clearMessages(state) {
      state.messages = []
    }
  },
  actions: {
    connect({ commit, dispatch }) {
      const socket = io('http://localhost:3000')
 
      socket.on('connect', () => {
        console.log('Connected to server!')
      })
 
      socket.on('user', (user) => {
        commit('setUser', user)
      })
 
      socket.on('rooms', (rooms) => {
        commit('setRooms', rooms)
      })
 
      socket.on('activeRoomId', (roomId) => {
        commit('setActiveRoomId', roomId)
      })
 
      socket.on('message', (message) => {
        commit('addMessage', message)
      })
 
      socket.on('clearMessages', () => {
        commit('clearMessages')
      })
 
      socket.on('disconnect', () => {
        console.log('Disconnected from server!')
      })
    },
    sendMessage({ state }, message) {
      const socket = io('http://localhost:3000')
 
      const payload = {
        roomId: state.activeRoomId,
        message
      }
 
      socket.emit('message', payload)
    }
  },
  modules: {
  }
})

创建Vue组件

<template>
  <div class="chat">
    <div class="chat__user">
      <h2>{{ user.name }}</h2>
    </div>
    <div class="chat__rooms">
      <ul>
        <li v-for="room in rooms" :key="room.id" @click="selectRoom(room.id)">
          {{ room.name }}
        </li>
      </ul>
    </div>
    <div class="chat__messages">
      <ul>
        <li v-for="message in messages" :key="message.id">
          {{ message.text }}
        </li>
      </ul>
    </div>
    <div class="chat__input">
      <input type="text" v-model="message">
      <button @click="sendMessage()">Send</button>
    </div>
  </div>
</template>
 
<script>
import { mapState, mapActions } from 'vuex'
 
export default {
  name: 'Chat',
  computed: {
    ...mapState(['user', 'rooms', 'activeRoomId', 'messages']),
  },
  methods: {
    ...mapActions(['connect', 'sendMessage', 'selectRoom']),
  },
  mounted() {
    this.connect()
  }
}
</script>

在服务器端实现Socket.io

const app = require('express')()
const http = require('http').createServer(app)
const io = require('socket.io')(http)
 
const PORT = 3000
 
http.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`)
})
 
let users = []
let rooms = []
 
io.on('connection', (socket) => {
  console.log('Client connected!', socket.id)
 
  socket.on('verifyUser', (user) => {
    console.log('Verifying user', user)
 
    const authenticatedUser = {
      id: socket.id,
      name: 'Mike'
    }
 
    socket.emit('user', authenticatedUser)
  })
 
  socket.on('getRooms', () => {
    socket.emit('rooms', rooms)
  })
 
  socket.on('selectRoom', (roomId) => {
    socket.join(roomId)
    socket.emit('activeRoomId', roomId)
    socket.emit('clearMessages')
 
    const room = rooms.find(room => room.id === roomId)
    socket.emit('messages', room.messages)
  })
 
  socket.on('message', (payload) => {
    const room = rooms.find(room => room.id === payload.roomId)
 
    const message = {
      id: Date.now(),
      text: payload.message
    }
 
    room.messages.push(message)
 
    io.in(payload.roomId).emit('message', message)
  })
 
  socket.on('disconnect', () => {
    console.log('Client disconnected!', socket.id)
  })
})
 
rooms.push({
  id: '1',
  name: 'Room 1',
  messages: []
})
 
rooms.push({
  id: '2',
  name: 'Room 2',
  messages: []
})

本文链接:http://so.lmcjl.com/news/6872/

展开阅读全文
相关内容