2017-02-02 5 views
1

Ich habe Probleme mit Ereignissen in meiner Servicestack-Anwendung. Ich erstelle eine SOA-Anwendung basierend auf ServiceStack. Ich hatte kein Problem damit, einen einfachen GET/POST Manager innerhalb des Hosts zu erstellen. Nun möchte Ich mag Ereignisse hinzufügenIch kann keine Ereignisse vom Server in ServiceStack empfangen

Ich verwende ein Beispiel versucht, aber das Ereignis wird vom Client nicht empfangen

Hat jemand eine Idee davon haben?

Das ist mein Server:

ServiceStack.Text.JsConfig.EmitCamelCaseNames = true; 

ServerEventsFeature serverEventsFeature = new ServerEventsFeature() 
{ 
    LimitToAuthenticatedUsers = false, 
    NotifyChannelOfSubscriptions = true, 
    OnPublish = (res, msg) => 
    { 
     //fired after ever message is published 
     res.Write("\n\n\n\n\n\n\n\n\n\n"); 
     res.Flush(); 
    }, 
    OnConnect = (eventSubscription, dictionary) => 
    { 
    }, 
    OnSubscribe = (eventSubscription) => 
    { 
    } 
}; 
Plugins.Add(serverEventsFeature); 

container.Register<IServerEvents>(c => new MemoryServerEvents()); 
container.Register(c => new FrontendMessages(c.Resolve<IServerEvents>())); 
container.Register<IWebServiceEventManager>(c => new WebServiceEventManager(DeviceManager, macroManager)); 

SetConfig(new HostConfig 
{ 
    DefaultContentType = MimeTypes.Json, 
    EnableFeatures = Feature.All.Remove(Feature.Html), 
}); 

public class FrontendMessage 
{ 
    public string Level { get; set; } 
    public string Message { get; set; } 
} 

public class FrontendMessages 
{ 
    private readonly IServerEvents _serverEvents; 
    private Timer _timer; 

    public FrontendMessages(IServerEvents serverEvents) 
    { 
     if (serverEvents == null) throw new ArgumentNullException(nameof(serverEvents)); 
     _serverEvents = serverEvents;    
    } 

    public void Start() 
    { 
     var ticks = 0; 
     _timer = new Timer(_ => { 
      Info($"Tick {ticks++}"); 
      _timer.Change(500, Timeout.Infinite); 
     }, null, 500, Timeout.Infinite); 
    } 

    public void Info(string message, params object[] parameters) 
    { 
     var frontendMessage = new FrontendMessage 
     { 
      Level = "success", 
      Message = message 
     }; 

     Console.WriteLine("Sending message: " + frontendMessage.Message); 
     _serverEvents.NotifyChannel("messages", frontendMessage); 
    } 

Dies ist mein Kunde:

public async void Connect() 
{ 
    try 
    { 
     Task.Delay(2000).Wait(); 
     clientEvents = new ServerEventsClient("http://127.0.0.1:20001/", "messages"); 
     clientEvents.OnConnect = (msg) => 
     { 
     }; 

     clientEvents.OnHeartbeat =() => 
     { 

     }; 
     clientEvents.OnCommand = (msg) => 
     { 

     }; 
     clientEvents.OnException = (msg) => 
     { 

     }; 
     clientEvents.OnMessage = (msg) => 
     { 

     }; 
     Dictionary<string, ServerEventCallback> handlers = new Dictionary<string, ServerEventCallback>(); 
     handlers.Add("messages", (client, msg) => 
     { 

     }); 
     clientEvents.RegisterHandlers(handlers); 

     await clientEvents.Connect(); 
     client = (IServiceClient)(clientEvents.ServiceClient); 
    } 
    catch (Exception e) 
    { 
    } 
} 

Antwort

2

Ich würde zuerst looking at ServerEvents Examples und die docs for the C# ServerEventsClient Beispiele für Arbeitskonfigurationen empfehlen.

Ihre zusätzliche ServerEventsFeature Konfiguration ist nicht sinnvoll, da Sie nur die Standardwerte angeben und der neue Zeilenhack Publish() nicht benötigt wird, wenn Sie disable buffering in ASP.NET. So würde ich es ändern:

Plugins.Add(new ServerEventsFeature()); 

zweites Problem ist, dass Sie die Verwendung von Message Event handlers falsch ist, C# ServerEventsClient ist bereits mit dem messages Kanal. Ihre Handler werden verwendet, um auf Nachrichten zu hören, die an den Selektor cmd.* gesendet werden (z. B. cmd.FrontendMessage).

Da Sie ein DTO zu einem Kanal sind zu veröffentlichen, das heißt:

_serverEvents.NotifyChannel("messages", frontendMessage); 

Sie können eine Global Receiver verwenden es zu handhaben, z:

public class GlobalReceiver : ServerEventReceiver 
{ 
    public void Any(FrontendMessage request) 
    { 
     ... 
    } 
} 

client.RegisterReceiver<GlobalReceiver>(); 
+0

Danke. Ich versuche es! –

0

Dank mythz! Es funktioniert korrekt.

Der nächste Schritt besteht darin, das gleiche Verhalten auf Javascript-Client (Ereignisse und Get/Post-Anfrage) zu replizieren. Hast du etwas, das ich vorschlagen kann?

Vielen Dank! Leo

Verwandte Themen