2017-10-12 8 views
0

Nous avions une solution pour envoyer un fichier à l'aide de client SignalR .Net Nous avons déménagé à .Net de base En solution précédente .net, nous utilisé pour contexte Hub via GlobalHost.ConnectionManagercomment envoyer un fichier binaire au client SignalR du serveur dans le noyau dotnet

var myHub = GlobalHost.ConnectionManager.GetHubContext<MyHub>(); 
myHub.Clients.Client(connectionId).doStuffWithFile(fileByteArray, fileName); 

où dans le côté client, fonction doStuffWithFile serait déclenchée avec les deux arguments.

Dans nouvelle solution .Net Core J'ai créé une classe Hub en dérivant de Hub. J'ai ajouté une méthode d'envoi pour envoyer un fichier au client spécifique et non la diffusion à tous

public class MyHub : Hub 
{ 
    private static string _connectionId;  

    public override Task OnConnectedAsync() 
    { 
     _connectionId = Context.ConnectionId; 
     return Task.CompletedTask; 
    } 

    public override Task OnDisconnectedAsync(Exception exception) 
    { 
     _connectionId = Context.ConnectionId; 

     //// remove Connection Id 
     return base.OnDisconnectedAsync(exception); 
    } 

    public async Task Send(byte[] fileByteArray, string fileName) 
    { 
     await Clients.Client(_connectionId).InvokeAsync("doStuff", fileByteArray, fileName); 
    } 
} 

Cependant, je ne dispose d'aucun mécanisme dans le noyau .Net, comme GlobalHost ou ConnectionManager pour obtenir HubContext pour envoyer le fichier.

Du côté client:

static void Main(string[] args) 
     { 
      var connection = new HubConnectionBuilder() 
       .WithUrl("http://localhost:25786/file") 
       .WithConsoleLogger() 
       .Build(); 
      connection.On<byte[], string>("doStuff", DoStuff); 

      connection.StartAsync().ContinueWith(
       task => 
       { 
        if (task.IsFaulted) 
        { 
         Console.WriteLine("Connection faulty"); 
        } 
       }); 

      Console.ReadLine(); 
} 
private static void DoStuff(byte[] data, string name) 
{ 
    File.WriteAllBytes(@"c:\Projects\" + name, data); 
} 

J'ai essayé de créer une nouvelle instance de MyHub pour appeler la méthode Send, mais simplement ça ne marche pas. Pourriez-vous s'il vous plaît me conseiller comment faire cela?

+0

Copie possible de https://stackoverflow.com/questions/46332651/signalr-call-client-methods-from-outside-the-hub-class-aspnetcore – Pawel

Répondre

1

Ceci n'est pas une réponse directe à votre question mais j'espère que cela vous aidera à trouver une solution.

Le stockage de l'ID de connexion dans une variable de classe statique est incorrect. Il changera chaque fois qu'un nouveau client se connecte et vous n'aurez aucun contrôle sur le client auquel vous envoyez. À partir du code que vous avez fourni, il n'est pas clair comment vous savez à quel client envoyer le fichier. Notez que vous définissez également le lorsque le client est déconnecté. Il est donc probable que vous essaierez d'envoyer des données à la connexion dont vous savez qu'elle a été fermée. Je pense réellement que vous voulez passer l'ID de connexion cible ou l'utilisateur à la méthode du concentrateur Send. Je pense que vous n'avez peut-être pas assez de contexte dans la méthode de concentrateur pour résoudre l'ID de connexion, mais comme l'ID de connexion est un concept SignalR, il peut être difficile d'y accéder en dehors des composants SignalR. C'est pourquoi il peut être plus facile d'utiliser l'utilisateur à la place de l'ID de connexion (c'est-à-dire Clients.User(...) au lieu de Clients.Client(...)).

GlobalHost n'existe plus dans le nouveau SignalR. Au lieu de cela, vous pouvez injecter IHubContext<THub> à la classe dont vous voulez appeler la méthode et utiliser InvokeAsync. Here est un exemple d'invocation d'une méthode de concentrateur à partir d'un contrôleur Mvc.

+0

Merci beaucoup, mon problème était d'obtenir HubContext qui maintenant Je peux passer à travers DI comme mentionné dans l'exemple. C'était vraiment utile. –