Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

สร้างแอปแชทแบบเรียลไทม์ด้วย Ably, Upstash Redis และ Node.js

ในบล็อกโพสต์นี้ เราจะสร้างแอปพลิเคชันแชทแบบเรียลไทม์ที่เรียบง่ายที่อนุญาตให้ผู้ใช้เข้าร่วมกลุ่มแชทและสื่อสารแบบเรียลไทม์

เราจะใช้ประโยชน์จากประสิทธิภาพของ Ably สำหรับการส่งข้อความแบบเรียลไทม์กับผู้ใช้ที่มีเวลาแฝงต่ำ Upstash Redis สำหรับการจัดเก็บข้อความอย่างถาวร และ Node.js สำหรับการสร้างแอปพลิเคชัน

ความสามารถ

Ably เป็นแพลตฟอร์มประสบการณ์แบบเรียลไทม์ที่ช่วยให้สามารถสื่อสารสองทางระหว่างผู้ใช้ได้

สำหรับแอปพลิเคชันแชทนี้ เราจะใช้ช่อง Pub/Sub ของ Ably เพื่อให้ผู้ใช้ส่งข้อความโดย "เผยแพร่" ข้อความไปยังช่อง Ably และให้ผู้ใช้รับข้อความที่ส่งไปยังช่องโดย "สมัครสมาชิก"

สามารถจัดเตรียมช่อง Pub/Sub เหล่านี้ได้โดยการเพิ่มเลเยอร์นามธรรมที่ด้านบนของ Web Sockets พร้อมคุณสมบัติเพิ่มเติม บางส่วนมีดังนี้:

  • การปรากฏตัวของสมาชิก

  • การรับรองความถูกต้อง

  • กลไกการเต้นของหัวใจ

  • คิว

  • ความสามารถในการส่งข้อความตามลำดับที่เผยแพร่

  • การรวมระบบเพื่อเรียกใช้ฟังก์ชันตามเหตุการณ์ใดๆ บน Ably

  • สตรีมข้อความ/การแสดงตน/ข้อมูลเมตาไปยัง Kafka

คุณสามารถเยี่ยมชมเว็บไซต์ของพวกเขาเพื่อเรียนรู้เพิ่มเติม!

หากต้องการใช้ศูนย์กลางประสบการณ์แบบเรียลไทม์อันทรงพลังนี้ เราจำเป็นต้องสร้างแอปพลิเคชันบน Ably

มาสร้างบัญชี Ably กันก่อน

จากนั้น เราสามารถสร้างแอปพลิเคชันได้โดยเลือก "แชทสด"

สร้างแอปแชทแบบเรียลไทม์ด้วย Ably, Upstash Redis และ Node.js

แค่นั้นแหละ!

เราไม่จำเป็นต้องทำอะไรอย่างอื่นที่นี่ตอนนี้ เราจะกลับไปที่แดชบอร์ด Ably ในภายหลังเพื่อรับคีย์ API

อัพสแตช เรดดิส

เราจะใช้ Upstash Redis เพื่อจัดเก็บข้อความแชทอย่างต่อเนื่อง

พื้นที่เก็บข้อมูลนี้จะช่วยให้ผู้ใช้ดึงประวัติการแชทเมื่อเข้าร่วมได้

Upstash Redis จะอนุญาตให้เราจัดเก็บข้อความแชทเป็นรายการที่เรียงลำดับ ซึ่งจะช่วยให้เราส่งข้อความจากฐานข้อมูลไปยังไคลเอนต์โดยไม่จำเป็นต้องจัดเรียงใหม่

หากต้องการสร้างฐานข้อมูล Upstash Redis ให้ไปที่ Upstash Console เข้าสู่ระบบ และสร้างฐานข้อมูล Redis

สร้างแอปแชทแบบเรียลไทม์ด้วย Ably, Upstash Redis และ Node.js

โครงสร้างพื้นฐานพร้อม ตอนนี้ มาดูสถาปัตยกรรมของแอปพลิเคชันกันต่อ

สถาปัตยกรรมแอปแชท

การออกแบบแอปพลิเคชันแชทนี้จะค่อนข้างตรงไปตรงมา

สร้างแอปแชทแบบเรียลไทม์ด้วย Ably, Upstash Redis และ Node.js

ในโครงการสาธิตนี้ เราจะสร้างช่อง Ably เพียงช่องเดียวเพื่อให้เรียบง่าย ลูกค้ากำลังจะเผยแพร่ข้อความที่พวกเขาส่งไปยังช่องทางนั้น เมื่อลูกค้าเผยแพร่ข้อความ ลูกค้ารายอื่นจะได้รับข้อความทันทีผ่านการสมัครสมาชิกช่องของตน

นอกเหนือจากการส่งข้อความแบบเรียลไทม์ระหว่างไคลเอนต์แล้ว เรายังต้องจัดเก็บข้อความไว้ใน Upstash Redis เพื่อให้สามารถทำเช่นนั้นได้ ช่อง Ably จะมีสมาชิกเพิ่มขึ้นอีกหนึ่งรายซึ่งก็คือเซิร์ฟเวอร์ของเรา เซิร์ฟเวอร์นี้จะได้รับข้อความที่ส่งโดยไคลเอนต์ ส่งไปที่ Upstash Redis และเก็บไว้ที่นั่น

สุดท้ายนี้ เราจะใช้ประวัติการแชทที่จัดเก็บไว้ใน Upstash Redis ด้วยความช่วยเหลือของเซิร์ฟเวอร์ เราจะสร้างจุดสิ้นสุด "/history" บนฝั่งเซิร์ฟเวอร์ ซึ่งจะส่งคืนประวัติการแชทจาก Redis ลูกค้าจะสามารถเรียกคืนประวัติการแชทได้เมื่อโหลดแอปโดยการเรียกตำแหน่งข้อมูลนี้

อย่างที่คุณเห็น นี่เป็นแอปแชทธรรมดา ๆ เพื่อการสาธิต แอปพลิเคชันแชทนี้สามารถแก้ไขและขยายได้โดยใช้คุณสมบัติอื่นของ Ably ที่กล่าวถึงก่อนหน้านี้ในโพสต์บล็อกนี้

มาเริ่มกันเลย...

ฝั่งไคลเอ็นต์

ขั้นแรก เราต้องสร้าง UI การแชทพื้นฐานสำหรับผู้ใช้ เราจะสร้าง index.html ที่ตรงไปตรงมา หน้าเว็บเพื่อทำสิ่งนี้

<!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>

ในเบราว์เซอร์ของผู้ใช้ เราจะเห็นช่องป้อนข้อมูลสำหรับพิมพ์ข้อความ ปุ่มส่งเพื่อส่งข้อความและกล่องข้อความที่แสดงข้อความก่อนหน้า

ตอนนี้ เราจะเขียน “app.js” ซึ่งเป็นไฟล์ JavaScript ที่กำลังจะถูกดำเนินการโดยเป็นส่วนหนึ่งของหน้าเว็บ

เราจะสร้างช่อง Ably ก่อน ในการทำเช่นนั้น เราต้องกลับไปที่แดชบอร์ด Ably และสร้างคีย์ API ใหม่ภายใต้ "คีย์ API"

ให้เลือก "เผยแพร่" และ "สมัครรับข้อมูล" เป็นความสามารถของ API นี้

สร้างแอปแชทแบบเรียลไทม์ด้วย Ably, Upstash Redis และ Node.js

ตอนนี้เราสามารถสร้างไคลเอนต์ Ably ในไฟล์ JavaScript ได้โดยใช้คีย์ที่ให้ไว้ในแดชบอร์ดของ Ably

const ably = new Ably.Realtime(‘<Ably API Key>’);

คำเตือน

การให้คีย์ API แก่ลูกค้านั้นไม่ปลอดภัย สามารถจัดเตรียมกลไกที่เรียกว่า “TokenRequest” เนื่องจากนี่เป็นแอปพลิเคชันสาธิต เราจะมอบคีย์ API ให้กับไฟล์ JavaScript โดยตรง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการตรวจสอบสิทธิ์ไคลเอ็นต์สำหรับ Ably โปรดตรวจสอบเอกสารโทเค็นของ Ably

ตอนนี้ มาดูช่องทางของ Ably ที่ลูกค้าจะสื่อสารกัน

const channel = ably.channels.get('chat');

เราไม่จำเป็นต้องสร้างช่อง ช่องจะถูกสร้างขึ้นเมื่อมีผู้เผยแพร่บางสิ่งลงในช่อง

ในขั้นตอนก่อนหน้าก่อนที่จะใช้ฟังก์ชันการรับส่งข้อความ เราจำเป็นต้องได้รับชื่อผู้ใช้จากผู้ใช้ เราจะทำให้มันง่ายมากเนื่องจากการตรวจสอบสิทธิ์ไม่ใช่จุดสำคัญของบล็อกนี้

let name = window.prompt("Please enter your name.", "Anonymous");

ตอนนี้เราสามารถใช้การส่งข้อความได้แล้ว

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 = '';
 }
});

การส่งข้อความนั้นง่ายมาก! เราจำเป็นต้องสร้างวัตถุที่มีชื่อผู้ใช้และข้อความและเผยแพร่ไปยังช่อง Ably

เพื่อให้ผู้ใช้สามารถรับข้อความได้ เราจำเป็นต้องสร้างการสมัครสมาชิกช่องนั้นและเพิ่มกล่องข้อความที่มีชื่อผู้ใช้และข้อความ

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);
}

สุดท้ายนี้ เราจะดึงประวัติการแชทเมื่อโหลดเพจครั้งแรก

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);
 });
}

ฝั่งเซิร์ฟเวอร์

เซิร์ฟเวอร์ในแอปพลิเคชันสาธิตนี้จะสมัครรับข้อมูลจากช่อง Ably พุชไปยังฐานข้อมูล Upstash Redis และส่งคืนประวัติการแชทจาก Upstash Redis เมื่อไคลเอนต์ร้องขอ

เราจะกำหนดค่าเซิร์ฟเวอร์ก่อนในไฟล์ "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;

ต่อไป เราจะสร้างเซิร์ฟเวอร์ของเราใน “server.js” สมัครรับข้อมูลจากช่อง Ably และเชื่อมต่อกับ 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');

ขั้นตอนต่อไปคือการส่งข้อความขาเข้าไปยังฐานข้อมูล Upstash Redis เราจะดำเนินการนี้ด้วยการสมัครสมาชิกช่อง 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);
});

สุดท้ายนี้ เราจะใช้งานตำแหน่งข้อมูล “/history” ซึ่งจะดึงประวัติการแชทจาก Upstash Redis และส่งคืนไปยังไคลเอนต์

// 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 });
});

เรียกใช้แอป

ไปที่ไดเรกทอรีของไฟล์ “server.js” แล้วเรียกใช้:

node server.js

เปิด localhost:3000 ในเบราว์เซอร์ของคุณ มันจะขอชื่อผู้ใช้ก่อน

สร้างแอปแชทแบบเรียลไทม์ด้วย Ably, Upstash Redis และ Node.js

เมื่อคุณป้อนชื่อผู้ใช้แล้ว คุณจะสามารถเปิดแชทได้

หากคุณส่งข้อความจากแท็บเดียวและเปิด localhost:3000 ในแอปอื่นโดยใช้ชื่อผู้ใช้อื่น คุณสามารถดูข้อความที่ส่งจากแท็บก่อนหน้าได้

สร้างแอปแชทแบบเรียลไทม์ด้วย Ably, Upstash Redis และ Node.js

ขอบคุณ Upstash Redis คุณจะดึงข้อมูลประวัติการแชททุกครั้งที่คุณเปิดแอปพลิเคชันแชท

บทสรุป

สามารถนำเสนอคุณสมบัติต่างๆ เพื่อปรับปรุงการสื่อสารแบบเรียลไทม์ระหว่างแอปพลิเคชันต่างๆ โลกเรียลไทม์อันทรงพลังสามารถใช้ประโยชน์จากกรณีการใช้งานที่แตกต่างกันได้มากมาย

ในบล็อกโพสต์นี้ เราใช้ Ably เพื่อสร้างแอปพลิเคชันแชทแบบเรียลไทม์โดยใช้ช่อง Pub/Sub ขณะทำเช่นนี้ เราได้จัดเก็บข้อความไว้ในฐานข้อมูล Upstash Redis เครื่องมือทั้งสองนี้ทำให้แอปพลิเคชันนี้สร้างได้ง่ายและรวดเร็ว

เนื่องจากโปรเจ็กต์นี้เป็นเพียงการสาธิตวิธีใช้ Upstash Redis และ Ably เราจึงรักษาขอบเขตของโปรเจ็กต์นี้ให้เรียบง่ายมาก หากคุณสนใจ คุณสามารถสร้างแอปพลิเคชันแบบเรียลไทม์ที่แข็งแกร่ง ปรับขนาดได้ และปลอดภัยได้โดยใช้ฟีเจอร์ของ Ably และ Upstash Redis