Kiến trúc EzyChat được tổ chức theo hướng “một lõi nghiệp vụ, nhiều kênh giao tiếp”. REST API, Server-Sent Events, socket và trang quản trị không tự xây dựng các quy tắc chat riêng; chúng đóng vai trò adapter, cùng sử dụng mô hình dữ liệu và service dùng chung.
Cách tổ chức này giúp hệ thống duy trì hành vi nhất quán khi người dùng gửi tin nhắn từ widget, nhân viên trả lời qua giao diện hỗ trợ hoặc quản trị viên thao tác trên trang quản trị.

Bức tranh kiến trúc

Ở mức tổng thể, EzyChat gồm bốn lớp:
  • Lớp giao diện và client.
  • Lớp giao tiếp HTTP, SSE và socket.
  • Lớp nghiệp vụ dùng chung.
  • Lớp lưu trữ và dịch vụ nền tảng.
flowchart TB
    subgraph Client["Lớp client"]
        Widget["Widget chat"]
        SupportUI["Giao diện hỗ trợ"]
        AdminUI["Giao diện quản trị"]
        SocketClient["Socket client"]
    end

    subgraph Transport["Lớp giao tiếp"]
        WebRuntime["Web runtime"]
        AdminRuntime["Admin runtime"]
        SocketRuntime["Socket runtime"]
    end

    subgraph Application["Lớp ứng dụng"]
        Controllers["Controller và command handler"]
        Validators["Xác thực nghiệp vụ"]
        Decorators["Decorator và converter"]
        Services["Service nghiệp vụ"]
        BotManager["Bộ điều phối chatbot"]
    end

    subgraph Domain["Lõi dùng chung"]
        Models["Entity và model"]
        Repositories["Repository"]
        Pagination["Phân trang và bộ lọc"]
        Settings["Dịch vụ cấu hình"]
    end

    subgraph Infrastructure["Hạ tầng"]
        Database[(Cơ sở dữ liệu)]
        UserSystem["Người dùng và phân quyền"]
        MediaSystem["Media"]
        NotificationSystem["Thông báo"]
        BotProvider["Chatbot provider"]
    end

    Widget --> WebRuntime
    SupportUI --> WebRuntime
    AdminUI --> AdminRuntime
    SocketClient --> SocketRuntime

    WebRuntime --> Controllers
    AdminRuntime --> Controllers
    SocketRuntime --> Controllers

    Controllers --> Validators
    Controllers --> Services
    Controllers --> Decorators

    Services --> Models
    Services --> Repositories
    Services --> Pagination
    Services --> Settings
    Services --> BotManager

    Repositories --> Database
    Services --> UserSystem
    Services --> MediaSystem
    SocketRuntime --> NotificationSystem
    BotManager --> BotProvider

Các module kiến trúc

SDK dùng chung

SDK là phần lõi của EzyChat. Nó không trực tiếp nhận HTTP request hay socket command mà cung cấp các thành phần được các runtime khác tái sử dụng:
  • Entity ánh xạ dữ liệu chat.
  • Model truyền dữ liệu giữa các lớp.
  • Repository truy cập cơ sở dữ liệu.
  • Service triển khai nghiệp vụ.
  • Validator dùng chung.
  • Converter giữa request, model, entity và response.
  • Bộ lọc và tham số phân trang.
  • Hợp đồng tích hợp chatbot.
  • Dịch vụ đọc cấu hình.
Các module web, admin và socket đều phụ thuộc vào SDK. Chiều phụ thuộc chỉ đi từ adapter vào lõi; SDK không phụ thuộc ngược vào giao diện web hay trang quản trị.
flowchart LR
    Admin["Admin plugin"] --> SDK["EzyChat SDK"]
    Web["Web plugin"] --> SDK
    SocketApp["Socket application"] --> SDK
    SocketPlugin["Socket plugin"] --> SDK

    SDK --> Platform["EzyPlatform SDK"]
Cấu trúc này gần với kiến trúc phân lớp kết hợp adapter: lõi nghiệp vụ định nghĩa cách hệ thống vận hành, còn từng module bên ngoài chuyển đổi giao thức cụ thể thành lời gọi nghiệp vụ.

Web plugin

Web plugin chịu trách nhiệm cho trải nghiệm chat trên website. Thành phần này cung cấp:
  • Trang widget có thể nhúng.
  • Màn hình hỗ trợ đầy đủ.
  • REST API cho kênh, tin nhắn và thiết lập người dùng.
  • Phân trang lịch sử chat.
  • Luồng SSE cho phản hồi chatbot.
  • Tích hợp với người dùng, media và các chức năng web khác của nền tảng.
Web controller không truy cập trực tiếp cơ sở dữ liệu. Request được kiểm tra, chuyển thành model rồi chuyển tới service. Response sau đó được decorate bằng thông tin người gửi, media hoặc tin nhắn được trả lời trước khi gửi về client.

Admin plugin

Admin plugin là lớp vận hành dành cho quản trị viên và nhân viên hỗ trợ. Nó cung cấp cả giao diện HTML và API quản trị cho:
  • Danh sách kênh.
  • Lịch sử tin nhắn.
  • Hồ sơ chat.
  • Thành viên hồ sơ.
  • Nhân viên hỗ trợ.
  • Cấu hình widget và chatbot.
  • Ghim tin nhắn.
  • Kích hoạt, lưu trữ hoặc xóa kênh.
Trong giai đoạn cấu hình sau khi plugin được nạp, module quản trị còn thực hiện một số tác vụ khởi tạo, chẳng hạn bảo đảm vai trò hỗ trợ tồn tại và tạo danh tính hệ thống cho chatbot nếu chưa được cấu hình.
Đây là bước bootstrap có tính idempotent: hệ thống kiểm tra trạng thái hiện tại trước khi tạo dữ liệu cần thiết.

Socket application

Socket application xử lý các hành vi thời gian thực:
  • Nhận lệnh gửi tin nhắn.
  • Phân phối tin nhắn đến thành viên trong kênh.
  • Phát trạng thái đang nhập.
  • Phát câu trả lời chatbot.
  • Gửi thông báo tới người nhận.
  • Trao đổi dữ liệu với các connector được hỗ trợ.
Socket runtime lấy danh tính người dùng từ phiên kết nối đã được xác thực. Sau đó nó vẫn kiểm tra tư cách thành viên của kênh trước khi chấp nhận lệnh.
Socket không chỉ là kênh phát sự kiện cho dữ liệu được tạo từ REST. Nó có controller riêng và có thể tiếp nhận trực tiếp lệnh gửi tin nhắn, sau đó gọi cùng lớp nghiệp vụ mà web runtime sử dụng.

Socket plugin

Socket plugin là điểm tích hợp với vòng đời của EzyFox Server. Thành phần này khai báo thông tin plugin và vùng socket cần tham gia.
Request nghiệp vụ chat không được xử lý trực tiếp trong socket plugin. Chúng được chuyển cho socket application. Việc tách hai phần giúp điểm tích hợp server giữ vai trò mỏng, còn xử lý chat nằm trong application chuyên biệt.

Support view

Support view là ứng dụng giao diện phía trình duyệt. Nó giao tiếp với web plugin hoặc socket application tùy theo cấu hình của hồ sơ chat.
Frontend không phải nguồn xác thực quyền truy cập. Các kiểm tra thành viên, trạng thái kênh và quyền thao tác vẫn được thực hiện ở server.

Phân lớp bên trong mỗi runtime

Các module web, admin và socket có cấu trúc gần giống nhau:
flowchart LR
    Request["HTTP request hoặc socket command"]
    Controller["Controller"]
    Validator["Validator"]
    ControllerService["Dịch vụ điều phối"]
    DomainService["Service nghiệp vụ"]
    Repository["Repository"]
    Database[(Cơ sở dữ liệu)]
    Converter["Converter và decorator"]
    Response["HTTP response hoặc socket event"]

    Request --> Controller
    Controller --> Validator
    Validator --> ControllerService
    ControllerService --> DomainService
    DomainService --> Repository
    Repository --> Database

    Database --> Repository
    Repository --> DomainService
    DomainService --> Converter
    Converter --> Response
Controller giữ vai trò tiếp nhận giao thức:
  • Đọc path parameter, query parameter hoặc request body.
  • Lấy danh tính người gọi.
  • Kích hoạt validation.
  • Gọi dịch vụ điều phối.
  • Trả response phù hợp với giao thức.
Service nghiệp vụ chịu trách nhiệm thực hiện quy tắc chat. Repository chỉ phụ trách truy vấn và lưu dữ liệu. Converter và decorator tạo response có đủ thông tin hiển thị mà không làm phình entity lưu trữ.
Cách phân chia này hạn chế việc đưa logic nghiệp vụ vào controller, đồng thời cho phép REST và socket tái sử dụng cùng một hành vi.

Kiến trúc dữ liệu

Mô hình dữ liệu tập trung quanh kênh trò chuyện.
erDiagram
    CHAT_PROFILE ||--o{ CHAT_PROFILE_MEMBER : "quy định thành viên"
    CHAT_PROFILE ||--o{ CHANNEL : "được áp dụng cho"
    CHANNEL ||--o{ CHANNEL_MEMBER : "có thành viên"
    CHANNEL ||--o{ MESSAGE : "chứa"
    CHANNEL ||--o{ USER_CHANNEL_SETTING : "có thiết lập cá nhân"

    MESSAGE ||--o{ MESSAGE_STATUS : "theo dõi giao nhận"
    MESSAGE ||--o{ MESSAGE_RESOURCE : "đính kèm"
    MESSAGE ||--o{ MESSAGE_ACTION : "ghi nhận thao tác"
    MESSAGE o|--o{ MESSAGE : "trả lời hoặc phân cấp"

Chat profile

Chat profile là cấu hình cấp cao của một trải nghiệm chat. Nó mô tả:
  • Loại trải nghiệm.
  • Giao diện widget.
  • Phương thức truyền tải.
  • Điều kiện thông tin người dùng.
  • Thành viên hỗ trợ.
  • Chatbot service và cấu hình AI.
Một profile có thể được sử dụng để tạo nhiều kênh có hành vi giống nhau.

Channel

Channel là aggregate trung tâm của một cuộc hội thoại. Nó chứa trạng thái và metadata chung, trong khi thành viên và tin nhắn được lưu ở các quan hệ riêng.
Thiết kế này hỗ trợ cả hội thoại trực tiếp lẫn nhóm, đồng thời cho phép bổ sung thread hoặc các định dạng kênh khác.

Channel member

Channel member biểu diễn quan hệ giữa danh tính và kênh. Quan hệ này lưu vai trò, trạng thái, số tin chưa đọc và lần đọc gần nhất.
EzyChat phân biệt loại thành viên, chẳng hạn người dùng hoặc quản trị viên, thay vì giả định mọi thành viên đến từ cùng một bảng tài khoản.

Message

Message lưu nội dung cốt lõi. Media và tài nguyên đính kèm được tách khỏi bản ghi tin nhắn, cho phép một tin nhắn liên kết nhiều tài nguyên.
Trạng thái tin nhắn cũng được lưu riêng theo thành viên. Vì vậy, một tin nhắn có thể đã được người này xem nhưng vẫn chưa được người khác đọc.

Thiết lập kênh của người dùng

Các thiết lập như khóa kênh, đánh dấu spam hoặc ẩn hội thoại thuộc về quan hệ giữa một người dùng và một kênh. Chúng không làm thay đổi trạng thái chung của kênh đối với tất cả thành viên.

Luồng tạo kênh hỗ trợ

Khi người dùng bắt đầu trò chuyện, web runtime xác định hồ sơ chat từ khóa nhúng và tạo hoặc lấy lại kênh hỗ trợ.
sequenceDiagram
    actor User as Người dùng
    participant Web as Web runtime
    participant Profile as Dịch vụ hồ sơ chat
    participant Channel as Dịch vụ kênh
    participant Member as Dịch vụ thành viên
    participant DB as Cơ sở dữ liệu

    User->>Web: Yêu cầu bắt đầu chat
    Web->>Profile: Xác thực khóa nhúng
    Profile-->>Web: Hồ sơ đang hoạt động

    Web->>Channel: Tìm hoặc tạo kênh hỗ trợ
    Channel->>DB: Tìm kênh gần nhất

    alt Chưa có kênh
        Channel->>DB: Tạo kênh
        Channel->>Member: Thêm người dùng
        Channel->>Member: Thêm nhân viên hỗ trợ
    end

    Web->>Channel: Gắn hồ sơ chat vào kênh
    Web->>Member: Thêm thành viên của hồ sơ
    Channel-->>Web: Thông tin kênh
    Web-->>User: Kênh sẵn sàng
Hệ thống hỗ trợ hai ý định khác nhau:
  • Tìm hoặc tạo kênh hỗ trợ hiện có.
  • Luôn tạo một cuộc hội thoại hỗ trợ mới.
Sự phân biệt này cho phép sản phẩm lựa chọn giữa mô hình “một hộp thư hỗ trợ lâu dài” và “mỗi yêu cầu là một phiên hỗ trợ riêng”.

Luồng gửi tin nhắn qua socket

Socket là đường truyền thời gian thực đầy đủ nhất của EzyChat.
sequenceDiagram
    actor Sender as Người gửi
    participant Socket as Socket controller
    participant Guard as Validator
    participant Message as Dịch vụ tin nhắn
    participant Channel as Dịch vụ kênh
    participant Status as Dịch vụ trạng thái
    participant Push as Bộ phát socket
    participant Bot as Bộ điều phối chatbot

    Sender->>Socket: Lệnh gửi tin nhắn
    Socket->>Guard: Kiểm tra request và thành viên
    Guard-->>Socket: Hợp lệ

    Socket->>Message: Lưu tin nhắn và tài nguyên
    Socket->>Channel: Cập nhật lần chat gần nhất
    Socket->>Channel: Tăng số tin chưa đọc
    Socket->>Status: Tạo trạng thái SENT

    Socket->>Push: Phát tin nhắn tới thành viên
    Socket->>Push: Gửi thông báo
    Socket->>Bot: Yêu cầu trả lời nếu cần
    Socket-->>Sender: Tin nhắn được phát qua kênh chung
Danh sách người nhận được tạo từ thành viên của kênh, sau đó chuyển thành danh tính socket tương ứng. Vì vậy, phạm vi phát tin không phụ thuộc vào dữ liệu do client tự cung cấp.
Trạng thái “đang nhập” đi theo một luồng nhẹ hơn: server xác thực tư cách thành viên rồi phát sự kiện tạm thời. Sự kiện này không được lưu như một tin nhắn.

Luồng HTTP và SSE

REST được dùng cho phần lớn thao tác truy vấn và quản lý. Riêng việc gửi tin nhắn có chatbot có thể sử dụng request bất đồng bộ cùng SSE.
sequenceDiagram
    actor Browser as Trình duyệt
    participant API as Web API
    participant Chat as Dịch vụ tin nhắn
    participant SSE as SSE writer
    participant Bot as Chatbot service
    participant DB as Cơ sở dữ liệu

    Browser->>API: POST tin nhắn
    API->>Chat: Kiểm tra và lưu tin nhắn
    Chat->>DB: Lưu dữ liệu
    API->>SSE: Mở event stream
    SSE-->>Browser: event: message

    API->>Bot: Bắt đầu sinh câu trả lời

    loop Nội dung đang được sinh
        Bot-->>SSE: Delta nội dung
        SSE-->>Browser: event: botTyping
    end

    Bot-->>API: Câu trả lời hoàn chỉnh
    API->>DB: Lưu tin nhắn chatbot
    SSE-->>Browser: event: message
    SSE-->>Browser: event: done
Request được đưa sang chế độ bất đồng bộ trước khi gọi chatbot. Điều này tránh giữ một servlet thread trong suốt thời gian mô hình tạo câu trả lời.
Nếu validation thất bại sau khi request đã chuyển sang async, web runtime phải tự ghi mã lỗi và nội dung JSON vào response rồi hoàn tất async context. Lỗi này không còn đi qua exception handler đồng bộ thông thường.

Kiến trúc chatbot

Chatbot được triển khai theo mô hình Strategy kết hợp Registry.
flowchart LR
    ChatFlow["Luồng gửi tin nhắn"]
    Resolver["Bộ chọn chatbot"]
    Registry["Registry các chatbot service"]
    Default["Cấu hình mặc định"]
    Profile["Cấu hình theo hồ sơ"]
    ProviderA["Chatbot provider A"]
    ProviderB["Chatbot provider B"]
    Stream["Bộ xử lý stream"]
    Storage["Lưu câu trả lời"]

    ChatFlow --> Resolver
    Profile --> Resolver
    Default --> Resolver
    Resolver --> Registry
    Registry --> ProviderA
    Registry --> ProviderB
    ProviderA --> Stream
    ProviderB --> Stream
    Stream --> Storage
Mỗi chatbot service có tên riêng và triển khai hợp đồng tạo input stream, output stream cũng như kiểm tra trạng thái khả dụng. Service có thể được phát hiện từ application context hoặc đăng ký bổ sung khi runtime đang hoạt động.
Thứ tự lựa chọn chatbot là:
  1. Dịch vụ được chỉ định trong hồ sơ chat.
  2. Dịch vụ được cấu hình làm mặc định.
  3. Một dịch vụ đã đăng ký và khả dụng.
Trước khi gọi chatbot, hệ thống còn kiểm tra:
  • Danh tính chatbot đã được cấu hình.
  • Chatbot là thành viên của kênh.
  • Tin nhắn không đến từ chatbot hoặc quản trị viên.
  • Hạn mức phản hồi của người gửi chưa bị vượt quá.
  • Hồ sơ hoặc cấu hình mặc định phù hợp tồn tại.
Phần đọc stream chạy trên một thread pool riêng. Các delta được gom lại thành câu trả lời hoàn chỉnh; sự kiện “bot đang nhập” được giới hạn tần suất để tránh phát quá nhiều cập nhật tới client.

Cấu hình runtime

Cấu hình EzyChat được chia thành hai cấp.
Cấu hình toàn hệ thống bao gồm:
  • Bật hoặc tắt hiển thị chat trên web.
  • Chọn socket hay HTTP làm phương thức mặc định.
  • Giới hạn độ dài tin nhắn.
  • Cho phép đính kèm tệp.
  • Yêu cầu thông tin người dùng.
  • Cấu hình giao diện launcher.
  • Chatbot mặc định.
  • Số lượng tin nhắn làm ngữ cảnh.
  • Hạn mức và chu kỳ làm mới quota chatbot.
  • Kích thước thread pool xử lý stream.
Cấu hình theo chat profile có thể ghi đè hoặc cụ thể hóa trải nghiệm cho từng widget, website hay trường hợp sử dụng.
flowchart TB
    Global["Cấu hình toàn hệ thống"]
    Profile["Cấu hình chat profile"]
    Channel["Trạng thái của kênh"]
    UserSetting["Thiết lập cá nhân"]
    Runtime["Hành vi runtime"]

    Global --> Runtime
    Profile --> Runtime
    Channel --> Runtime
    UserSetting --> Runtime
Cấu hình quyết định hành vi, nhưng không thay thế kiểm tra quyền. Ví dụ, chọn giao tiếp qua socket không loại bỏ bước xác minh thành viên kênh.

Xác thực và phân quyền

EzyChat phân biệt authentication và authorization.
Authentication xác định người gọi là ai:
  • REST API người dùng và quản trị yêu cầu phiên đăng nhập.
  • Socket command sử dụng danh tính gắn với kết nối.
  • Trang widget có thể được tải công khai.
  • Trang hỗ trợ cho phép runtime nhận biết người dùng nếu đã có phiên.
Authorization xác định người gọi được làm gì:
  • Chỉ thành viên mới được đọc hoặc gửi tin nhắn trong kênh.
  • Một tin nhắn phải thuộc đúng kênh đang thao tác.
  • Kênh đã xóa không thể tiếp tục sử dụng.
  • Một số hành động yêu cầu vai trò nhân viên hỗ trợ.
  • Kênh bị khóa yêu cầu mật khẩu cũ hoặc token mở khóa còn hạn.
  • Thao tác quản trị vẫn phải đi qua validator nghiệp vụ.
Khi không có quyền truy cập, hệ thống thường trả tài nguyên như không tồn tại thay vì làm lộ rằng kênh có thật nhưng người gọi không phải thành viên.

Tính nhất quán và trạng thái

Một lần gửi tin nhắn bao gồm nhiều cập nhật:
  • Lưu tin nhắn.
  • Lưu tài nguyên.
  • Cập nhật thời điểm chat gần nhất.
  • Tăng số lượng chưa đọc.
  • Tạo trạng thái gửi.
  • Phát sự kiện.
  • Kích hoạt chatbot.
Đây là một workflow nhiều bước. Phần phát socket, gửi thông báo và gọi chatbot là side effect sau khi dữ liệu cốt lõi được tạo.
Kiến trúc hiện tại ưu tiên xử lý trực tiếp theo luồng request. Từ code không thể kết luận rằng toàn bộ workflow được bao phủ bởi một distributed transaction hoặc cơ chế exactly-once. Khi triển khai ở quy mô lớn, cần xem xét thêm:
  • Retry cho side effect thất bại.
  • Idempotency khi client gửi lại request.
  • Outbox nếu cần bảo đảm sự kiện luôn tương ứng với dữ liệu đã commit.
  • Giám sát độ trễ và lỗi của chatbot provider.
  • Đồng bộ số lượng chưa đọc khi có cập nhật cạnh tranh.

Phân trang

Các danh sách lớn như kênh, tin nhắn, thành viên và trạng thái sử dụng một abstraction phân trang chung.
Pagination parameter kết hợp:
  • Bộ lọc nghiệp vụ.
  • Thứ tự sắp xếp.
  • Page token kế tiếp.
  • Page token trước đó.
  • Yêu cầu lấy trang cuối.
  • Giới hạn số phần tử.
Thiết kế dựa trên token phù hợp với dữ liệu chat hơn offset pagination vì tin nhắn và kênh có thể tiếp tục được thêm trong lúc người dùng đang duyệt.
Client không nên diễn giải nội dung page token hoặc giả định token có thể dùng lại cho một bộ lọc khác.

Các mẫu thiết kế nổi bật

Kiến trúc EzyChat thể hiện một số mẫu thiết kế rõ ràng:
  • Layered Architecture: controller, service và repository có trách nhiệm tách biệt.
  • Adapter: web, admin và socket chuyển các giao thức khác nhau vào cùng lõi nghiệp vụ.
  • Strategy: nhiều chatbot service có thể được lựa chọn tại runtime.
  • Registry: chatbot service được tra cứu theo tên.
  • Decorator: response được bổ sung thông tin người dùng, media và quan hệ tin nhắn.
  • Repository: lớp nghiệp vụ không phụ thuộc trực tiếp vào truy vấn cơ sở dữ liệu.
  • DTO/Converter: request, model, entity và response không bị trộn lẫn.
  • Asynchronous Streaming: chatbot được đọc theo stream và trả về qua SSE hoặc socket.

Ranh giới kiến trúc

EzyChat thực hiện việc quản lý hội thoại và điều phối các thành phần liên quan, nhưng có một số ranh giới rõ ràng:
  • Plugin không tự cung cấp mô hình AI; nó gọi chatbot service đã đăng ký.
  • REST và socket là hai adapter riêng, không tự chuyển đổi qua lại.
  • Socket plugin không chứa toàn bộ nghiệp vụ chat; phần đó thuộc socket application và SDK.
  • Mật khẩu khóa kênh là kiểm soát truy cập, không phải mã hóa đầu cuối.
  • Sự tồn tại của loại tin nhắn mã hóa không chứng minh nội dung đã được mã hóa end-to-end.
  • SSE chỉ truyền sự kiện từ server về client trong request đang mở; nó không thay thế hoàn toàn kết nối socket hai chiều.
  • Frontend không quyết định quyền truy cập cuối cùng.
  • Cơ sở dữ liệu là nguồn lưu trữ hội thoại; socket chỉ là kênh phân phối thời gian thực.

Khả năng triển khai

Các thành phần của EzyChat có thể được nhìn như ba runtime chính:
flowchart TB
    Browser["Trình duyệt"]
    AdminBrowser["Trình duyệt quản trị"]

    WebProcess["Web runtime"]
    AdminProcess["Admin runtime"]
    SocketProcess["Socket server"]

    SharedDB[(Cơ sở dữ liệu dùng chung)]
    Bot["Dịch vụ chatbot"]

    Browser --> WebProcess
    Browser <--> SocketProcess
    AdminBrowser --> AdminProcess
    AdminBrowser <--> SocketProcess

    WebProcess --> SharedDB
    AdminProcess --> SharedDB
    SocketProcess --> SharedDB

    WebProcess --> Bot
    SocketProcess --> Bot
Các runtime dùng chung dữ liệu nhưng có vòng đời xử lý khác nhau. Vì vậy, cấu hình chatbot, danh tính thành viên và quy tắc phân quyền cần nhất quán giữa web và socket.
Nếu triển khai nhiều instance socket hoặc web, hệ thống cũng cần hạ tầng phân phối session và sự kiện phù hợp; code nghiệp vụ của plugin không tự biến kết nối socket cục bộ thành một message bus liên node.

Kết luận

Kiến trúc EzyChat được xây dựng quanh một lõi nghiệp vụ dùng chung và nhiều adapter giao tiếp. SDK giữ mô hình dữ liệu cùng quy tắc chat; web plugin phục vụ widget, REST và SSE; admin plugin phục vụ vận hành; socket application cung cấp giao tiếp thời gian thực; chatbot được tích hợp qua một hợp đồng mở rộng độc lập với nhà cung cấp.
Thiết kế này giúp EzyChat hỗ trợ nhiều trải nghiệm chat mà vẫn giữ nhất quán về dữ liệu và phân quyền. Đồng thời, ranh giới giữa lõi nghiệp vụ, giao thức truyền tải và dịch vụ bên ngoài tạo điều kiện để mở rộng chatbot, giao diện hoặc cơ chế phân phối mà không phải viết lại toàn bộ hệ thống.