WEB实例:开发一个聊天室应用

前言

这篇文章介绍如何使用 Vue.js 以及 chatkit 快速的开发一个聊天室应用,chatkit 提供了一系列 api 用以更方便的开发聊天功能,源码地址.css

建立Chatkit实例

首先须要创建一个 Chatkit 实例, 前往 chatkit控制台 创建,建好以后新建一个房间以及用户,将以后要用到的 instanceLocator, key 记录到本地html

创建后端服务

新建一个 Node.js 服务用来建立用户以及提供 jwt token,安装依赖 yarn add express cors pusher-chatkit-server 启动服务。前端

const cors = require('cors')
const express = require('express')
const Chatkit = require('pusher-chatkit-server')
const config = require('../config')

const app = express()
const PORT = config.SERVER_PORT || 4399

app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: false }))

// eslint-disable-next-line
const chatkit = new Chatkit.default({
  instanceLocator: config.CHATKIT_INSTANCELOCATOR,
  key: config.CHATKIT_KEY
})

app.post('/user', (req, res) => {
  const { username } = req.body

  const user = {
    id: username,
    name: username
  }

  chatkit
    .createUser(user)
    .then(() => res.status(201).json({ success: true, message: '建立用户成功', user }))
    .catch(error => {
      res.status(error.status).json({ success: false, message: error.error_description })
    })
})

app.post('/auth', (req, res) => {
  const data = chatkit.authenticate({ userId: req.query.user_id })
  res.status(data.status).json(data.body)
})

app.listen(PORT, error => {
  if (error) {
    console.log(error)
  } else {
    console.log(`Server running on port ${PORT}`)
  }
})

复制代码

新建前端项目

新建一个 Vue.js 项目,创建一个用来建立新用户的表单, 表单提交到刚才建立的 express 服务的 user 路由vue

<form class="create__form" @submit.prevent="createUser">
  <input class="create__input" v-model="newUserName" placeholder="输入你的名字" autofocus required /> </form>
复制代码
async createUser() {
  const username = this.newUserName

  const result = await fetch(`${config.SERVER_HOST}:${config.SERVER_PORT}/user`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ username })
  })
  .then(res => res.json())
  .catch(error => error)

  if (result.success) {
    const user = result.user
    this.initChatApp(user.name) // 建立用户成功
  } else {
    console.log(result)
  }
}
复制代码

新建用户成功后,初始化应用react

async initChatApp(userId) {
  const chatManager = new Chatkit.ChatManager({
    userId,                                           // 用户名称
    instanceLocator: config.CHATKIT_INSTANCELOCATOR,  // instanceLocator
    tokenProvider: new Chatkit.TokenProvider({       
      url: `${config.SERVER_HOST}:${config.SERVER_PORT}/auth`
    })
  })

  const currentUser = await chatManager.connect()

  const currentRoom = await currentUser
    .joinRoom({
      roomId: config.CHATKIT_ROOM_ID
    })
    .catch(error => {
      return error
    })
    
  currentUser.subscribeToRoom({
    messageLimit: 20,
    roomId: config.CHATKIT_ROOM_ID, // 在控制台创建的房间ID
    hooks: {
      onNewMessage: message => {
        this.users = this.users.map(user => {
              if (user.name === message.senderId) {
                user.online = true
              }
              return user
            })
            this.messages.push(message)
          }
        }
    })

  const messages = await currentUser
    .fetchMessages({
      roomId: config.CHATKIT_ROOM_ID,
      direction: 'older',
      limit: 20
    })
    .catch(error => {
        console.error(error)
    })

  this.currentUser = currentUser
  this.currentRoom = currentRoom
  this.users = currentRoom.userIds.filter(name => name !== currentUser.name).map(name => {
    return { name, online: false }
  })
  this.messages = messages
}
复制代码

页面布局

进行布局以及UI,使用 Grid 进行快速布局, 创建用户列表,消息列表以及发送消息的表单git

<ul class="chat__users">
  <li class="user-item" v-for="user of users" :key="user.id">
   <span class="name">{{ user.name }}</span>
   <span class="spot" :class="{ 'spot--online': user.online }"></span>
  </li>
</ul>
复制代码
<ul class="chat__messages">
  <message-item v-for="(message, index) of messages" :key="index" :message="message" :currentUser="currentUser" />
</ul>
复制代码
<form class="chat__send" @submit.prevent="sendMessage">
  <input class="input" type="text" @change="typingMessage" v-model="newMessage" autofocus required placeholder="说点什么..." />
  <button class="button" type="submit">发送</button>
</form>
复制代码
.chat {
  display: grid;
  grid-auto-columns: 240px auto;
  grid-auto-rows: 30px auto 70px;
  grid-template-areas:
    'users messages'
    'users messages'
    'users send';
  height: 100vh;
}  
复制代码

发送消息

使用 chatkit 提供的api便可github

sendMessage() {
  this.currentUser // 当前用户
    .sendMessage({
      text: this.newMessage, // 消息内容
      roomId: config.CHATKIT_ROOM_ID // 房间ID
    })
    .then(messageId => {
      this.newMessage = ''
    })
    .catch(error => {
      this.newMessage = ''
       console.log(error)
    })
}
复制代码

最后

开发完成后,使用 yarn build 命令将 Vue 项目打包,而后使用 express 内置的 static 中间件挂载打包后的 dist 目录, 在浏览器中打开 express 运行的端口就能够看到效果了,文章只是简述如何开发,具体实现请看 github 源码。express

app.use('/', express.static(path.join(__dirname, '/dist')))
复制代码

参考

vue-chatjson

CHATKIT DOCS后端

Build a Slack Clone with React and Pusher Chatkit

相关文章
相关标签/搜索