2011-09-25 17 views
54

Tôi đang sử dụng tính năng Hub- của SignalR (https://github.com/SignalR/SignalR) công bố thông điệp đến tất cả khách hàng đăng ký:SignalR + đăng một thông điệp tới một Hub thông qua một phương pháp hành động

public class NewsFeedHub : Hub 
public void Send(string channel, string content) 
{ 
    Clients[channel].addMessage(content); 
} 

này hoạt động tốt khi gọi "Gửi" thông qua Javascript, nhưng tôi cũng muốn ứng dụng web xuất bản các tin nhắn (từ bên trong một phương thức hành động ASP.NET MVC). Tôi đã cố gắng instantiating một đối tượng mới ob NewsFeedHub và gọi phương thức Send, nhưng điều này dẫn đến một lỗi (vì "Connection" cơ bản của Hub không được thiết lập). Có cách nào để sử dụng Hub mà không có kết nối không?

+2

đã làm bạn tìm câu trả lời này? Tôi đang ở trong tình trạng tương tự. Dll Signalr dường như khởi tạo đối tượng trung tâm, vì vậy tôi đã tự hỏi nếu tôi cần thiết để có được quyền truy cập vào đó. – Mike

Trả lời

79

Xin lưu ý rằng API SignalR đã thay đổi nhiều lần kể từ khi câu hỏi này được hỏi. Có khả năng một số câu trả lời sẽ lỗi thời. Điều này không có nghĩa rằng họ nên được xuống bình chọn là họ đã chính xác tại thời điểm viết bài

Còn có một câu trả lời được cập nhật cho điều này, như đã thấy trong SignalR Wiki

C#

Public ActionResult MyControllerMethod() 
{ 
    var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>(); 
    context.Clients.All.methodInJavascript("hello world"); 
    // or 
    context.Clients.Group("groupname").methodInJavascript("hello world"); 
} 

vb.net

Public Function MyControllerMethod() As ActionResult 
    Dim context = GlobalHost.ConnectionManager.GetHubContext(Of MyHub)() 
    context.Clients.All.methodInJavascript("hello world") 
    '' or 
    context.Clients.Group("groupname").methodInJavascript("hello world") 
End Function 

cập nhật

Mã này đã được cập nhật. Theo dõi http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server để biết các thay đổi.

Nếu bạn đang sử dụng DI chứa

Nếu bạn đang sử dụng một container DI để dây lên trung tâm của bạn, nhận IConnectionManager từ container của bạn, và gọi GetHubContext trên connectionManager đó.

+0

Hoạt động tuyệt vời! :) Giải quyết vấn đề của tôi. Tôi gặp vấn đề nghiêm trọng với một đoạn mã tôi nhận được ở đây: http://www.xhroot.com/blog/2012/07/12/live-updates-using-signalr/ –

+0

* Điều này không có nghĩa là chúng phải là xuống bình chọn khi chúng đã chính xác tại thời điểm viết *? Chắc chắn họ nên được downvoted nếu họ không chính xác nữa? – Liam

+0

Lý tưởng nhất là Thẻ nên là phiên bản cụ thể cho độ chính xác lịch sử. –

8

đã cập nhật: Câu trả lời này cũng cũ! API công cộng của SignalR là thông lượng liên tục, có vẻ như vậy. Tim B James có cách sử dụng API mới, thích hợp kể từ tháng 7 năm 2012.

Câu trả lời hiện tại được chấp nhận từ Mike cũ và không còn hoạt động với phiên bản SignalR mới nhất.

Dưới đây là một phiên bản cập nhật cho thấy làm thế nào để gửi một thông điệp tới một trung tâm từ một hành động điều khiển MVC:

public ActionResult MyControllerMethod() 
{ 
    // Important: .Resolve is an extension method inside SignalR.Infrastructure namespace. 
    var connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>(); 
    var clients = connectionManager.GetClients<MyHub>(); 

    // Broadcast to all clients. 
    clients.MethodOnTheJavascript("Good news!"); 

    // Broadcast only to clients in a group. 
    clients["someGroupName"].MethodOnTheJavascript("Hello, some group!"); 

    // Broadcast only to a particular client. 
    clients["someConnectionId"].MethodOnTheJavascript("Hello, particular client!"); 
} 
+0

Như một lưu ý cho bất kỳ ai đang cố gắng điều này, có vẻ như các phương pháp này không còn khả dụng nữa. +1 cho Tim để cập nhật theo cách mới. Có vẻ như đây là thông tin rất nhiều. –

+0

Tôi đang bối rối. Không phải là phần 'AspNetHost' là 0,4 và không phải là phiên bản hiện tại (hiện tại là 0,5.2). Điều này không phù hợp với tôi –

+0

Bạn đã đọc bản cập nhật ở trên cùng chưa? API này cũng đã không được chấp nhận. Xin đọc câu trả lời của Tim B James. –

38

2018 Tháng Hai, ngắn và giải pháp đơn giản

Đối với việc giải quyết này, tôi thường thiết kế trung tâm của tôi theo cách sau:

public class NewsFeedHub : Hub 
{ 
    private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NewsFeedHub>(); 

    // Call this from JS: hub.client.send(channel, content) 
    public void Send(string channel, string content) 
    { 
     Clients.Group(channel).addMessage(content); 
    } 

    // Call this from C#: NewsFeedHub.Static_Send(channel, content) 
    public static void Static_Send(string channel, string content) 
    { 
     hubContext.Clients.Group(channel).addMessage(content); 
    } 

} 

Vì vậy, thật dễ dàng để gọi từ javascript và từ mã back-end cũng. Hai phương thức là kết quả trong cùng một sự kiện tại máy khách.

+1

Tháng 8 năm 2016, chỉ thay đổi tôi phải làm là: Khách hàng [kênh] -> Khách hàng.Group (kênh) –

+1

Đây là giải pháp tốt nhất và hiệu quả nhất mà tôi đã gặp, đó là mã có thể tái sử dụng và hoạt động hoàn hảo. –

+0

Phương pháp tĩnh không hoạt động đối với tôi. Tôi gỡ lỗi và bước qua nó, nó cố gắng gửi JavaScript, nhưng không có gì xảy ra. Tuy nhiên, phương thức thông thường, không tĩnh làm việc giống hệt nhau. Vấn đề là tôi không thể gọi nó từ Web API, điều tôi đang cố gắng làm. Ý tưởng? EDIT: điều này có thể khủng khiếp, nhưng trong phương pháp không tĩnh của tôi, tôi lưu "Khách hàng" thành biến tĩnh riêng tư (của IHubConnectionContext ) và sau đó gọi nó theo phương pháp tĩnh của tôi. Làm việc, nhưng ... không cảm thấy đúng. – vbullinger

1

Tiếp theo từ câu trả lời DDan của bạn có thể tạo một phương pháp tĩnh quá tải và giữ logic thông thường trong một phương pháp - Tôi sử dụng mô hình này

public class ChatHub : Hub 
{ 
    private static IHubConnectionContext<dynamic> GetClients(ChatHub chatHub) 
    { 
     if (chatHub == null) 
      return GlobalHost.ConnectionManager.GetHubContext<ChatHub>().Clients; 
     else 
      return chatHub.Clients; 
    } 

    // Call from JavaScript 
    public void Send(string message) 
    { 
     Send(message, this); 
    } 

    // Call from C# eg: Hubs.ChatHub.Send(message, null); 
    public static void Send(string message, ChatHub chatHub) 
    { 
     IHubConnectionContext<dynamic> clients = GetClients(chatHub); 
     // common logic goes here 
     clients.All.receiveSend(message); 
    } 
} 

Sau đó từ bộ điều khiển của bạn, bạn có thể sử dụng

Hubs.ChatHub.Send(arg1, null);