Trò chuyện là một trong nhiều giao tiếp, trong khi mỗi người trong số nhiều người có thể gửi tin nhắn và sẽ nhận tin nhắn từ mọi người khác.
Hai hành động này (gửi, nhận) xảy ra liên tục. Vì vậy, điều này trông giống như một vòng lặp vô tận trong khi người dùng có thể tham gia (tham gia trò chuyện) và thoát (rời khỏi trò chuyện).
- nhập
- gửi thông điệp
- nhận được thông báo
- thoát
Vì vậy, các vòng lặp trông như thế này (pseudo-code) trên các mặt hàng:
while (userInChat)
{
if (userEnteredMessages)
{
userSendMessages(userEnteredMessages)
}
if (chatNewMessages)
{
displayMessages(chatNewMessages)
}
}
Như bạn đã lưu ý trong câu hỏi của mình, vấn đề là trong việc triển khai loại trò chuyện cho một trang web.
Để triển khai "vòng lặp" như vậy cho trang web, trước hết bạn phải đối mặt với tình huống mà bạn không muốn có vòng lặp thực sự tại đây. Miễn là người dùng đang trò chuyện, nó sẽ chạy và chạy và chạy. Vì vậy, bạn muốn phân phối việc thực hiện vòng lặp theo thời gian.
Để làm điều này, bạn có thể chuyển đổi nó thành một tập hợp các chức năng sự kiện:
ChatClient
{
function onEnter()
{
}
function onUserInput(messages)
{
sendMessages = send(messages)
display(sendMessages)
}
function onReceive(messages)
{
display(messages)
}
function onExit()
{
}
}
Đó là bây giờ có thể kích hoạt sự kiện thay vì có một vòng lặp. Chỉ còn lại là việc triển khai để kích hoạt các sự kiện này theo thời gian, nhưng hiện tại điều này không thực sự thú vị vì nó sẽ phụ thuộc vào cách trao đổi dữ liệu trò chuyện thực sự được triển khai.
Luôn có một điểm từ xa mà một ứng dụng trò chuyện (bằng cách nào đó) được kết nối với để gửi tin nhắn của chính nó và nhận tin nhắn mới từ đó.
Đây là một số loại luồng tin nhắn trò chuyện. Một lần nữa điều này trông giống như một vòng lặp, nhưng infact đó là một dòng. Giống như trong vòng lặp của máy khách trò chuyện, tại một thời điểm nào đó nó sẽ nối vào luồng và sẽ gửi đầu vào (ghi) và nhận đầu ra (đọc) từ luồng đó.
Điều này đã được hiển thị trong mã giả ChatClient ở trên, có sự kiện khi người dùng nhập một hoặc nhiều thư mà sau đó sẽ được gửi (văn bản). Và đọc tin nhắn sẽ có sẵn trong chức năng sự kiện onReceive.
Khi luồng là dữ liệu theo thứ tự, cần phải có thứ tự. Vì đây là tất cả sự kiện dựa trên và nhiều khách hàng có sẵn, điều này cần một số xử lý chuyên dụng. Theo thứ tự là tương đối, nó sẽ chỉ hoạt động trong bối cảnh của nó. Ngữ cảnh có thể là thời gian (một tin nhắn xuất hiện trước một tin nhắn khác), nhưng nếu ứng dụng trò chuyện có một đồng hồ khác là máy chủ hoặc máy khách khác, chúng tôi không thể sử dụng đồng hồ hiện tại làm nguồn thời gian cho thứ tự các thông điệp, vì nó thường khác nhau giữa các máy tính trong mạng WAN.
Thay vào đó bạn tạo thời gian của riêng mình để xếp hàng tất cả thư. Với thời gian chia sẻ trên tất cả các máy khách và máy chủ, luồng có thứ tự có thể được triển khai. Điều này có thể dễ dàng thực hiện bằng cách chỉ đánh số tin nhắn ở vị trí trung tâm. May mắn là cuộc trò chuyện của bạn có một vị trí trung tâm, máy chủ.
Luồng tin nhắn bắt đầu bằng tin nhắn đầu tiên và kết thúc bằng tin nhắn cuối cùng. Vì vậy, những gì bạn chỉ cần làm là để cung cấp cho các tin nhắn đầu tiên số 1 và sau đó mỗi tin nhắn mới sẽ nhận được số cao hơn tiếp theo. Hãy gọi nó là ID tin nhắn.
Vì vậy, bất kể bạn sẽ sử dụng công nghệ máy chủ nào, cuộc trò chuyện sẽ biết loại tin nhắn: Tin nhắn có ID và tin nhắn không có ID.Điều này cũng thể hiện trạng thái của tin nhắn: không phải là một phần hoặc một phần của luồng.
Không có thư liên quan đến luồng là thư mà người dùng đã nhập nhưng chưa được gửi đến máy chủ. Trong khi máy chủ nhận được tin nhắn "miễn phí", nó có thể đưa chúng vào luồng bằng cách gán ID:
function onUserInput(messages)
{
sendMessages = send(messages)
display(sendMessages)
}
Như ví dụ mã giả này cho thấy, đây là những gì đang xảy ra ở đây. Sự kiện onUserInput nhận được các tin nhắn chưa phải là một phần của luồng. Thói quen sendMessages sẽ trả về biểu diễn được truyền trực tiếp của chúng, sau đó được hiển thị.
Thói quen hiển thị sau đó có thể hiển thị thông báo trong thứ tự dòng của chúng. Vì vậy, vẫn không phụ thuộc vào cách thực hiện truyền thông máy khách/máy chủ, với cấu trúc như vậy bạn thực sự có thể xử lý một hệ thống trò chuyện dựa trên tin nhắn và tách nó khỏi các công nghệ cơ bản.
Điều duy nhất mà máy chủ cần làm là nhận tin nhắn, cung cấp cho mỗi tin nhắn một ID và trả lại các ID này. Việc gán ID thường được thực hiện khi máy chủ lưu trữ các thông điệp vào cơ sở dữ liệu của nó. Một cơ sở dữ liệu tốt sẽ chú ý đến các thông điệp số đúng cách, vì vậy không có nhiều việc phải làm.
Tương tác khác là đọc thư mới từ máy chủ. Để thực hiện điều này qua mạng một cách hiệu quả, máy khách sẽ thông báo cho máy chủ biết thông điệp nào mà nó thích đọc từ đó. Sau đó, máy chủ sẽ chuyển các tin nhắn từ thời gian đó (ID) đến máy khách.
Như điều này cho thấy, từ vòng lặp "vô tận" trong đầu nó bây giờ biến thành một hệ thống dựa trên sự kiện với các cuộc gọi từ xa. Khi các cuộc gọi từ xa đắt tiền, tốt hơn hết là làm cho chúng có thể chuyển nhiều dữ liệu với một kết nối. Một phần trong số đó đã có trong mã giả vì có thể gửi một hoặc nhiều thư đến máy chủ và nhận được không hoặc nhiều tin nhắn từ máy chủ cùng một lúc.
Việc triển khai lý tưởng sẽ là có một kết nối với máy chủ cho phép đọc và soạn tin nhắn với máy chủ ở chế độ song công. Tuy nhiên, không có công nghệ nào tồn tại trong javascript. Những thứ này đang được phát triển với Websockets và Webstream APIs và tương tự nhưng trong thời điểm này chúng ta hãy xem xét những thứ đơn giản và xem chúng ta có gì: yêu cầu HTTP không trạng thái, một số PHP trên máy chủ và cơ sở dữ liệu MySQL.
Luồng thông báo có thể được biểu diễn trong bảng cơ sở dữ liệu có khóa duy nhất tăng tự động cho ID và các trường khác để lưu trữ thư.
Kịch bản giao dịch ghi sẽ chỉ kết nối với cơ sở dữ liệu, chèn (các) thư và trả lại ID. Đó là một hoạt động rất phổ biến và nó phải được nhanh chóng (mysql có một loại cầu memcache mà nên làm cho hoạt động lưu trữ nhanh hơn và thuận tiện hơn).
Tập lệnh giao dịch đọc đơn giản như nhau, nó sẽ chỉ đọc tất cả các thư có ID cao hơn được truyền cho nó và trả lại cho khách hàng.
Giữ các tập lệnh này càng đơn giản càng tốt và tối ưu hóa thời gian đọc/ghi vào cửa hàng, để chúng có thể thực thi nhanh và bạn hoàn thành ngay cả khi trò chuyện qua HTTP thuần túy.
Máy chủ web của bạn và kết nối internet tổng thể có thể không đủ nhanh (mặc dù có keep-alive).
Tuy nhiên, HTTP phải đủ tốt để thử nghiệm nếu hệ thống trò chuyện của bạn thực sự hoạt động mà không có bất kỳ vòng lặp nào, không phải máy khách, cũng như phía máy chủ.
Nó cũng tốt để giữ các máy chủ chết đơn giản, bởi vì mỗi khách hàng dựa vào họ, vì vậy họ chỉ nên làm công việc của họ và đó là nó.
Bạn có thể bất cứ lúc nào thay đổi máy chủ (hoặc cung cấp loại khác nhau của máy chủ) có thể tương tác với khách hàng trò chuyện của bạn bằng cách đưa ra các chat client triển khai khác nhau của gửi và nhận các chức năng. Ví dụ. Tôi thấy trong câu hỏi của bạn rằng bạn đang sử dụng sao chổi, điều này cũng hoạt động tốt, có thể dễ dàng thực hiện trực tiếp máy chủ cho sao chổi.
Nếu trong WebSockets tương lai có thể truy cập hơn (mà có thể không bao giờ có trường hợp vì cân nhắc an ninh), bạn có thể cung cấp một loại máy chủ cho WebSockets là tốt. Miễn là cấu trúc dữ liệu của luồng là nguyên vẹn, điều này sẽ làm việc với các loại máy chủ khác nhau bên cạnh nhau. Cơ sở dữ liệu sẽ xử lý sự đồng dư.
Hy vọng điều này hữu ích.
Cũng giống như một lưu ý thêm: HTML5 cung cấp một cái gì đó gọi là Stream Updates with Server-Sent Events với một online demo và PHP/JS sources. Tính năng HTML 5 cung cấp một đối tượng sự kiện trong javascript có thể được sử dụng để tạo ra một ứng dụng thực hiện giao tác khách hàng trò chuyện mẫu.
+1, đây là câu trả lời duy nhất (cho đến nay) không chỉ đề xuất một cách tiếp cận khác với vòng lặp vô tận, mà còn cung cấp thông tin về cách tạo trao đổi tin nhắn full duplex (hoặc mô phỏng) dựa trên web. –
+1 chỉ vì những người viết này nhiều ?! Ý tôi là, tôi đã đọc các biểu hiện ngắn hơn. Tôi đã có các chuyến đi ngắn hơn đến DMV. Tôi đã có bữa sáng ngắn hơn với cặp song sinh 2 tuổi. Tất cả đùa sang một bên, chi tiết và suy nghĩ tốt đẹp! – iND