2014-05-20 29 views
6

Setup:SignalR khách hàng được kết nối lại sau khi khởi động lại Owin, nhưng thông điệp không được công bố

  1. SignalRServer console app: Microsoft.AspNet.SignalR.SelfHost v2.0.3
  2. SignalRClient console app: Microsoft .AspNet.SignalR.Client v2.0.3
  3. NET 4.5.1

tôi làm như sau:

  1. Hit nhập trên máy khách, một thông báo được nhận tại server và trên máy khách một lần nữa
  2. Vứt bỏ các máy chủ bằng cách nhấn phím bất kỳ trong máy chủ giao diện điều khiển
  3. Khởi động lại máy chủ bằng cách đánh phím bất kỳ trong máy chủ giao diện điều khiển
  4. khách hàng được kết nối lại
  5. Hit nhập vào khách hàng, nhận được tin nhắn ở máy chủ, nhưng không bao giờ đạt đến khách hàng một lần nữa

Tôi hy vọng tin nhắn sẽ được nhận lại tại máy khách. Tôi nghi ngờ nó có một cái gì đó để làm với việc tự lưu trữ, kể từ khi tôi đã cố gắng để chạy các khách hàng chống lại cùng một trung tâm trong một ứng dụng web chạy IIS với thành công.

Bất kỳ ý tưởng nào?

Cập nhật: nếu quá trình bảng điều khiển máy chủ bị giết và khởi động lại, nó có thể kết nối lại và truy xuất lại thư.

mã máy chủ

using System; 
using System.Threading.Tasks; 
using Microsoft.AspNet.SignalR; 
using Microsoft.Owin.Hosting; 
using Owin; 

namespace SignalRServer 
{ 
    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      const string url = "http://localhost:8081"; 

      while (true) 
      { 
       using (WebApp.Start<Startup>(url)) 
       { 
        Console.WriteLine("Server running on {0}. Hit any key to stop.", url); 
        Console.ReadLine(); 
       } 

       Console.WriteLine("Server stopped"); 

       Console.WriteLine("Hit any key to restart, Esc to exit"); 

       ConsoleKeyInfo ki = Console.ReadKey(true); 

       if (ki.Key == ConsoleKey.Escape) 
        return; 
      } 
     } 
    } 

    public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      app.MapSignalR(); 
     } 
    } 

    public class AuthenticationHub : Hub 
    { 
     public void BroadcastMessageToAll(string message) 
     { 
      Clients.All.sendMessageToClient(message); 
      Console.WriteLine("sendMessageToClient: " + message); 
     } 

     public override Task OnConnected() 
     { 
      Console.WriteLine("OnConnected " + Context.ConnectionId); 
      return base.OnConnected(); 
     } 

     public override Task OnReconnected() 
     { 
      Console.WriteLine("OnReconnected " + Context.ConnectionId); 
      return base.OnReconnected(); 
     } 

     public override Task OnDisconnected() 
     { 
      Console.WriteLine("OnDisconnected " + Context.ConnectionId); 
      return base.OnReconnected(); 
     } 
    } 
} 

Khách hàng đang

using System; 
using Microsoft.AspNet.SignalR.Client; 

namespace SignalRClient 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      while (true) 
      { 
       var hubConnection = new HubConnection("http://localhost:8081/signalr/hubs"); 

       hubConnection.Closed +=() => Console.WriteLine("Closed"); 
       hubConnection.StateChanged += e => Console.WriteLine("StateChanged: " + e.OldState + " " + e.NewState); 
       var hubProxy = hubConnection.CreateHubProxy("AuthenticationHub"); 

       hubProxy.On<string>("sendMessageToClient", 
        info => Console.WriteLine("sendMessageToClient received: " + info)); 
       hubConnection.Start(); 

       Console.WriteLine("Client started - hit Enter to send a message - ESC to stop"); 

       Console.ReadKey(); 

       while (true) 
       { 
        var keyInfo = Console.ReadKey(true); 

        if (keyInfo.Key == ConsoleKey.Escape) 
         break; 

        var message = "Console client : " + DateTime.Now.ToString("HH:mm:ss-fff"); 
        hubProxy.Invoke("BroadcastMessageToAll", message); 
        Console.WriteLine("Client sent BroadcastMessageToAll: " + message); 
       } 

       Console.WriteLine("Client stopping"); 

       hubConnection.Stop(); 

       Console.WriteLine("Client stopped - enter any key start again"); 
       Console.ReadLine(); 
      } 
     } 
    } 
} 
+0

Tôi ước gì có thể giúp đỡ nhiều hơn, nhưng tôi sao chép máy chủ của bạn và mã khách hàng đúng nguyên văn thành hai giao diện điều khiển dự án ứng dụng. Sau khi cài đặt các gói NuGet cần thiết, tôi đã có thể khởi động lại ứng dụng máy chủ, yêu cầu khách hàng tự động kết nối lại và sau đó tiếp tục gửi và nhận tin nhắn sau đó. – halter73

+0

Tôi đã cập nhật các bước để tái sản xuất chính xác hơn. Bạn nên khởi động lại chính ứng dụng giao diện điều khiển máy chủ, nhưng chính ứng dụng máy chủ SignalR. – Stian

Trả lời

5

Đội SignalR chỉ tôi đến giải pháp: Theo mặc định SignalR sử dụng GlobalHost, mà là một resolver singleton. Khi xử lý, nó sẽ không bao giờ quay trở lại.

Khi tạo cấu hình cho các trung tâm, bạn phải vượt qua một quán trọ resolver phụ thuộc mới:

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var hubConfiguration = new HubConfiguration {Resolver = new DefaultDependencyResolver()}; 
     app.MapSignalR(hubConfiguration); 
    } 
} 
0

tôi có một số vấn đề tương tự với SignalR (không exacly trong kịch bản giống nhau).

Sự cố thường xảy ra trong mô hình truyền thông request_from_server-> client-> response_to_server. Khi tôi cố gắng gọi Invoke trong mã máy khách (để gửi phản hồi đến máy chủ) trực tiếp trong quy trình nhận, tôi có hành vi lạ (chờ đợi vô hạn, các hiệu ứng phụ lạ, vv).

Giải pháp là chia quá trình thành hai chuỗi. Một để nhận tin nhắn từ máy chủ đến ConcurrentQueue cục bộ.Luồng thứ hai tìm nạp các thông điệp từ hàng đợi, xử lý chúng và gửi phản hồi trở lại máy chủ (bằng cách gọi). Bây giờ SignalR hoạt động như mong đợi.

Sự cố này có thể do cố gửi phản hồi TRƯỚC KHI thủ tục nhận được hoàn tất. Điều này không xảy ra trong mô hình truyền thông client-> server-> client thông thường.

1

Câu trả lời của Stian thật tuyệt vời. Nhưng nếu bạn cần sử dụng các phương thức tĩnh được định nghĩa trong GlobalHost, bạn cần gán trình phân giải phụ thuộc cho GlobalHost.

Các công trình sau đây cho tôi:

public void Configuration(IAppBuilder app) 
{ 
    .... Other configurations .... 
    GlobalHost.DependencyResolver = new DefaultDependencyResolver(); 
    app.MapSignalR(); 
} 

tôi xác định bối cảnh trung tâm theo cách này:

public sealed class RemoteAdminHub : Hub 
{ 
    #region Properties 

    /// <summary> 
    /// Gets the SignalR Hub context. 
    /// </summary> 
    public static IHubContext HubContext 
    { 
     get 
     { 
      return GlobalHost.ConnectionManager.GetHubContext<RemoteAdminHub>(); 
     } 
    } 

    #endregion 
} 
Các vấn đề liên quan