前言
這篇文章介紹如何使用 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')))
複製程式碼