2013-03-20 81 views
8

Chúng tôi đang gặp một vấn đề thú vị. Đây là những gì thiết lập của chúng tôi trông giống như:SignalR .NET client ngắt kết nối

  • SignalR Server (một ứng dụng ASP.NET MVC) trên cửa sổ Server 2012.
  • ứng dụng Sencha HTML5 (SignalR khách hàng) trên cùng một máy chủ (Windows Server 2012).
  • Dịch vụ Windows .NET trên máy chủ Windows Server 2008 R2. Điều này cũng hoạt động như một khách hàng của SignalR.

Ban đầu chúng tôi đang sử dụng SignalR 0.5.3 - khi chúng tôi bắt đầu quan sát thấy kết nối của dịch vụ cửa sổ với máy chủ R báo hiệu bị loại bỏ. Tần suất của dải tần này từ vài phút đến vài giờ một lần. Nó kết nối lại trong hầu hết các trường hợp, nhưng không kết nối lại thường xuyên, dẫn đến dịch vụ windows mất kết nối của nó sau mỗi vài ngày. Nhưng không có mô hình nào được thiết lập cho nó. Nó không liên quan đến việc khởi động lại máy chủ/sao lưu, vv Chúng tôi đã thêm tính năng đăng nhập vào dịch vụ Windows để giám sát sự kiện StateChanged trên kết nối máy khách và nhận thấy sự kiện bị kích hoạt khi ngắt kết nối và kết nối lại, nhưng không phải khi nó không kết nối lại.

Sau đó chúng tôi đi qua chủ đề này: client constantly reconnecting

và quyết định nâng cấp tất cả mọi thứ để SignalR 1.0.1 (chúng tôi phải làm điều đó anyway tại một số điểm). Dịch vụ windows cũng đã được nâng cấp lên khung công tác 4.5 (từ Framework 2.0) bây giờ tham chiếu đến Microsoft.AspNet.SignalR.Client.dll mới. Điều này cũng cho phép chúng tôi (sử dụng một thuộc tính kết nối mới được thêm vào) để xác định rằng dịch vụ Windows thực tế sử dụng giao thức ServerSentEvents. Cài đặt cùng một dịch vụ Windows trên máy Windows Server 2012 sử dụng giao thức WebSockets. Điều này phù hợp với chủ đề này: SignalR .NET Client doesn't support WebSockets on Windows 7

Tuy nhiên, hành vi của dịch vụ trên máy chủ Windows Server 2008 R2 không thay đổi. Nó vẫn ngắt kết nối và kết nối lại, và mất kết nối của nó một lần trong một thời gian. Do một vài hạn chế, chúng tôi không thể sử dụng máy chủ Windows 2012 cho dịch vụ cửa sổ và bị mắc kẹt với các hệ điều hành cũ hơn. Đây không phải là để nói rằng dịch vụ cửa sổ bằng cách sử dụng giao thức websockets sẽ giải quyết tất cả các vấn đề của chúng tôi (chúng tôi đã không kiểm tra kỹ lưỡng). Điều thứ ba chúng tôi đã thử là lấy mã nguồn từ GitHub và biên dịch nó và nâng cấp các dịch vụ (SignalR Server và máy khách) - điều này được thực hiện để đảm bảo rằng chúng tôi có được bản sao mới nhất với bất kỳ sửa lỗi tiềm ẩn nào.

Nhưng không hiệu quả. Chúng ta đang ở thời điểm mà chúng ta cảm thấy chúng ta đã cạn kiệt các lựa chọn của mình. Gợi ý sẽ được đánh giá cao. Cảm ơn.

=====================================

EDIT: THÔNG TIN THÊM :

OK, bây giờ chúng tôi có thêm thông tin. Chúng tôi đã thêm một số mã vào dịch vụ windows (SignalR Client) để đăng nhập vào SignalR Server sau mỗi 30 phút (để kiểm tra kết nối).

Đây là những gì xảy ra trên các mặt hàng mỗi 30 phút:

WriteEvent(Now(), "INFO", "PING", "Performing logon procedure with SiteCode = " & msSiteCode & ".") 
trans.Invoke("login", New String() {msSiteCode, "", "SERVER", "", ""}) 

nơi xuyên là thể hiện của các lớp phía máy chủ kế thừa từ Hub, và WriteEvent về cơ bản là một dấu vết để viết thư cho một tập tin đăng nhập .

và các mặt hàng khác cũng có một phương pháp 'isLoggedIn' như sau:

Private Sub isLoggedIn(ByVal bLoggedIn As String) 
     If bLoggedIn Then 
      WriteEvent(Now(), "INFO", "", "SignalR Server: Authenticated")   
     Else 
      WriteEvent(Now(), "ERROR", "", "SignalR Server: Authentication failed") 
     End If 
End Sub 

Về phía server chúng ta có phương pháp đăng nhập:

Public Sub login(ByVal sAccount As String, _ 
        ByVal sCompanyCode As String, _ 
        ByVal sClientId As String, _ 
        ByVal sPassword As String, _ 
        ByVal sModuleCode As String) 
     Try 
      'Some code omitted that validates the user and sets bValidated. 

      If bValidated Then 
       'Update user in cache 
       ConnectionCache.Instance.UpdateCache(userId, Context.ConnectionId, UserCredential.Connection_Status.Connected) 
       Clients.Caller.isLoggedIn(True) 

       Dim connectionId As String = ConnectionCache.Instance.FindConnectionId(userId) 
       LogEvent("Successful login for connectionid: " & connectionId & ". Context. User: " & userId, _ 
         EventLogEntryType.Information) 
      Else 
       Clients.Caller.isLoggedIn(False, results) 
      End If 
     Catch ex As Exception 
      LogEvent("Login: " & ex.Message, EventLogEntryType.Error) 
     End Try 
End Sub 

Nếu chúng ta nhìn vào các tập tin đăng nhập của khách hàng , cứ sau 30 phút chúng tôi nhận được các mục nhập nhật ký sau:

  • Thực hiện quy trình đăng nhập bằng SiteCode = ABCD.
  • SignalR Server: Authenticated

Vì vậy, chúng ta biết rằng đăng nhập phương pháp server-side đang được gọi, và isLoggedIn phương pháp client-side cũng được gọi.

Tuy nhiên, tại một số thời điểm, trong khi phương thức phía máy chủ được gọi, phương thức phía máy khách isLoggedIn không được gọi. Vì vậy, cứ 30 phút một lần, chúng tôi chỉ bắt đầu có một mục nhập:

  • Thực hiện quy trình đăng nhập bằng SiteCode = ABCD.

Bên cạnh đó, sự kiện nhật ký:

LogEvent("Successful login for connectionid: " & connectionId & ". Context. User: " & userId, EventLogEntryType.Information) 

trong server-side phương pháp đăng nhập được ghi vào log server-side. Vì vậy, Clients.Caller.isLoggedIn (True) được gọi như mong đợi, nhưng chúng tôi không thấy điều đó ở phía máy khách. Vì vậy, tôi đoán những gì chúng tôi đang xem là khách hàng luôn có thể truy cập vào máy chủ và có thể gọi chức năng phía máy chủ (đăng nhập), nhưng máy chủ không gọi chức năng phía máy khách (isLoggedIn), và điều này bắt đầu xảy ra tại một số điểm.

Ngoài ra, điều này có thể là một cái gì đó cụ thể cho khách hàng .NET, vì tôi khá chắc chắn chúng tôi đã không nhìn thấy điều này xảy ra với khách hàng HTML5/javascript của chúng tôi.

+0

Nếu bạn muốn, bạn có thể thử gói hàng đêm cho khách hàng trên nguồn cấp dữ liệu myget này www.myget.org/F/aspnetwebstacknightly/. Bây giờ chúng ta có ghi nhật ký phía máy khách (Kết nối có một thuộc tính Text.Trace TextWriter). Bạn có thể sử dụng điều này để xem điều gì đang diễn ra và tại sao mọi thứ không hoạt động trên mạng của bạn. – davidfowl

+0

Cảm ơn. Chúng tôi hiện đã đăng nhập một vài sự kiện khác và đã cập nhật câu hỏi ban đầu với một số thông tin khác. – smitra

+0

Bạn cần ghi nhật ký phía máy khách chứ không phải nhật ký máy chủ. – davidfowl

Trả lời

2

Cuối cùng, chúng tôi vừa tạo một hàm "PINGING" đơn giản. Điều này được gọi mỗi 15 phút. Logic là như sau:

  1. SignalR Khách hàng có bộ hẹn giờ gọi phương thức PING mỗi 15 phút một lần.
  2. Máy chủ gọi phương thức PINGCLIENT của khách hàng trên máy khách để phản hồi.
  3. Trong sự kiện hẹn giờ PING tiếp theo trên máy khách (sau 15 phút), chúng tôi kiểm tra xem có phản hồi hay không. Nếu không, chúng tôi sẽ tạm ngưng tất cả hoạt động và khởi tạo lại kết nối Hub. Sau đó khởi động lại bộ hẹn giờ PINGING.

Vì vậy, mặc dù chúng tôi đã cố gắng tìm ra nguyên nhân là gì, chúng tôi có giải pháp để quản lý mất kết nối "máy chủ đến khách hàng" khi điều đó xảy ra. Lưu ý rằng đây là ngoài logic tái kết nối trong xây dựng trong signalR.

Chúng tôi cũng duy trì nhật ký và trung bình điều này xảy ra (khách hàng không nhận được PING từ máy chủ) có thể mỗi ngày một lần.

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