2015-06-15 14 views
7

Đọc qua here và nhìn vào ví dụ here:Owin Websockets - Hiểu IOwinContext và WebSocketAccept

Tôi cố gắng để hiểu thực sự những gì WebSocketAccept thực hiện. Tôi biết rằng WebSocketAccept là:

using WebSocketAccept = 
    Action 
    < 
     IDictionary<string, object>, // WebSocket Accept parameters 
     Func // WebSocketFunc callback 
     < 
      IDictionary<string, object>, // WebSocket environment 
      Task // Complete 
     > 
    >; 

và được sử dụng theo cách này:

public void Configuration(IAppBuilder app) 
    { 
     app.Use(UpgradeToWebSockets); 
     app.UseWelcomePage(); 
    } 

    // Run once per request 
    private Task UpgradeToWebSockets(IOwinContext context, Func<Task> next) 
    { 
     WebSocketAccept accept = context.Get<WebSocketAccept>("websocket.Accept"); 
     if (accept == null) 
     { 
      // Not a websocket request 
      return next(); 
     } 

     accept(null, WebSocketEcho); 

     return Task.FromResult<object>(null); 
    } 

Vì vậy, những gì đang accept() actuallyt làm gì? Có phải nó đang gọi thuộc tính Func <> của WebSocketAccept và một phương thức WebSocketEcho được định nghĩa? WebSocketEcho được định nghĩa là:

private async Task WebSocketEcho(IDictionary<string, object> websocketContext) 

Vậy, websocketContext đến từ đâu? Điều gì xảy ra nếu chúng ta muốn vượt qua điều này sâu hơn khi chúng ta đã xác định nó là một yêu cầu socket web?

Trả lời

3

WebSocketAccept là gì?

WebSocketAccept là một using alias

Ví dụ:

... 
using Foo.Bar 
using MyBar = Fee.Bar 
... 

Ở đây chúng ta đang sử dụng Bar từ 2 gian tên khác nhau, nhưng chúng tôi bí danh là người thứ 2 với 'MyBar' vì vậy chúng tôi có thể phân biệt giữa hai người.

Tại sao sử dụng bí danh là WebSocketAccept?

Bí danh trong trường hợp này chỉ là sự tiện lợi, do đó bạn không phải nhập toàn bộ điều, có nghĩa là thay vì viết toàn bộ tên khi sử dụng, bạn có thể sử dụng bí danh thay thế.

Hiểu WebSocketAccept

Nếu chúng ta xem xét kỹ hơn chúng ta thấy rằng loại là:

Action<A, B> 

Điều này có nghĩa rằng nó thực chất là một chức năng mà không trả lại và mất 2 đối số, trong C# lambda:

(A, B) => { } 

Chúng tôi thấy đối số thứ nhất (A) là: IDictionary<string, object>, còn được gọi là môi trường Owin.

Đối số thứ 2 là (B) là: Func<C, D> có nghĩa là đó là hàm cần có C và trả lại D. Trong C# lambda:

(C) => { return D; } 

Sau đó chúng ta cần đi sâu vào đối số thứ nhất (C) của đối số thứ 2 (B). Và chúng ta thấy rằng phải mất một môi trường Owin và trả về một Task.

Chấp nhận là gì?

accept cố gắng trích xuất tham số từ IOwinContext và ánh xạ chúng tới loại WebSocketAccept.

Nếu nó không thể giải nén chúng là null và chúng tôi tiến hành phần mềm trung gian tiếp theo.

Nếu không, đó là yêu cầu websocket và chúng tôi gọi hàm có 2 tham số (WebSocketAccept), như chúng tôi đã thảo luận ở trên (Action<A, B>).

Tham số đầu tiên là từ điển thông thường, chứa từ khóa web chấp nhận các tham số.

Tham số thứ hai là hàm nhận từ điển và trả về tác vụ.

Chức năng này được gọi bởi người khác, nội dung của mã, là chuyển chức năng gọi lại cho người gọi.

Người gọi sau đó gọi hàm bằng đối số chính xác. Bởi vì người gọi biết chữ ký của hàm. Hàm này được gọi là SAU khi chấp nhận yêu cầu kết nối websocket. Do đó gọi lại bình luận.

Điều gì sẽ xảy ra nếu chúng tôi muốn truyền điều này sâu hơn khi chúng tôi xác định đó là yêu cầu trên web socket?

Vâng trong ví dụ này, hàm callback là WebSocketEcho nhưng về cơ bản bạn có thể vượt qua trong bất kỳ chức năng, đáp ứng các chức năng chữ ký của:

Task MyCallbackFunction(IDictionary<string, object> context) 
{ 
    // Do something 
    return Task.FromResult(0); 
} 

Các takeaway là bạn không gọi hàm, các chức năng được gọi cho bạn. Bạn chỉ định rằng sau khi thương lượng kết nối yêu cầu socket web, bạn quyết định điều gì xảy ra.

Chức năng WebSocketEcho được gọi một lần cho mọi khách hàng và lặp lại cho đến khi khách hàng chọn đóng kết nối. Trong khi đó nó lặp lại bất cứ điều gì nó nhận được.

Tuyên bố từ chối trách nhiệm: Tôi cũng đang cố gắng bọc đầu quanh ổ cắm web và nợ, nhưng tôi muốn chia sẻ những phát hiện của tôi về hậu thế, vì không ai trả lời câu hỏi của bạn. Tôi hoan nghênh mọi sửa đổi.

EDIT
tôi nhận thấy với thí nghiệm của riêng tôi, rằng nếu bạn trở về từ các hàm callback rằng kết nối websocketContext sẽ Abort ed. Có nghĩa là bạn không thể gửi/nhận tin nhắn trên kết nối nếu bạn vượt qua websocketContext xung quanh sau khi kết thúc cuộc gọi lại.

CẬP NHẬT
Thời gian qua tôi đã cố gắng để sử dụng này trên R2 IIS 7,5 máy chủ Windows 2008 tôi không thể có được WebSocket để làm việc. Sau đó, theo điều này: https://stackoverflow.com/a/14130152/1640121 - Máy chủ IIS 7.5 không hỗ trợ websockets.
Điều đó có nghĩa là nếu ứng dụng của bạn được lưu trữ trong IIS 7.5, nó sẽ không thể có ổ cắm web.

Sau đó, tôi nghĩ về một giải pháp khả thi:

  1. Sử dụng một ứng dụng riêng biệt, ví dụ một chương trình dịch vụ (bên ngoài IIS) xử lý yêu cầu websocket.
  2. Sử dụng một proxy ngược để lập bản đồ theo yêu cầu cho các ứng dụng dịch vụ

này cảm thấy quá rườm rà đối với tôi, điều đó khiến tôi đặt sang một bên thực hiện một WebSocket cho bây giờ ...

+1

Tôi nhận được 400 Bad Request trong khi thử cùng một mã. – Jigar