2017-03-06 3 views
2

Ich habe in den letzten Wochen von Cloud Services auf Service Fabric umgestellt und bin mit Remoting zwischen zwei Diensten in einige Stolpersteine ​​geraten.Service Fabric Service Remoting

Ich habe mit der offiziellen Dokumentation und Beispielcode auf Service-Remoting- und insbesondere ich versuche, die Probe, hier zu arbeiten skizzierte zu erhalten:

https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting

Ich habe 2 Dienstleistungen. Eine heißt "RemoteService" und die andere heißt "CallerService". Beide stammen aus einem Standard-Stateless-Service-Projekt.

Sowohl in der „Remoteservice“ und „CallerService“ Projekte, die ich die folgende Schnittstelle hinzugefügt haben den Dienstvertrag zwischen ihnen zu beschreiben:

public interface IMyService : IService 
{ 
    Task<string> HelloNameAsync(string name); 
} 

Im „Remoteservice“ Ich habe erstellt asociated Methode innerhalb der Klasse Remoteservice

public Task<string> HelloNameAsync(string name) 
{ 
    return Task.FromResult("Hello " + name + "!"); 
} 

I außer Kraft setzen auch CreateServiceInstanceListeners mit den folgenden

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() 
{ 
    return new[] { new ServiceInstanceListener(context => this.CreateServiceRemotingListener(context)) }; 
} 

In meinem "CallerService" wenn ich versuche, den Aufruf der "Remoteservice" zu verbinden, machen mit den folgenden:

IMyService helloNameClient = ServiceProxy.Create<IMyService>(new Uri("fabric:/Application/RemoteService")); 
string message = await helloNameClient.HelloNameAsync("Luke"); 

Ich erhalte diese Ausnahme

InnerException = {"Interface id '1994370306' is not implemented by object 'RemoteService.RemoteService'"} 

Ich bin über diese Probe mit einem feinen Zahnkamm gegangen und bin sicher, dass ich alles habe n Platz wie es sein sollte. Ich habe über das Einrichten von Endpunkten und das Registrieren Ihrer Dienste in einem Dienstverzeichnis gelesen, aber von dem, was ich verstehe, sind diese für externe Dienste und die Remoting-Dokumentation erwähnt dies nicht erforderlich.

UPDATE:

Hier ist, wie die Remoteservice Klasse deklariert ist:

internal sealed class RemoteService : StatelessService, IMyService 

UPDATE 2

Hier ist, was die Settings.xml wie für beide Dienste aussieht. Dies sind die Standardeinstellungen, die mit dem Projekt aus der Box kommen. Ich habe nichts hinzugefügt oder entfernt. Ich möchte auch anmerken, dass ich all dies auf meiner lokalen Service-Struktur laufen lasse.

<?xml version="1.0" encoding="utf-8" ?> 
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric"> 
    <!-- Add your custom configuration sections and parameters here --> 
    <!-- 
    <Section Name="MyConfigSection"> 
    <Parameter Name="MyParameter" Value="Value1" /> 
    </Section> 
    --> 
</Settings> 
+0

Können wir sehen, wie Sie die RemoteService-Klasse deklariert haben? Auch Settings.xml für beide Dienste. – cassandrad

+0

Ja, ich habe gerade ein Update hinzugefügt. – CodeAbundance

+0

Die Datei Settings.xml wurde ebenfalls hinzugefügt. – CodeAbundance

Antwort

4

Die Montage der Service-Schnittstelle in Bedürfnisse deklariert wird mit dem Kunden geteilt werden, können Sie nicht eine identische Schnittstelle auf der Client-Seite neu zu erstellen. Wenn Service Fabric die Kommunikation einrichtet, erstellt es eine Zuordnung der Schnittstelle und ihrer Methoden aus der tatsächlichen vom Dienst verwendeten Assembly.

Basierend auf Ihrer Beschreibung, es sieht aus wie Sie eine identische Schnittstelle sowohl in Service und Client-Projekt deklarieren? Wenn ja, dann ist dies die Lösung.

Von SO: Calling services from other application in the cluster: Der einzige knifflige Teil ist, wie Sie die Schnittstelle vom externen Dienst zu Ihrem Anrufdienst erhalten? Sie können einfach auf die integrierte EXE-Datei für den Service verweisen, den Sie aufrufen möchten, oder Sie können die Assembly, die die Schnittstelle enthält, als NuGet-Paket verpacken und einen privaten Feed einrichten.

Wenn Sie dies nicht tun, und Sie stattdessen einfach den Code zwischen Ihrem Visual Studio-Lösungen teilen sich die Service-Fabric denken das sind zwei verschiedene Schnittstellen, auch wenn sie genau die gleiche Unterschrift teilen. Wenn Sie dies für einen Service tun, erhalten Sie einen NotImplementedException-Spruch "Interface id '{xxxxxxxx}' wird nicht durch das Objekt '{service}'" implementiert und wenn Sie dies für einen Actor tun, erhalten Sie eine KeyNotfoundException mit dem Hinweis "No MethodDispatcher is found for Schnittstellen-ID '- {xxxxxxxxxx}' ".

Also, Ihr Problem zu beheben, stellen Sie sicher, dass Sie die gleiche Assembly verweisen, die in der Anwendung ist, dass Sie in der externen Anwendung aufgerufen werden sollen, die anruft.

+0

Danke das war es! Da beide Dienste in derselben Lösung sind, habe ich eine gemeinsame Bibliothek für das Interface erstellt. – CodeAbundance