Socket.io - MVC

 


- Hôm nay là chủ đề triển khai 1 socket-io cơ bản trong nodejs theo mô hình MVC😈😈

b1 : clone trên github về : git clone https://github.com/socketio/chat-example.git

Giải thích qua 1 chút về socket:

Socket.IO là một thư viện JavaScript hỗ trợ việc phát triển ứng dụng web thời gian thực (real-time applications). Nó cho phép giao tiếp hai chiều giữa máy chủ và trình duyệt web của người dùng, cho phép truyền tải dữ liệu và sự kiện giữa hai bên một cách nhanh chóng và liên tục.

Socket.IO xây dựng trên giao thức WebSocket, tuy nhiên nó cung cấp một lớp trừu tượng hơn cho việc làm việc với WebSocket và cung cấp nhiều tính năng hỗ trợ như đảm bảo tương thích ngược với các trình duyệt cũ không hỗ trợ WebSocket, xử lý tự động kết nối lại và phân biệt giữa các sự kiện và dữ liệu trong gói tin truyền tải.

Với Socket.IO, thì ta có thể xây dựng các ứng dụng web thời gian thực như trò chơi trực tuyến đa người chơi, ứng dụng chat và hệ thống thông báo trực tiếp. Nó hỗ trợ cả phía máy chủ và phía khách hàng, cho phép gửi và nhận các sự kiện và dữ liệu trong thời gian thực giữa các thành phần khác nhau của ứng dụng.

Socket.IO có thể được sử dụng với nhiều ngôn ngữ lập trình, không chỉ giới hạn trong JavaScript. Có các phiên bản và thư viện khác nhau của Socket.IO cho các ngôn ngữ như Python, Java, C++, C# và PHP.

Sau khi clone về thì ta được 1 cấu trúc cơ bản dạng như này :



b2 : Tạo thêm 1 số folder cơ bản của mô hình mvc như : Controllers , Models , Service , Routes ...

mkdir -p src/controllers ....



Trong folder trên github đã đc cài đặt sẵn express và socket rồi chỉ cần npm i là xong cài thêm nodemon để khỏi restart lại server



chạy thử 1 cái xem nó ra cái gì :


Chạy xong cũng ok không vấn đề gì . vẫn chat qua lại với nhau được .

Giờ thử thay đổi 1 chút theo mô hình mvc nè :


Rồi chạy thử coi : Lỗi sml :>

À là do quên import lại bên index.js đấy :

Rồi chạy lại xem :))

Nó lại lòi ra lỗi kia , lí do là ở đây nè :

ở file __dirname nó trỏ về thư mục root nên khi nhét vào file khác tất nhiên nó sai đường dẫn cmnr .

Ta sử kiểu sử dùng biến global thử xem sao .

Trong index.js định nghĩa ra 1 biến như sau :

global.__basedir = __dirname;

Lưu ý : khi đặt biến global ở trên thì có thể sử dụng biến này khắp toàn ứng dụng Khi tạo 1 biến toàn cục nó sẽ tồn tại trong suốt thời gian ứng dụng hoạt động - khi nó tồn tại như vậy thì điều đócó nghĩa nó nằm ở đó và chiếm tài nguyên ứng dụng đang chạy

thứ 2 nếu sử dụng global theo cách truyền thống thì nó gây ra tính đồng thời nhiều -

vì khi 1 ứng dụng có thể có nhiều luồng truy cập vào 1 biến dễ gây conflict khi đặt tên biến .

Oke giờ thử thay đổi 1 chút theo mô hình mvc này : Khi call api chạy qua route , route gọi hàm trong controller , controller chọc vào service (tự tìm hiểu thêm về mô hình mvc ở đây dài quá không nói hết)




Vẫn sẽ chạy được thôi Rồi ok coi như xong , giờ đến vấn đề chính là làm thế nào nhét cái thằng soket vào file nằm trong controller ?

Cách bình thường thì chúng ta sẽ sử dụng MiddleWare : (tự tìm hiểu về cơ chế hoạt động của middleware)


Tạo thêm 1 router và 1 hàm xử lý nữa : để call api và xử lí





oke test thử bằng cmd nè :




đấy chạy ngon :>

Tuy Nhiên vấn đề là bây giờ đăng kí sự kiện on thì thế nào xem đây :




sau khi chạy lần 1 :


Chỉ có 1 dòng được log ra tuy nhiên chạy lần 2 :

thấy vấn đề chưa ? lặp lại ở mỗi lần tương tự lần 3 log 3 lần , lần 4 log 4 lần .....

tức là khi đã khởi tạo connection thì chỉ cần khởi tạo 1 lần thôi nên khi để trong controller nó lặp lại nhiều lần như vậy thì hoàn toàn không đúng .

Rồi oke cách giải quyết là đặt io thành biến global :)



oke tạo file services này : chứ không cần gọi hàm connection gì ở controller nữa :>





ở file index import nó vào mà dùng :


sau đó cũng tại đây gọi luôn sự kiện connection :

cách này không dùng đến midleware nên cũng xóa đi . và sửa lại file controller :






Chạy refresh thử thì :

oke ko lặp lại log mà vẫn chat đc bth kìa !! thế là xong rồi :>






















































Nhận xét

related

Tìm hiểu về Rabbit-mq

Lợi ích của Promise so với async-await

Mạng máy tính

Redis - Basic