Categories
DevOps

WEBSOCKET: TỪ SOCKETIO ĐẾN SOKETI

Khoảng 8 năm trước, từ lúc bỏ mô hình Server Side Rendering (jQuery, Ajax…) và bắt đầu xây dựng hệ thống dựa trên mô hình Microservices & Single Page App (SPA) và sử dụng hoàn toàn frontend bằng Reactjs thì cũng là lúc bắt đầu chơi với WebSocket cho các tính năng tương tác hai chiều (Client < — > Server) theo thời gian thực.

Hoạt động của WebSocket khá đơn giản: trình duyệt kết nối tới một Socket server, lắng nghe trên 1 (hoặc nhiều) channel mình khai báo rồi…chờ message trên channel đó. Server muốn gửi dữ liệu cho trình duyệt của user thì chỉ cần đẩy message vào channel này, trình duyệt sẽ tự động nhận message và xử lý (ví dụ như hiển thị thông báo trên trình duyệt hoặc một hành động khác.)

Nhiều người khi nghe nói đến Websocket thì chỉ nghĩ đến các tính năng realtime chat, nhưng Websocket có nhiều ứng dụng, trong đó mình sử dụng nhiều nhất cho 3 chỗ trên trình duyệt: Nhận thông báo mới (Notification), Cập nhật dữ liệu cache trên trình duyệt (Realtime Data Update) và Trạng thái online của user (Online Presence).

Các phần mềm hỗ trợ WebSocket Server

Thời bấy giờ không có nhiều lựa chọn, ứng cử viên sáng giá nhất là Socket.IO: Open Source – Miễn phí, tự cài đặt trên server riêng và Pusher: Cloud, không cần cài đặt gì hết và trả phí.

Socket.IO thì hầu như không có nhiều đồ chơi, ngoài việc chỉ hỗ trợ trình duyệt kết nối socket tới server, không có cơ chế xác thực (Authentication), muốn làm gì thì phải chủ động code tính năng hết. Do mình làm ứng dụng cho dự án SaaS và multi-tenant nên khối lượng code viết thêm nếu làm trên SocketIO là quá lớn nên buộc phải tìm giải pháp khác, và lúc này Pusher đã xuất hiện.

Pusher cung cấp cơ chế WebSocket với nhiều tính năng, trong đó có 2 tính năng nổi bật nhất là hỗ trợ Authentication xác thực user kết nối và Presence Channel để biết ai đang online/offline. Ngoài ra, Pusher còn cung cấp các thư viện tích hợp cho cả Javascript (gắn ở trình duyệt) và PHP (gắn ở server) để xác thực và trao đổi dữ liệu realtime giữa client và server được đơn giản và nhanh chóng, rút ngắn thời gian phát triển.

Có một bất lợi duy nhất của Pusher là…chi phí. Do đặc thù của một hệ thống Realtime là số lượng kết nối thường xuyên đến socket server, nên chi phí tính dựa vào số lượng kết nối. Sau khi đánh giá thì với chi phí của Pusher so với những lợi ích nó mang lại thì quyết định chọn Pusher.

Thay thế Pusher bằng Soketi

Mười ngày trước, nằm trong tuần lễ cải tổ hệ thống, trong đó có hạng mục nâng cấp phân hệ Pusher sau một thời gian dài sử dụng, thì thấy chi phí hiện tại không ổn nếu scale lên vài ngàn socket connection dựa trên Pusher, cũng như áp dụng cho các khách hàng outsourcing.

Thật may mắn là đã tìm ra Soketi, một open source cài đặt trên server của mình và cung cấp các tính năng gần như tương tự của Pusher. Và đặc biệt quan trọng là tương thích hoàn toàn với các thư viện kết nối ở phía Javascript và PHP, tức là không phải thay đổi cơ chế kết nối và lắng nghe message, chỉ cần cài Soketi (có hỗ trợ docker), sau đó thì config trỏ lại kết nối đến Soketi Websocket server vừa cài là xong.

Sau một tuần triển khai lên các môi trường dev và production cho các dự án thì thấy hoàn toàn ổn định, kết quả này cũng là cảm hứng cho bài viết chia sẻ công nghệ này. Hy vọng anh chị em có một hệ thống Websocket ngon, bổ rẻ để xây dựng các tính năng realtime cho môi trường web.

Categories
Technology

Vũ trụ Nextjs và Headless CMS

Sau nhiều ngày chờ đợi để xem NextJS có ra bản 13.5 hay không thì cũng không chịu được nữa (nằm ở v13.4 đã gần 3 tháng) và đành khởi công dự án xây dựng Public CMS Framework (hay nói kiểu nhà quê là làm cái website) với phiên bản NextJS 13.4.12.

Server Side Rendering (SSR) với PHP

#Cropcom, mỗi một Public CMS Framework được xây dựng thì xác định tối thiểu phải 5 năm sau mới thay đổi công nghệ nên việc lựa chọn công nghệ nền ban đầu ảnh hưởng rất lớn đến trải nghiệm phát triển tính năng của team, cũng như phải “chịu đựng” trong quá trình xây dựng tính năng nếu lỡ nó lạc hậu hoặc team đó bỏ rơi không phát triển tiếp công nghệ nền.

Nếu bạn quan tâm thì Public CMS Framework gần nhất của công ty do Tuấn xây dựng là dựa trên PHP 7, sử dụng một phần của Symfony HTTPFoundation để xây dựng core, sử dụng Smarty cho tầng View (HTML, CSS..), còn layer Model & Controller thì kết nối đến hệ thống microservice theo cơ chế Headless CMS. Public CMS này thực ra hiện tại vẫn ổn vì nó tương thích hoàn toàn với khả năng Server Side Rendering (SSR) để tận dụng tối đa khả năng onsite SEO.

NextJS cho SSR & CSR trong tương lai

Hướng cũ này có một bất lợi duy nhất là, sẽ khó khăn nếu tiếp cận xây dựng các tính năng không cần SEO (sau màn hình đăng nhập) như thông tin tài khoản, các tính năng sau khi đăng nhập (submit này nọ, tương tác với thành viên khác…). Lỡ theo kiến trúc này nên phần lớn các tính năng đòi hỏi thuần Client Side Rendering (CSR) toàn phải xài jQuery và code chay, rất khó mở rộng theo nhánh này. Mà ngày nay, làm gì có website nào chỉ thuẩn SEO content, nếu vậy xài WordPress cho rồi, viết framework đồ chi.

Nếu muốn viết lại Framework mới cho Public CMS thì phải giải quyết được 2 bài toán là cần có SSR, hỗ trợ được các công nghệ CSR như Reactjs…để vừa đạt hiệu quả làm SEO, vừa hỗ trợ team dev phát triển tính năng một cách hiệu quả, nhanh chóng. Thế là đến với NextJS. Hiện tại sau hơn 4 năm chạy với Nextjs (từ nextjs 8.x đến nay thì phiên bản 13.4 được coi là siêu ổn để giải quyết 2 vấn đề lớn mà Tuấn cần giải quyết cho Public CMS của mình.

Lựa chọn UI Component Library

Tuy nhiên, sau khi trào lưu di dời sang Nextjs thì sẽ phát sinh 1 vấn đề khác là không có một bộ Component UI Library hoàn hảo. Và vấn đề này luôn là mối quan ngại khi xây dựng CMS với Nextjs bởi chưa có “cái nào” mà mình đánh giá là xài được. Radix UI thì có vẻ phức tạp, ngôi sao mới nổi Shadcn thì tạo ra các giao diện không mấy thân thiện với người dùng bình thường nên chủ yếu shadcn để xây các sản phẩm hơi hướng tinh giản và tech savy. Chưa kể nhiều UI Lib không tương thích với React Server Component.

Dường như vũ trụ Nextjs đã lắng nghe, và sau 1 ngày xây dựng thì dự án NextUI (không liên quan đến Vercel) hôm qua đã ra mắt phiên bản 2.0 với RẤT nhiều cải tiến mà sẽ dùng tốt cho NextJS 13 (dùng App Router). Việc thấy được sự ra mắt của NextUI 2.0 chính là cảm hứng cho mình chia sẻ bài viết này cũng như mọi người có thể hình dung xây dựng một Public CMS cần có nhiều yếu tố cân nhắc vì tính dài hạn và hướng người dùng (UX) & hướng dev (DX).

NextUI Website: https://nextui.org/

Trong tương lai nếu có lib nào xịn hơn thì sẽ xem xét và cân nhắc, nhưng cho đến hôm nay thì mình thấy NextUI là chân ái và sẽ apply cùng với TailwindCSS cho toàn bộ các design của CMS.