Redis Pub/Sub กับ Node.js ระดับ 101

มาหัดทำ Redis Publish/Subscribe ด้วย Node.js ที่เรารักกันนะ

Siwawes Wongcharoen
3 min readMay 18, 2022

ใน Blog นี้ ในส่วนแรก จะอธิบายถึง Pub/Sub ว่าหมายถึงอะไร และในส่วนหลังจะเป็นตัวอย่างการ Implement ของ Redis Pub/Sub กับ Node.js ครับ

Pub/Sub (Publish/Subscribe) คืออะไร

https://itnext.io/event-data-pipelines-with-redis-pub-sub-async-python-and-dash-ab0a7bac63b0

Pub/Sub เป็นรูปแบบการส่งข้อความ (Message) จากผู้ส่ง (Publisher) ไปยังผู้รับ (Subscriber) โดยที่ผู้ส่งและผู้รับ จะตกลงสื่อสารกันด้วยหัวข้อ (Topic) ผ่านตัวกลาง/ช่องทาง (Medium/Channel) ที่กำหนดไว้แล้ว

องค์ประกอบสำคัญของ Pub/Sub

Publisher

ผู้ส่ง Message/Event

Channel

ช่องทางการสื่อการ บางครั้งอาจจะเรียกว่า Broker, Message broker, Event bus หรือ Queue messaging ก็ได้

Subscriber

ผู้รับ Message/Event

Topic

หัวข้อของ Message/Event ที่ใช้สื่อสารกัน

ยกตัวอย่างที่น่าจะทำให้เข้าได้ง่ายขึ้น (อาจจะไม่ถูกต้อง 100%)

ให้นึกถึงบอร์ดประกาศข่าวสาร (Medium/Channel) เมื่อผู้ที่ต้องประกาศข่าว (Publisher) เอาตัวประกาศ (Message) มาติดที่บอร์ด โดยที่ตัวประกาศเอง ก็มีหัวข้อที่ชัดเจน แล้วมีผู้ที่ต้องการทราบประกาศ (Subscriber) โดยรู้ว่าต้องการอ่านประกาศจากหัวข้ออะไร (Topic) มาอ่านประกาศนั้น ๆ

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

publish–subscribe is a messaging pattern where senders is messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers, but instead categorize published messages into classes without knowledge of which subscribers

Redis Pub/Sub x Node.js Implementation

ในตัวอย่างนี้จะใช้งาน Redis ผ่าน Container เนื่องจากเป็นวิธีที่สะดวกที่สุดแล้วนะครับ ส่วนตัว Node.js Application ก็จะเขียนด้วย Javascript ธรรมดาครับ และ Code ทั้งหมดจะอยู่ที่ https://github.com/puuga/hello-redis-pub-sub-x-nodejs

Redis Container

สามารถเลือกใช้ Image ได้จาก https://hub.docker.com/_/redis

จากนั้นสั่งให้สร้าง Container ขึ้นมา

docker run --name my-redis -d -p 6379:6379 redis:6-alpine

เพื่อความแน่ใจ ลองใช้คำสั่ง docker container ls เพื่อตรวจสอบว่ามี Redis Container ทำงานหรือยัง

docker container ls

Publisher Node.js Application

Note: Code ทั้งหมดของ publish.js จะอยู่ที่ https://github.com/puuga/hello-redis-pub-sub-x-nodejs/blob/main/publish.js

ในส่วนของการ Publish Message เราจะทำตาม Redis Library หน้าตาของ Code ที่ได้ จะประมาณนี้ครับ

const client = createClient();
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();
const publisher = client.duplicate();
await publisher.connect();
await publisher.publish(topic, message);

Subscriber Node.js Application

Note: Code ทั้งหมดของ publish.js จะอยู่ที่ https://github.com/puuga/hello-redis-pub-sub-x-nodejs/blob/main/subscribe.js

ในส่วนของการ Subscribe Message เราจะทำตาม Library Redis หน้าตาของ Code ที่ได้ จะประมาณนี้ครับ

const client = createClient();
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();
const subscriber = client.duplicate();
await subscriber.connect();
await subscriber.subscribe(topic, (message) => {
console.log('Got message from topic:', topic);
console.log(message); // 'message'
});

Let Them Fight

ในการทดลองทำ Pub/Sub จะทดลองโดยการสื่อสารผ่าน 2 Topics คือ topic1 และ topic2 จาก publisher1, publisher2 และ subscriber1_1, subscriber2_1 และ subscriber3_2

ออกแบบการส่งข้อความตามลำดับดังนี้

  1. ให้ subscriber1_1, subscriber2_1 และ subscriber3_1 เริ่มทำงาน
  2. publisher1 สื่อสารโดยใช้ topic1 โดยมี subscriber1_1 และ subscriber2_1
  3. publisher2 สื่อสารโดยใช้ topic2 โดยมี subscriber3_2

1. ให้ subscriber1_1, subscriber2_1 และ subscriber3_1 เริ่มทำงาน

subscriber

แสดง subscriber1_1, subscriber2_1 และ subscriber3_1 เรียงตามลำดับจากบนลงล่าง

2. publisher1 สื่อสารโดยใช้ topic1 โดยมี subscriber1_1 และ subscriber2_1

ให้ publisher1 ส่งข้อความผ่าน topic1

ฉะนั้น subscriber1_1 และ subscriber2_1 จะได้รับข้อความ แต่ subscriber3_1 ไม่ได้รับข้อความ

topic1:message1

3. publisher2 สื่อสารโดยใช้ topic2 โดยมี subscriber3_2

ให้ publisher2 ส่งข้อความผ่าน topic2

ฉะนั้น subscriber3_1 จะได้รับข้อความ แต่ subscriber1_1 และ subscriber2_1 ไม่ได้รับข้อความ

topic2:message2

Conclusion

จากผลที่ได้ สามารถบอกได้เลยว่า การทำ Pub/Sub ผ่าน Redis นั่น เป็นอะไรที่ง่ายและตรงไปตรงมามาก

การทำ Pub/Sub สามารถนำไปต่อยอด กับระบบต่าง ๆ ได้อีกมาก แต่ในบางกรณี อาจจะต้องการ Feature ที่มากกว่านี้ เช่น Push/Pull ที่ Redis ก็ทำได้ แต่จะแอบใช้งานยากหน่อย เป็นต้น

ตัว Redis Library เอง ก็ยังมี Feature อีกหลายอย่างที่ไม่ได้ นำมาใช้ใน Blog นี้

--

--

No responses yet