2012-12-06 24 views
8

tôi có dịch vụ WCF tiêu thụ bởi AJAX khách hàng sử dụng SOAP 1.2Tại sao InstanceContextMode.PerSession hoạt động như PerCall khi sử dụng wsHttpBinding?

Web.config:

<endpoint address="" binding="wsHttpBinding" 
contract="WcfService1.IService1" bindingConfiguration="wsHttpBin"> 

<wsHttpBinding> 
    <binding name="wsHttpBin"> 
    <security mode="None"/>   
    </binding> 
</wsHttpBinding> 

Từ những gì tôi có read, tôi phải sử dụng <security mode="None"/> từ một dịch vụ tiếp xúc với “wsHttpBinding” ràng buộc triển khai WS-Security của các đặc tả dịch vụ web của WS- *. Vì ràng buộc sử dụng bảo mật, yêu cầu sẽ bị từ chối vì AJAX không hỗ trợ ngữ cảnh bảo mật.

hành vi dịch vụ WCF của tôi được định nghĩa với InstanceContextMode.PerSession:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
       InstanceContextMode = InstanceContextMode.PerSession)] 

nhưng khi tôi tiêu thụ nó, cư xử như dịch vụ PerCall và mọi cuộc gọi bắt đầu một trường hợp WCF mới thay vì sử dụng các ví dụ hiện tại.

Tại sao InstanceContextMode.PerSession hoạt động như PerCall khi sử dụng wsHttpBinding?

Tôi có thể làm gì?

+0

có thể trùng lặp: http://stackoverflow.com/questions/4767102/wcf-sessions-with-a-wshttpbinding-and-without-windows-security – ErnieL

+0

@ErnieL Cảm ơn nhưng bằng không phải là một lựa chọn cho tôi vì nó sẽ không hoạt động với máy khách AJAX của tôi. –

+0

Bản thân wsHttpBinding không hỗ trợ phiên. – ErnieL

Trả lời

3

Phiên, khi được sử dụng qua HTTP, chỉ được WCF hỗ trợ khi sử dụng phiên bảo mật hoặc phiên đáng tin cậy. Nếu bạn không thể sử dụng một trong hai thì bạn phải tự mình thực hiện một cơ chế phiên. Nếu bạn kiểm soát cả phía máy khách lẫn phía máy chủ, nó sẽ khá dễ dàng để làm điều đó. Dưới đây là cách thực hiện:

Tạo lớp chứa tất cả dữ liệu phiên bạn cần lưu trữ (hãy gọi số SessionData), cộng thêm DateTime để sử dụng phiên cuối cùng. Sau đó, thêm vào lớp dịch vụ của bạn (hoặc bất kỳ lớp học nào khác) theo số staticConcurrentDictionary<string, SessionData>.

Khi khách hàng thực hiện cuộc gọi đến dịch vụ của bạn, yêu cầu nó chuyển một chuỗi duy nhất xác định phiên (có thể được tạo ngẫu nhiên ở phía máy khách). Bất cứ khi nào một khách hàng gọi cho bạn dịch vụ, tra cứu chuỗi phiên trong từ điển và truy xuất dữ liệu phiên (và cập nhật nội dung của nó nếu cần). Nếu nó không tồn tại, hãy tạo một mục mới trong từ điển. Ngoài ra, mỗi khi bạn truy cập đối tượng SessionData, hãy cập nhật 'lần sử dụng cuối cùng' DateTime vào thời điểm hiện tại. Nhiệm vụ nền nên định kỳ xóa các phiên cũ chưa được sử dụng trong một thời gian.

Vậy đó - bạn đã tự mình triển khai các phiên. Bây giờ bạn có thể sử dụng InstanceContextMode.Single và không lo lắng về WCF tạo đúng các phiên bản của lớp dịch vụ của bạn mỗi phiên.

EDIT: Nếu bạn đang viết dịch vụ WCF với .NET 4.5 và ứng dụng web của bạn chỉ nhắm mục tiêu trình duyệt hiện đại, bạn có thể sử dụng NetHttpBinding ở phía máy chủ và WebSocket ở phía máy khách. NetHttpBinding hỗ trợ phiên (khi chỉ định SessionMode.Required).

+0

+1: Không nói đề xuất của bạn thiếu sót để bắt đầu, nhưng để triển khai cơ chế phiên sẵn sàng sản xuất, có một loạt vấn đề cần xem xét hoặc xử lý: như tấn công phiên (tình cờ hoặc mục đích), thời gian chờ của phiên thực tế có ý nghĩa đối với ứng dụng, phiên (dữ liệu) kiên trì/khả năng phục hồi của bạn, trong trường hợp máy chủ khởi động lại (dự kiến ​​hoặc không có kế hoạch/hỏng), sửa đổi đồng thời phiên (dữ liệu) theo nhiều yêu cầu đồng thời, v.v. –

+0

@ Christian.K: Rất thật. Tôi không tin rằng hai điều cuối cùng được cung cấp bởi WCF ở tất cả mặc dù. An ninh thực sự là một vấn đề cần xem xét, và về an toàn luồng, giả sử mỗi khách hàng sẽ tạo ra một khóa phiên duy nhất và sẽ thực hiện tối đa một cuộc gọi đến dịch vụ tại bất kỳ thời điểm nào, nhưng nếu đó không phải là trường hợp an toàn luồng tính chính xác cũng cần phải được chăm sóc. –

+0

@AllonGuralnek không sử dụng InstanceContextMode.Single sẽ có tác động lớn đến hiệu suất của tôi? –

0

Điều này link cung cấp cho bạn khá nhiều tất cả Bạn cần biết về điều này (nói chung tất nhiên).

Nhưng chính xác.MSDN nói về phiên WCF:

Chúng được bắt đầu một cách rõ ràng và chấm dứt bởi ứng dụng gọi

tôi phải nói rằng tôi không biết về bất kỳ JS mã/khuôn khổ mà sẽ cho phép bạn để lưu trữ mở một cách rõ ràng kênh truyền thông WCF để giữ cho "phiên" của bạn còn sống. (Bạn chưa cung cấp mã khách hàng của mình vì vậy tôi phải đưa ra một số giả định). Phiên WCF không phải là "dựa trên cookie". Nó không làm việc "ra khỏi hộp" từ trình duyệt của bạn giống như nó sẽ cho ứng dụng web ASP.NET.

Đặt InstanceContextMode.PerSession làm cho dịch vụ WCF của bạn "sẵn sàng phiên" nhưng không đủ để "buộc" phiên.

+0

Ý của bạn là gì về "dựa trên cookie" cho ASP.NET? nếu tôi sẽ thêm để tôi có thể sử dụng nó? tôi có thể có giải pháp "ngoài hộp" không. –

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