2015-05-20 3 views
8

Я экспериментировал с SignalR сегодня, и это действительно опрятно. В основном, чего я хотел достичь, является следующее:SignalR - Отправить сообщение OnConnected

Как только устройство подключается, оно должно отправить сообщение первому. Если есть больше устройств, чем 1 подключено, я бы хотел отправить два сообщения. Один для всех за исключением последнего подключенного клиента. И одно сообщение для только последний подключенный клиент.

Код, который я использовал, отлично работает, когда я помещаю его в пользовательский контроллер API и в основном вызываю действие, но это не то, что я хочу.

Я бы хотел послать сообщения, как только устройство подключится в пределах OnConnected без какого-либо взаимодействия с пользователем, но когда я помещаю свой код внутри OnConnected, он перестает работать. Он больше не отправляет конкретным клиентам (первый подключенный и последний подключенный).

Я надеюсь, что кто-то сможет мне помочь, потому что я уже несколько часов стучал головой.

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(); 
    } 

ответ

4

Благодарим за помощь (при поддержке вас, ребята). На самом деле проблема нашла. Это было внутри моего клиента. Я сначала подписался на функцию «привет», а затем начал HubConnection. Как только я изменил этот порядок, все сработало нормально.

Он работал со следующим кодом клиента:

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

хорошо ... Вы возвращаете задачу ... поэтому я думаю, что может быть проблема ... сначала вы должны выполнить свой код, а затем вернуть задание ... или поставить ContinueWith. .. как ...

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; 
    } 

Я не проверял, что ... его просто догадка ..

3

Поскольку вы не установили связь еще, пытается вызвать вашу функцию клиента .hello() в OnConnected невозможно в этом пункте. Тем не менее, мы можем определить метод серверного хаба и немедленно вызвать это при нашем обращении к вызову .done. Затем в нашем новом методе сервера мы можем перераспределить используемую вами логику в OnConnected.

Это изменит нашу установку совсем немного, и ввести некоторые дополнительные шаги, но наблюдать следующий пример ...

// 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 
}); 

Так основная идея здесь заключается в первую

  1. Подключиться =>.done(function() { ... });
  2. Звоните server.afterConnected()
  3. Выполнение логики в этом методе
  4. Если мы удовлетворены условия требуют наша функция .hello() клиента

Примечание - это реализация для клиента JavaScript - но та же идея может быть переведенным в .net-клиент. Это в основном архитектурная проблема.

10

Если я не пропустить что-то из вашего вопроса, решение выглядит довольно просто мне нужно просто переключиться на использование

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

вместо того, чтобы пытаться понять себя, кто последний подключенный идентификатор. То же самое для других, вы можете использовать:

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

Вам не нужно всю логику вы настроите эти 2 линии делать то, что вам нужно, и они работают в OnConnected.

+0

спасибо много для этого кода. Это делает мой код намного проще! – Mittchel

Смежные вопросы