2015-05-20 73 views
8

Tôi đã thử nghiệm với SignalR hôm nay và nó thực sự gọn gàng. Về cơ bản những gì tôi muốn đạt được là:SignalR - Gửi tin nhắn OnConnected

Ngay sau khi thiết bị kết nối nó sẽ gửi một tin nhắn cho người đầu tiên. Nếu có nhiều thiết bị hơn 1 kết nối, tôi muốn gửi hai tin nhắn. Một đến tất cả ngoại trừ khách hàng được kết nối cuối cùng. Và một thông báo đến chỉ khách hàng được kết nối mới nhất.

Mã tôi đã sử dụng hoạt động hoàn hảo khi tôi đặt nó trong bộ điều khiển API tùy chỉnh và về cơ bản gọi hành động, nhưng đó không phải là điều tôi muốn.

Tôi muốn gửi tin nhắn ngay khi thiết bị kết nối trong phạm vi OnConnected mà không có bất kỳ tương tác người dùng nào, nhưng khi tôi đặt mã của mình bên trong ghi đè OnConnected thì nó ngừng hoạt động. Nó không gửi đến các máy khách cụ thể nữa (lần đầu tiên được kết nối và kết nối lần cuối).

Tôi hy vọng một người nào đó có thể giúp tôi với điều này, bởi vì tôi đã đập đầu của tôi trong một vài giờ ngay bây giờ.

public override System.Threading.Tasks.Task OnConnected() 
    { 
     UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1); 

     int amountOfConnections = UserHandler.ConnectedIds.Count; 
     var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault(); 
     var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList(); 

     if (amountOfConnections == 1) 
     { 
      Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one"); 
     } 
     else 
     { 
      Clients.Clients(allExceptLast).hello("Send to everyone except last"); 
      Clients.Client(lastConnection.Key).hello("Send to only the last one"); 
     } 

     return base.OnConnected(); 
    } 

Trả lời

4

Cảm ơn tất cả sự giúp đỡ (các bạn đã upvoted). Trên thực tế tìm thấy vấn đề .. nó đã được bên trong khách hàng của tôi. Lần đầu tiên tôi đăng ký chức năng 'hello' và sau đó tôi bắt đầu HubConnection. Ngay khi tôi thay đổi thứ tự này, mọi thứ đều ổn.

Nó làm việc với mã khách hàng như sau:

private async Task ConnectToSignalR() 
    { 
     var hubConnection = new HubConnection("url"); 
     hubConnection.Headers["x-zumo-application"] = "clientapikey"; 

     IHubProxy proxy = hubConnection.CreateHubProxy("ChatHub"); 

     proxy.On<string>("hello", async (msg) => 
     { 
      Console.WriteLine(msg); 
     }); 

     await hubConnection.Start(); 
    } 
1

cũng ... bạn đang trở về một nhiệm vụ ... vì vậy tôi nghĩ rằng có thể vấn đề này ... trước tiên bạn cần thực thi mã của bạn và sau đó trở về nhiệm vụ ... hoặc đặt một ContinueWith. .. như ...

public override Task OnConnected() 
    { 
     Task task = new Task(() => 
      { 
       UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1); 

       int amountOfConnections = UserHandler.ConnectedIds.Count; 
       var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault(); 
       var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList(); 

       if (amountOfConnections == 1) 
       { 
        Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one"); 
       } 
       else 
       { 
        Clients.Clients(allExceptLast).hello("Send to everyone except last"); 
        Clients.Client(lastConnection.Key).hello("Send to only the last one"); 
       } 
      }); 

     task.ContinueWith(base.OnConnected()); 

     return task; 
    } 

tôi đã không kiểm tra đó ... nó chỉ là một phỏng đoán ..

3

Vì bạn chưa thiết lập một kết nối nào, cố gắng để gọi chức năng khách hàng của bạn trong vòng .hello()OnConnected không thể thực hiện tại thời điểm này. Tuy nhiên, chúng tôi có thể xác định phương thức trung tâm máy chủ và ngay lập tức gọi khi kết nối của chúng tôi gọi lại số .done. Sau đó, trong phương thức máy chủ mới của chúng tôi, chúng tôi có thể phân bổ lại logic mà bạn hiện có trong OnConnected.

này sẽ thay đổi thiết lập của chúng tôi khá một chút và giới thiệu một số bước bổ sung, nhưng quan sát ví dụ sau ...

// WhateverHub 
public override Task OnConnected() 
{ 
    return base.OnConnected() 
} 

public void AfterConnected() 
{ 
    // if(stuff) -- whatever if/else first user/last user logic 
    // { 
     Clients.Caller.hello("message") 
    // } 
} 

var proxy= $.connection.whateverHub; 

proxy.client.hello = function(message) { 
    // last step in event chain 
} 

$.connection.hub.start().done(function() { 
    proxy.server.afterConnected() // call AfterConnected() on hub 
}); 

Vì vậy, ý tưởng cơ bản ở đây là đầu tiên

  1. Kết nối =>.done(function() { ... });
  2. Gọi server.afterConnected()
  3. Execute logic trong phương pháp
  4. rằng Nếu chúng tôi hài lòng với điều kiện gọi hàm .hello() khách hàng của chúng tôi

Note - thực hiện này là dành cho một khách hàng JavaScript - nhưng ý tưởng tương tự có thể được dịch sang ứng dụng .net. Đây chủ yếu là một vấn đề kiến ​​trúc.

10

Trừ khi tôi nhớ một cái gì đó từ câu hỏi của bạn, giải pháp trông khá đơn giản với tôi, bạn chỉ cần chuyển sang sử dụng

Clients.Caller.hello("Send to only the last one"); 

thay vì cố gắng để hiểu chính mình ai là id kết nối cuối cùng. Tương tự cho những người khác, bạn có thể sử dụng:

Clients.Others.hello("Send to everyone except last"); 

Bạn không cần phải tất cả các logic bạn thiết lập, những 2 dây chuyền làm những gì bạn cần, và họ làm việc bên trong OnConnected.

+0

thanks a lot cho mã này. Nó thực sự làm cho mã của tôi dễ dàng hơn rất nhiều! – Mittchel

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