Trong bài đăng trên blog này, chúng tôi sẽ tạo một ứng dụng trò chuyện thời gian thực đơn giản cho phép người dùng tham gia nhóm trò chuyện và giao tiếp trong thời gian thực.
Chúng tôi sẽ tận dụng sức mạnh của Ably để nhắn tin theo thời gian thực cho người dùng với độ trễ thấp, Upstash Redis để lưu trữ tin nhắn liên tục và Node.js để xây dựng ứng dụng.
Có thể
Ably là nền tảng trải nghiệm thời gian thực cho phép giao tiếp hai chiều giữa người dùng.
Đối với ứng dụng trò chuyện này, chúng tôi sẽ sử dụng các kênh Pub/Sub của Ably để cho phép người dùng gửi tin nhắn bằng cách "xuất bản" tin nhắn lên kênh Ably và cho phép người dùng nhận tin nhắn gửi đến kênh bằng cách "đăng ký".
Ably cung cấp các kênh Pub/Sub này bằng cách thêm một lớp trừu tượng lên trên Ổ cắm web với các tính năng bổ sung. Một số trong số đó như sau:
-
Sự hiện diện của người đăng ký
-
Xác thực
-
Cơ chế nhịp tim
-
Hàng đợi
-
Khả năng gửi tin nhắn theo thứ tự chúng được xuất bản
-
Tích hợp để gọi các chức năng theo bất kỳ sự kiện nào trên Ably
-
Truyền trực tuyến tin nhắn/sự hiện diện/siêu dữ liệu tới Kafka
Bạn có thể truy cập trang web của họ để tìm hiểu thêm!
Để tận dụng trung tâm trải nghiệm thời gian thực mạnh mẽ này, chúng ta cần tạo một ứng dụng trên Ably.
Trước tiên hãy tạo một tài khoản Ably.
Sau đó, chúng ta có thể tạo một ứng dụng bằng cách chọn “Trò chuyện trực tiếp”.

Thế thôi!
Chúng tôi không cần phải làm bất cứ điều gì khác ở đây ngay bây giờ. Chúng tôi sẽ quay lại trang tổng quan Ably sau để lấy khóa API.
Upstash Redis
Chúng tôi sẽ sử dụng Upstash Redis để lưu trữ liên tục các tin nhắn trò chuyện.
Bộ nhớ này sẽ cho phép người dùng truy xuất lịch sử trò chuyện khi họ tham gia.
Upstash Redis cũng sẽ cho phép chúng tôi lưu trữ các tin nhắn trò chuyện dưới dạng danh sách được sắp xếp. Điều này sẽ giúp chúng tôi gửi tin nhắn từ cơ sở dữ liệu đến máy khách mà không cần sắp xếp lại chúng.
Để tạo cơ sở dữ liệu Upstash Redis, hãy truy cập Upstash Console, đăng nhập và tạo cơ sở dữ liệu Redis.

Cơ sở hạ tầng đã sẵn sàng. Bây giờ, hãy chuyển sang kiến trúc của ứng dụng.
Cấu trúc ứng dụng trò chuyện
Thiết kế của ứng dụng trò chuyện này khá đơn giản.

Trong dự án demo này, chúng tôi sẽ chỉ tạo một kênh Ably để đơn giản hóa. Khách hàng sẽ xuất bản các tin nhắn mà họ gửi đến kênh đó. Sau khi khách hàng đăng thông báo, các khách hàng khác sẽ ngay lập tức nhận được thông báo thông qua đăng ký kênh của họ.
Ngoài việc nhắn tin theo thời gian thực giữa các máy khách, chúng ta cần lưu trữ các tin nhắn trong Upstash Redis. Để có thể làm được điều đó kênh Ably sẽ có thêm một người đăng ký nữa đó là máy chủ của chúng tôi. Máy chủ này sẽ nhận tin nhắn do khách hàng gửi, gửi chúng đến Upstash Redis và lưu trữ chúng ở đó.
Cuối cùng, chúng tôi sẽ sử dụng lịch sử trò chuyện được lưu trữ trong Upstash Redis với sự trợ giúp của máy chủ. Chúng tôi sẽ tạo điểm cuối "/history" ở phía máy chủ để trả về lịch sử trò chuyện từ Redis. Khách hàng sẽ có thể truy xuất lịch sử trò chuyện khi họ tải ứng dụng bằng cách gọi điểm cuối này.
Như bạn có thể thấy, đây là một ứng dụng trò chuyện đơn giản nhằm mục đích trình diễn. Ứng dụng trò chuyện này có thể được sửa đổi và mở rộng bằng cách sử dụng các tính năng khác của Ably đã đề cập trước đó trong bài đăng trên blog này.
Hãy bắt đầu...
Phía khách hàng
Đầu tiên, chúng ta cần tạo giao diện người dùng trò chuyện cơ bản cho người dùng. Chúng ta sẽ tạo một index.html đơn giản trang web để thực hiện việc này.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="index.css">
<title>Chat App</title>
</head>
<body>
<div class="container">
<p class="msg">Messages:</p>
<div id="messages" class="messages"></div>
<form id="msgForm" class="msgForm">
<input type="text" placeholder="Send message" class="input" id="inputBox" />
<input type="submit" class="btn" value="Send">
</form>
</div>
<script src="https://cdn.ably.io/lib/ably.min-1.js"></script>
<script src="app.js"></script>
</body>
</html> Trong trình duyệt của người dùng, chúng ta sẽ thấy trường nhập để nhập tin nhắn, nút gửi để gửi tin nhắn và hộp tin nhắn hiển thị các tin nhắn trước đó.
Bây giờ, chúng ta sẽ viết “app.js”, đây là tệp JavaScript sẽ được thực thi như một phần của trang web.
Trước tiên chúng ta sẽ tạo kênh Ably. Để làm điều đó, chúng ta cần quay lại trang tổng quan Ably và tạo khóa API mới trong “Khóa API”.
Hãy chọn “Xuất bản” và “Đăng ký” làm khả năng của API này.

Bây giờ chúng ta có thể tạo ứng dụng khách Ably trong tệp JavaScript bằng cách sử dụng Khóa được cung cấp trong trang tổng quan Ably.
const ably = new Ably.Realtime(‘<Ably API Key>’); Cảnh báo
Việc cung cấp khóa API cho khách hàng là KHÔNG AN TOÀN. Ably cung cấp một cơ chế có tên là “TokenRequest”. Vì đây là ứng dụng demo nên chúng tôi sẽ cung cấp khóa API trực tiếp cho tệp JavaScript. Để biết thêm thông tin về xác thực ứng dụng khách cho Ably, vui lòng kiểm tra tài liệu về mã thông báo của Ably.
Bây giờ, hãy lấy kênh Ably mà khách hàng sẽ liên lạc qua đó.
const channel = ably.channels.get('chat'); Chúng tôi không cần tạo kênh. Kênh được tạo sau khi ai đó xuất bản nội dung nào đó lên kênh đó.
Là bước trước khi triển khai chức năng nhắn tin, chúng tôi cần lấy tên người dùng từ người dùng. Chúng tôi sẽ làm cho nó thật đơn giản vì xác thực không phải là trọng tâm của blog này.
let name = window.prompt("Please enter your name.", "Anonymous"); Bây giờ chúng ta có thể thực hiện gửi tin nhắn.
const form = document.getElementById('msgForm');
form.addEventListener('submit', (event) => {
event.preventDefault();
const message = document.getElementById('inputBox').value;
if (message.trim() !== '') {
const messageData = {
name: name,
message: message
}
channel.publish('message', messageData);
document.getElementById('inputBox').value = '';
}
}); Gửi tin nhắn rất đơn giản! Chúng ta cần tạo một đối tượng chứa tên người dùng và tin nhắn rồi xuất bản nó lên kênh Ably.
Để cho phép người dùng nhận tin nhắn, chúng tôi cần tạo đăng ký kênh đó và thêm hộp tin nhắn chứa tên người dùng và tin nhắn.
channel.subscribe('message', (message) => {
console.log("Client received: ", message);
displayMessage(message.data);
});
function displayMessage(message) {
const incomingName = message.name;
const incomingMessage = message.message;
const messageElement = document.createElement('div');
const messageValue = document.createElement('div');
const messageWriter = document.createElement('div');
if(incomingName !== name){
messageElement.classList.add('msgSent');
}
else {
messageElement.classList.add('msgReceived');
}
messageWriter.classList.add('msgWriter');
messageValue.classList.add('msgValue');
messageWriter.textContent = incomingName;
messageValue.textContent = incomingMessage;
messageElement.appendChild(messageWriter);
messageElement.appendChild(messageValue);
const list = document.getElementById('messages');
list.appendChild(messageElement);
} Cuối cùng, chúng tôi sẽ truy xuất lịch sử trò chuyện khi trang được tải lần đầu tiên.
document.addEventListener("DOMContentLoaded", function() {
fetchChatHistory();
});
function fetchChatHistory() {
fetch('/history')
.then((response) => {
if (!response.ok) {
throw new Error('Failed to fetch chat history');
} return response.json();
})
.then((data) => {
const history = data.history;
console.log(history);
if (history && history.length > 0) {
history.forEach((message) => {
displayMessage(JSON.parse(message));
});
}
})
.catch((error) => {
console.error('Error fetching chat history:', error);
});
} Phía máy chủ
Máy chủ trong ứng dụng demo này sẽ đăng ký kênh Ably, đẩy kênh này vào cơ sở dữ liệu Upstash Redis và trả về lịch sử trò chuyện từ Upstash Redis khi khách hàng yêu cầu.
Trước tiên, chúng tôi sẽ định cấu hình máy chủ trong tệp “app.js”.
var express = require('express'); var path = require('path');
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'ChatApp' });
});
app.use('/', router);
module.exports = app; Tiếp theo, chúng tôi sẽ tạo máy chủ của mình trong “server.js”, đăng ký kênh Ably và kết nối với Upstash Redis.
var app = require('../app');
var http = require('http');
const redis = require('redis');
const Ably = require('ably');
const port = process.env.PORT || '3000';
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
const redisClient = redis.createClient({ url : "<Upstash Redis Endpoint>" });
redisClient.on("error", function(err) {
throw err;
});
redisClient.connect().then(r => {
console.log("Connected to Redis.")
})
// Ably configuration
const ably = new Ably.Realtime({
key: '<Ably API Key>',
});
// Define a channel
const channel = ably.channels.get('chat'); Bước tiếp theo là đẩy các tin nhắn đến vào cơ sở dữ liệu Upstash Redis. Chúng tôi sẽ thực hiện thao tác này với đăng ký kênh Ably.
// Handle incoming messages
channel.subscribe('message', async (message) => {
const convertedMessage = JSON.stringify(message.data);
console.log('Received message:', convertedMessage);
// Store the message in Upstash Redis
await redisClient.LPUSH("AblyChatList",convertedMessage);
}); Cuối cùng, chúng tôi sẽ triển khai điểm cuối “/history”, điểm truy xuất lịch sử trò chuyện từ Upstash Redis và trả lại cho khách hàng.
// Get chat history endpoint
app.get('/history', async (req, res) => {
// Retrieve chat history from Upstash Redis
const messages = await redisClient.LRANGE("AblyChatList", 0, -1);
messages.reverse();
console.log("history api: ", messages);
res.json({ history: messages });
}); Chạy ứng dụng
Chuyển đến thư mục của tệp “server.js” và chạy:
node server.js
Mở localhost:3000 trong trình duyệt của bạn. Đầu tiên nó sẽ yêu cầu tên người dùng.

Khi bạn nhập tên người dùng của mình, nó sẽ cho phép bạn mở cuộc trò chuyện.
Nếu bạn gửi tin nhắn từ một tab và mở localhost:3000 trong một ứng dụng khác sử dụng tên người dùng khác, bạn có thể xem tin nhắn được gửi từ tab trước.

Nhờ Upstash Redis, bạn sẽ truy xuất được lịch sử trò chuyện mỗi khi mở ứng dụng trò chuyện.
Kết luận
Ably cung cấp nhiều tính năng khác nhau để tăng cường giao tiếp thời gian thực giữa các ứng dụng. Thế giới thời gian thực mạnh mẽ của nó có thể được tận dụng cho rất nhiều trường hợp sử dụng khác nhau.
Trong bài đăng trên blog này, chúng tôi đã sử dụng Ably để xây dựng một ứng dụng trò chuyện thời gian thực bằng các kênh Pub/Sub của nó. Trong khi thực hiện việc này, chúng tôi đã lưu trữ các tin nhắn trong cơ sở dữ liệu Upstash Redis. Hai công cụ này giúp ứng dụng này được xây dựng dễ dàng và nhanh chóng.
Vì dự án này chỉ nhằm mục đích trình diễn cách sử dụng Upstash Redis và Ably nên chúng tôi giữ phạm vi của nó rất đơn giản. Nếu quan tâm, bạn có thể xây dựng các ứng dụng thời gian thực mạnh mẽ, có thể mở rộng và bảo mật bằng cách sử dụng các tính năng của Ably và Upstash Redis.