前言
这篇文章介绍如何使用 Vue.js 以及 chatkit 快速的开发一个聊天室应用,chatkit 提供了一系列 api 用以更方便的开发聊天功能,源码地址.
创建Chatkit实例
首先需要建立一个 Chatkit 实例, 前往 chatkit控制台 建立,建好之后新建一个房间以及用户,将之后要用到的 instanceLocator
, key
记录到本地
建立后端服务
新建一个 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 路由
<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)
}
}
复制代码
新建用户成功后,初始化应用
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
进行快速布局, 建立用户列表,消息列表以及发送消息的表单
<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即可
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 源码。
app.use('/', express.static(path.join(__dirname, '/dist')))
复制代码