2010-03-14 41 views
5

Từ những gì tôi đọc về Java NIO và SocketChannels [Server] không chặn, có thể viết một máy chủ TCP duy trì một số kết nối chỉ sử dụng một luồng - tôi sẽ tạo một Bộ chọn chờ tất cả các kênh liên quan trong vòng lặp của máy chủ.Ổ cắm Java: Tôi có thể viết một máy chủ TCP với một luồng không?

Điều đó đúng hay tôi thiếu một số chi tiết quan trọng? Tôi gặp phải vấn đề gì?

(Bối cảnh:.. Các giao thức TCP sẽ cho một trò chơi nhiều người chơi nhỏ, vì vậy tối đa 10-20 kết nối đồng thời tin nhắn sẽ được gửi về mỗi vài giây.)

Trả lời

2

Vâng, bạn là đúng. Các vấn đề bạn có thể gặp phải là khi thời lượng xử lý quá dài. Trong trường hợp này, bạn phải bọc phần xử lý bên trong một luồng khác, sao cho nó sẽ không can thiệp vào luồng mạng và ngăn sự chậm trễ đáng chú ý.

Chi tiết khác; Kênh là tất cả về dữ liệu "di chuyển". Nếu dữ liệu bạn muốn gửi đã sẵn sàng, thì bạn có thể di chuyển dữ liệu này sang kênh mạng. Sao chép/đệm/v.v. là tất cả được thực hiện bởi việc thực hiện NIO, sau đó.
Chủ đề mạng "đơn luồng" chỉ là kết nối, nhưng không điều chỉnh được kết nối (đọc: tương tự kỳ lạ với ô tô).

Phương pháp đa luồng cơ bản dễ thiết kế và triển khai hơn NIO luồng đơn. Hiệu suất đạt được là không đáng chú ý trong một máy chủ trò chơi nhiều người chơi nhỏ/khách hàng, đặc biệt là nếu một tin nhắn chỉ được gửi mỗi vài giây.

+0

Vâng ... có vẻ rất quen thuộc với lập trình xoay .. nơi bạn có một chuỗi gửi sự kiện chính, nhưng trong trường hợp máy chủ, tên thay vì là "Yêu cầu gửi chủ đề". Và đó cũng là thực hành tốt để ủy thác cho người khác chủ đề những sự kiện/requets đó đòi hỏi một số chế biến mà có thể mất nhiều hơn một giây để giải phóng các chủ đề bỏ phiếu. Có ý nghĩa guys hay tôi chỉ nói hạt? – Victor

+1

Vâng, những gì bạn nói có ý nghĩa. Những gì bạn mô tả là điển hình cho bộ xử lý sự kiện. Yêu cầu được xử lý dưới dạng sự kiện và kênh mà dữ liệu có sẵn hoặc sẽ được ghi vào được xử lý bởi một chuỗi khác với từ người chấp nhận. Lưu ý rằng với mô hình I/O ban đầu, người ta thường giả định rằng một máy chủ sinh ra một luồng mới cho mỗi máy khách, nhưng mô hình dựa trên sự kiện này với một số luồng cố định hữu dụng như nhau. – Pindatjuh

0

Có thể. Xem this example để biết minh họa về cách thực hiện việc này.

Phần quan trọng là thế này:

for (;;) { // Loop forever, processing client connections 
    // Wait for a client to connect 
    SocketChannel client = server.accept(); 

    // Build response string, wrap, and encode to bytes (elided) 

    client.write(response); 
    client.close(); 
} 

này tất cả hoạt động tốt khi xử lý server-side cho mỗi khách hàng là không đáng kể. Tuy nhiên một cách tiếp cận đa luồng sẽ mở rộng tốt hơn nhiều.

2

Brian Agnew nói:

này tất cả hoạt động tốt khi server-side chế biến cho mỗi khách hàng là không đáng kể. Tuy nhiên, phương pháp đa luồng sẽ mở rộng tốt hơn nhiều.

Tôi cầu xin không đồng ý. Một cách tiếp cận một khách hàng-một-thread sẽ xả bộ nhớ nhanh hơn nhiều nếu bạn xử lý nhiều khách hàng cho mỗi chủ đề vì bạn sẽ không cần một ngăn xếp đầy đủ cho mỗi khách hàng. Xem giấy C10K để biết thêm thông tin về chủ đề: http://www.kegel.com/c10k.html

Dù sao, nếu không có nhiều hơn 20 khách hàng, chỉ cần sử dụng mọi thứ dễ nhất để mã và gỡ lỗi.

Các vấn đề liên quan