Một chatbox đơn giản sử dụng WebSocket. Là một phiên bản nâng cấp của Bản API để cập nhật theo thời gian thực.
Đây là Server của classic-chatbox. Click vào đây để chuyển sang bản Client.
Ở phiên bản v2, mình (thực ra là chờ teacher dạy WebSocket) đã sử dụng WebSocket để thay thế cho API ở v1, giúp cập nhật theo thời gian thực với lượng tài nguyên sử dụng rất ít. Cũng qua đó mình cũng thêm vào "Hệ thống Chống lặp Biệt danh" (ARNS: Anti-Repeat Nickname System) (đặt tên cho nó sang), tức là mỗi kết nối chỉ được sử dụng 1 biệt danh (có thể thay đổi) và không được lặp với biệt danh hiện tại của người trước đó.
Ngoài ra còn có:
- "get" ngoài cung cấp tin nhắn ra thì nó sẽ cung cấp cho Client cái Biệt danh của những người đã kết nối tới Server.
- Để sử dụng các tính năng trên Server (trừ "register"), bạn sẽ phải Đăng ký cho mình một cái Biệt danh trước ("register"), hoặc là Server chỉ đưa cho bạn đúng mỗi cái nịt
status: false
cho bạn muốn làm gì thì làm. - Thông báo cho bạn nguyên nhân gây lỗi yêu cầu của bạn ("reason" và "error")
- Log tại Console đã được phân rõ ràng
- ...
và nhiều tính năng mới mà cơ bản mình lười nên không ghi, với lại không nhớ mình đã update những gì
Chạy file index.py
(python index.py
)
Tóm gọn lại là thế này:
Mỗi Client sau khi kết nối phải gửi lệnh (tin) đăng ký để đăng ký cho mình 1 biệt danh, có thể thay đổi nhưng phải khác với các biệt danh hiện tại của người khác, bằng không thì các chức năng chính (trừ chức năng đăng ký) sẽ không được thực thi. Biệt danh giống như tên của Client, dùng làm tên để đại diện trò chuyện với các Client khác.
Khi Client gửi cho Server 1 message:
{"data":"name", "name":"
Tên_người_dùng
"}
- TH1: Chưa đăng ký
- Server sẽ gửi cho Client đó:
{"type":"name", "action":"register", "name":"
Tên_Người_dùng
", "status":true, "timestamp":"
Thời_gian
"}
và đăng ký Biệt danhTên_người_dùng
cho Client (vào lúcThời_gian
) (Thành công){"type":"name", "action":"register", "name":"
Tên_Người_dùng
", "status":false, "reason":"NameAlreadyUsed"}
nếu Biệt danh đãTên_Người_dùng
bị ai đó sử dụng/đăng ký (Thất bại){"type":"name", "action":"register", "name":"
Tên_Người_dùng
", "status":false, "reason":"WrongFormatName"}
nếu Biệt danhTên_Người_dùng
không đúng quy chuẩn (Thất bại){"type":"name", "action":"register", "name":"
Tên_Người_dùng
", "status":false, "reason":"ErrorWhenRegister", "error":"
Lỗi_Trên_Server
"}
nếu đã xảy ra lỗiLỗi_Trên_Server
khi thực hiện đăng ký biệt danhTên_Người_dùng
cho Client trên Server (Thất bại)
- Server sẽ gửi cho các Client khác:
{"type": "receive", "datatype": "register", "name":"
Tên_người_dùng
", "timestamp":"
Thời_gian
"}
nếu việc đăng ký Biệt danhTên_người_dùng
cho Client trên thành công vào lúcThời_gian
`
- Server sẽ gửi cho Client đó:
- TH2: Đã đăng ký
- Server sẽ gửi cho Client đó:
{"type":"name", "action":"change", "oldname":"
Tên_Người_dùng_cũ
", "newname":"
Tên_Người_dùng_mới
", "status":true, "timestamp":"
Thời_gian
"
và đổi Biệt danh cho Client từTên_Người_dùng_cũ
thànhTên_Người_dùng_mới
vào lúcThời_gian
(Thành công){"type":"name", "action":"change", "oldname":"
Tên_Người_dùng_cũ
", "newname":"
Tên_Người_dùng_mới
", "status":false, "reason":"NameAlreadyUsed"}
nếu không thể đổi Biệt danh cho Client từTên_Người_dùng_cũ
thànhTên_Người_dùng_mới
do Biệt danhTên_Người_dùng_mới
đã được sử dụng/đăng ký (Thất bại){"type":"name", "action":"change", "oldname":"
Tên_Người_dùng_cũ
", "newname":"
Tên_Người_dùng_mới
", "status":false, "reason":"WrongFormatName"}
nếu không thể đổi Biệt danh cho Client từTên_Người_dùng_cũ
thànhTên_Người_dùng_mới
do Biệt danhTên_Người_dùng_mới
không đúng quy chuẩn (Thất bại){"type":"name", "action":"change", "oldname":"
Tên_Người_dùng_cũ
", "newname":"
Tên_Người_dùng_mới
", "status":false, "reason":"ErrorWhenChange", "error":"
Lỗi_Trên_Server
"}
nếu đã xảy ra lỗiLỗi_Trên_Server
khi thực hiện thao tác đổi Biệt danh cho Client từTên_Người_dùng_cũ
thànhTên_Người_dùng_mới
trên Server (Thất bại)
- Server sẽ gửi cho các Client khác:
{"type": "receive", "datatype": "change", "oldname":"
Tên_người_dùng_cũ
", "newname":"
Tên_người_dùng_mới
", "timestamp":"
Thời_gian
"}
nếu việc đổi Biệt danh cho Client trên từTên_Người_dùng_cũ
thànhTên_Người_dùng_mới
vào lúcThời_gian
thành công
- Server sẽ gửi cho Client đó:
- TH1: Chưa đăng ký
{"data":"get"}
- Server sẽ gửi cho Client đó:
{"type":"get", "status":true, "name":"
Tên_Người_dùng
", "timestamp":"
Thời_gian
", "data": {"message":
[Dãy_Tin_nhắn]
, "online":
[Dãy_Người_dùng]
}}
cho Client mình (Biệt danh:Tên_Người_dùng
), lấy dữ liệu vào lúcThời_gian
(Thành công)[Dãy_Tin_nhắn]
là tập hợp tất cả tin nhắn (Object), sắp xếp theo Cũ đến mới nhất. Đây là đại diện 1 tin nhắn có nội dungNội_dung
được gửi bởiTên_Người_dùng
lúcThời_gian
:{"name":"
Tên_Người_dùng
", "content":"
Nội_dung
", "timestamp":"
Thời_gian
"}
***[Dãy_Người_dùng]***
là tập hợp tất cả xâu là những biệt danh đang được sử dụng/đăng ký (Kể cả của bạn).
{"type":"get", "status":false, "reason":"UnknownRegister"}
nếu Client chưa đăng ký biệt danh (Thất bại){"type":"get", "name":"
Tên_Người_dùng
", "status":false, "reason":"ErrorWhenGet", "error":"
Lỗi_trên_Server
"}
nếu đã xảy ra lỗiLỗi_Trên_Server
khi thực hiện thao tác trên Server cho Client đó (biệt danhTên_Người_dùng
) (Thất bại)
- Server sẽ gửi cho Client đó:
{"data":"send", "content":"
Nội_dung
"}
- Server sẽ gửi cho Client đó:
{"type":"send", "name":"
Tên_Người_dùng
", "content":"
Nội_dung
", "status":true, "timestamp":"
Thời_gian
"}
và lưu tin nhắn lại, gửi bởi Client đó (biệt danh:Tên_Người_dùng
) với nội dungNội_dung
vào lúcThời_gian
(Thành công){"type":"send", "status":false, "reason":"UnknownRegister"}
nếu Client đó chưa đăng ký biệt danh (Thất bại){"type":"send", "username":"
Tên_Người_dùng
", "content":"
Nội_dung
", "status":false, "reason":"WrongFormatContent"}
nếuNội_dung
không đúng quy chuẩn (Gửi tin nhắn cho Client đó (Biệt danh:Tên_Người_dùng
)) (Thất bại){"type":"send", "username":"
Tên_Người_dùng
", "content":"
Nội_dung
", "status":false, "reason":"ErrorWhenSend", "error":"
Lỗi_trên_Server
"}
nếu đã xảy ra lỗiLỗi_Trên_Server
khi thực hiện thao tác gửi tin nhắn cho Client đó (Biệt danh:Tên_Người_dùng
) với nội dungNội_dung
trên Server (Thất bại)
- Server sẽ gửi cho các Client khác:
{"type":"receive", "datatype":"message", "name":"
Tên_người_dùng
", "content":"
Nội_dung
", "timestamp":"Thời_gian"}
nếu việc gửi tin nhắn có nội dungNội_dung
cho Client trên (Biệt danh:Tên_người_dùng
) thành công
- Server sẽ gửi cho Client đó:
Tại sự kiện:
- Có 1 client đã đăng ký biệt danh
Tên_người_dùng
Ngắt kết nối khỏi Server vào lúcThời_gian
:- Server sẽ gửi cho các Client khác:
{"type":"receive", "datatype":"leave", "name":"
Tên_người_dùng
", "timestamp":"
Thời_gian
"}
và xóa biệt danhTên_người_dùng
khỏi danh sách biệt danh đã đăng ký
- Server sẽ gửi cho các Client khác:
- Client gửi cho Server tin nhắn không thuộc dạng JSON:
- Server sẽ gửi cho Client đó:
{"status":false, "reason":"WrongFormatJSON"}
- Server sẽ gửi cho Client đó:
- Client gửi cho Server một trong 2
Loại_Yêu_cầu
trên (name
hoặcsend
) nhưng không có keyKey_cần
được yêu cầu- Server sẽ gửi cho Client đó:
{"type":"
Loại_Yêu_cầu
", "status":false, "reason":"NotEnoughKey", "need":"
Key_cần
}
- Server sẽ gửi cho Client đó:
- Client gửi cho Server tin nhắn không thuộc một trong 3 Loại yêu cầu trên (
name
,send
,get
):- Server sẽ gửi cho Client đó:
{"type":null, "status":false, "reason":"UnknownType"}
- Server sẽ gửi cho Client đó:
Server sẽ kiểm tra Client đã Ngắt kết nối chưa mỗi 5s bằng cách cứ mối 5s sẽ gửi cho các Client tin nhắn {"type":"ping", "timeout":"
Delay_mỗi_lần_ping
"}
. Phải kiểm tra như vậy vì #1. Delay_mỗi_lần_ping
hiện tại là số 5.
Quy chuẩn:
Tên_Người_dùng
,Tên_Người_dùng_mới
có ít nhất 1 ký tự và nhiều nhất 100 ký tựNội_dung
có ít nhất 1 ký tự và nhiều nhất 4000 ký tựThời_gian
là một xâu có dạng{
Ngày
}/{
Tháng
}/{
Năm
} {
Giờ
}/{
Phút
}{
Giây
}
Lịch sử chat sẽ được lưu trong file data.json
để lưu trữ và thực hiện các hành động liên quan. Rất cổ điển.
- #study: Đây là repo được tạo ra nhằm mục đích để hoàn thành Bài tập về nhà hoặc tựa tựa thế.
Đây là dự án rất tâm huyết của mình :v Mong mọi người thích nó :3