Đồng bộ hóa máy khách với máy chủ và với nhau


9

Cách tốt nhất để giữ cho tất cả các máy khách được đồng bộ hóa với một máy chủ và với nhau là gì?

Hiện tại, chúng tôi có hai cách tiếp cận trong tâm trí:

  1. Khi một máy khách gửi một cái gì đó đến máy chủ, máy chủ sẽ ngay lập tức gửi tin nhắn đến tất cả các máy khách, nó sẽ phản ứng ngay lập tức.
  2. Giới thiệu một số thời gian trễ, theo đó máy chủ sẽ gửi tin nhắn cho tất cả khách hàng, với chỉ thị, "hành động theo thời gian này t.

Cách tiếp cận thứ hai có vẻ như sẽ giúp các máy khách đồng bộ hóa tốt hơn (vì nó phục vụ cho một mức độ trễ nào đó); nhưng tôi tự hỏi liệu khả năng phản hồi có bị mất ở mức độ quá cao hay không (tức là người dùng nhấp vào 'nhảy' và có một khoảng cách đáng chú ý giữa việc nhấn nút và thực sự nhảy).

Ngoài ra còn có khả năng khách hàng tự tính toán vị trí của mình (và không đợi máy chủ nói "bạn đã nhảy"); nhưng vì độ trễ không thể tránh khỏi, khách hàng sẽ rất không đồng bộ.

Sau đó, có toàn bộ câu hỏi TCP so với UDP; bởi vì chúng tôi muốn nó nhanh, nhưng tôi cũng ghét máy chủ nói rằng bạn đang ở một địa điểm hoàn toàn khác so với bạn nghĩ.

Với tất cả các nhu cầu cạnh tranh này, tất cả đều không chắc chắn về cách chúng ta nên tiếp cận vấn đề này. Phương pháp nào trong số các phương pháp này (hoặc bất kỳ phương pháp nào khác) sẽ là tốt nhất để giữ cho máy khách và máy chủ đồng bộ? Những cái nào thực sự được sử dụng trong ngành công nghiệp?

Câu trả lời:


7

Câu trả lời nhanh là: không có cách tiếp cận tốt nhất.

Tất cả các trò chơi đều chứa kiến ​​trúc khác nhau; mỗi trò chơi sẽ chọn các bộ dữ liệu khác nhau để gửi để đồng bộ hóa với các máy khác, điều này sẽ ảnh hưởng đến các lựa chọn mà bạn có thể thực hiện khi chọn cách xử lý độ trễ.

Những gì bạn chỉ định trong tùy chọn # 2 - rằng khách hàng gửi tin nhắn sẽ được hành động trong thời gian tới - chắc chắn là một cách tiếp cận. Trong thực tế, công cụ Nguồn sử dụng một biến thể của phương pháp này , trong đó kết xuất luôn chậm 100ms so với các hành động của máy khách cục bộ; tất cả các máy cố gắng hoạt động trên cùng một hành động cùng một lúc. Điều này thêm một độ trễ nhân tạo, không thể chấp nhận được vào trò chơi để che giấu độ trễ mạng thực tế.

Nếu bạn không thể thực hiện phương pháp này, bạn cũng có thể chọn tùy chọn # 1, chỉ cần gửi dữ liệu cập nhật nhất và khi nhận được, sử dụng phép nội suy và ngoại suy (dự đoán phía khách hàng) để cố gắng che giấu độ trễ. Tôi đã sử dụng phương pháp này trong ít nhất một trò chơi vận chuyển - nhưng một lần nữa, tất cả phụ thuộc vào trò chơi của bạn ; có thể có những cách tiếp cận khác mà bạn có thể thực hiện.

Cuối cùng, khi chọn giữa TCP và UDP - bạn có thể muốn UDP. Có những tình huống trong đó TCP một tùy chọn khả thi để kết nối trò chơi của bạn, nhưng khi bạn tạo một trò chơi hành động, bạn muốn có dữ liệu mới nhất càng sớm càng tốt. Nếu bạn có thể tự xử lý các gói bị rơi, UDP là lựa chọn tốt hơn. (Có các thư viện, chẳng hạn như ENet , cung cấp trình bao bọc xung quanh UDP để thay thế chức năng từ TCP, chẳng hạn như các gói đáng tin cậy.)


Bạn thực sự không muốn sử dụng UDP. Chi phí hoạt động của một kết nối TCP được cấu hình chính xác là tối thiểu và địa ngục giao hàng không theo thứ tự là điều không ai cần phải trải qua.
coderanger

2
Đây không phải là vấn đề quá cao, mặc dù TCP bổ sung một số - cách TCP xử lý các gói bị rơi về cơ bản là không tốt trong các trò chơi khi độ trễ lớn giữa hành động và phản ứng có thể tạo ra sự khác biệt lớn về khả năng chơi. Đối với một trò chơi như WoW, nơi các hành động tương đối không thường xuyên, TCP hoạt động, nhưng nó sẽ thất bại trong một trò chơi như CounterStrike, vì một gói bị rơi sẽ điều tiết kết nối của bạn và có khả năng khiến bạn "tụt hậu" trong một giây trở lên.
Blair Holloway

Nếu bạn định sử dụng UDP, tốt nhất không nên tự viết; sử dụng một trình bao bọc như ENet, công việc khó khăn cho bạn. Nhưng câu trả lời ban đầu của tôi vẫn tồn tại - UDP là cách tốt nhất nếu bạn tạo một trò chơi với bất kỳ hành động nhịp độ nhanh nào.
Blair Holloway

Đối với tôi, RakNet đã khiến việc chạy kết nối UDP cho công cụ trò chơi của tôi cực kỳ dễ dàng. Nó có nhiều tùy chọn cho cách bạn muốn gửi gói của bạn tức là. Làm thế nào để đặt hàng chúng, gói tin có nên được gửi lại nếu bị rơi v.v.
BarakatX2

3

Đây là một vài liên kết tốt bao gồm rất nhiều mạng trò chơi.

Và đây là phần đầu tiên của loạt bài về mạng nhiều hơn. http://gafferongames.com/networking-for-game-programmer/udp-vs-tcp/

Đối với lịch sử. 'chúng tôi xin lỗi, nhưng là một cơ chế ngăn chặn thư rác, người dùng mới chỉ có thể đăng tối đa một siêu liên kết. Kiếm 10 danh tiếng để đăng nhiều siêu liên kết hơn. ' Chỉ cần nhìn xung quanh trang web của mình, dù sao.


1

Vì bạn đề cập đến Khách hàng và Máy chủ, tôi sẽ giả định rằng bạn đang nói về kiến ​​trúc Máy khách / Máy chủ trong đó Máy chủ là cơ quan có thẩm quyền về trạng thái của tất cả các đối tượng.

Lưu ý: Giải pháp thay thế là kiến ​​trúc ngang hàng trong đó chủ sở hữu của một đối tượng là người có thẩm quyền cho đối tượng đó.

Hiện đã có một phương pháp được chứng minh tốt để đồng bộ hóa các đối tượng chuyển động bằng kiến ​​trúc Client-Server. Nó được gọi là Xác định chết. .

Một cách tốt để thực hiện điều này trong một trò chơi sẽ như thế này:

  1. Khách hàng gửi đầu vào đến máy chủ.
  2. Máy chủ cập nhật các đối tượng trò chơi (tăng tốc & chỉ đường) và gửi lại cho Khách hàng.
  3. Khách hàng sử dụng các giá trị được cập nhật này để mô phỏng chuyển động của các đối tượng cục bộ.
  4. Thỉnh thoảng, máy chủ gửi một hiệu chỉnh vị trí để tránh trôi.
  5. Rửa sạch; nói lại.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.