Ik ben een pub/sub mechanisme aan het bouwen in WCF. Ik heb een basis voor een architectuur staan maar vraag me af of dit "the way to do it" is of dat er betere oplossingen bestaan.
Het doel van het systeem is alsvolgt: er zijn een hoop clients die verbinding maken met een centrale server. Een client moet events kunnen publishen en andere clients moeten zich kunnen subscriben. Dit is nog allemaal makkelijk te verwezenlijken en er is hierover op msdn zelfs een voorbeeld van de patterns en practices group (http://msdn.microsoft.com/en-us/library/ms752254.aspx). Het wordt echter wat complexer in mijn situatie omdat de clients in groepen onder te verdelen zijn, en iedere client die zich subscribed op een bepaald event wil alleen geinformeerd worden als dat event wordt gefired wordt door een andere client van zijn eigen groep. Hier is waar het pattern van ms failed want zij gebruiken een static event in de service. Ik kan dit pattern gaan misbruiken maar dan kom ik meteen een paar nasty dingen tegen:
1. Ik moet dan in de event args gaan opnemen voor welke group clients dit event getriggered wordt. Dus als ik 300 clients heb en het event is maar voor 3 clients bedoeld gaan er 297 handlers voor niks af in de service.
2. Alle clients moeten automatisch hetzelfde contract implementeren omdat ze allemaal naar dezelfde service connecten. In mijn situatie heb ik clients met verschillende contracten die echter toch naar dezelfde events luisteren. Ik moet dan alle contracten mergen in 1 contract en iedere client heeft nu een berg functies tot zijn beschikking die eigenlijk niet van toepassing zijn voor hem.
3. Er is geen enkele manier om state te persisten. De clients slaan een reference naar de callback op, maar als de server een keer plat gaat is al die state verloren en kan die alleen door de clients zelf weer opnieuw geinitieerd worden.
Al met al leek me dit niet ideaal dus heb ik het anders opgelost. Iedere client connect met een service en houdt een sessie aan met die service (over een NetTcpBinding). De service slaat dan weer een reference naar de callback op (tot aan hier is alles dus nog hetzelfde als het p&p voorbeeld van ms), evenals de groep waarbij de client behoort en een uniek id van de client. Daarnaast heb ik een extra service in het leven geroepen die de events routeert. De instances van de andere services kunnen dan subscriben, unsubscriben en events publishen via deze eventing service die dan weer bepaald welke call bij wie geinvoked moet worden.
Wat ik me afvraag is of ik goed omga met de instancing modes van de services. De clients die met hun services verbinding houden moeten dit in een sessie doen. De eventing service moet een singleton zijn. De event receivers op de andere services moet ik ook een singleton maken omdat dat de engie manier is om het event ook bij dezelfde instance te ontvangen i.p.v. dat er een nieuwe wordt gespawned (met de parameterless constructor, en waarbij ik dus geen referentie naar het callback channel van de client heb). Ik heb dus een service, met een InstanceContextMode die PerSession is, die vervolgens weer een child object heeft (de event receiver) die een InstanceContextMode Single heeft.
Is dit design-technisch gezien een nette oplossing wat ik hier heb of is er iets beters te verzinnen? (Ik heb 1 vertical slice geprogrammeerd als PoC en dat werkt prima overigens)
Het doel van het systeem is alsvolgt: er zijn een hoop clients die verbinding maken met een centrale server. Een client moet events kunnen publishen en andere clients moeten zich kunnen subscriben. Dit is nog allemaal makkelijk te verwezenlijken en er is hierover op msdn zelfs een voorbeeld van de patterns en practices group (http://msdn.microsoft.com/en-us/library/ms752254.aspx). Het wordt echter wat complexer in mijn situatie omdat de clients in groepen onder te verdelen zijn, en iedere client die zich subscribed op een bepaald event wil alleen geinformeerd worden als dat event wordt gefired wordt door een andere client van zijn eigen groep. Hier is waar het pattern van ms failed want zij gebruiken een static event in de service. Ik kan dit pattern gaan misbruiken maar dan kom ik meteen een paar nasty dingen tegen:
1. Ik moet dan in de event args gaan opnemen voor welke group clients dit event getriggered wordt. Dus als ik 300 clients heb en het event is maar voor 3 clients bedoeld gaan er 297 handlers voor niks af in de service.
2. Alle clients moeten automatisch hetzelfde contract implementeren omdat ze allemaal naar dezelfde service connecten. In mijn situatie heb ik clients met verschillende contracten die echter toch naar dezelfde events luisteren. Ik moet dan alle contracten mergen in 1 contract en iedere client heeft nu een berg functies tot zijn beschikking die eigenlijk niet van toepassing zijn voor hem.
3. Er is geen enkele manier om state te persisten. De clients slaan een reference naar de callback op, maar als de server een keer plat gaat is al die state verloren en kan die alleen door de clients zelf weer opnieuw geinitieerd worden.
Al met al leek me dit niet ideaal dus heb ik het anders opgelost. Iedere client connect met een service en houdt een sessie aan met die service (over een NetTcpBinding). De service slaat dan weer een reference naar de callback op (tot aan hier is alles dus nog hetzelfde als het p&p voorbeeld van ms), evenals de groep waarbij de client behoort en een uniek id van de client. Daarnaast heb ik een extra service in het leven geroepen die de events routeert. De instances van de andere services kunnen dan subscriben, unsubscriben en events publishen via deze eventing service die dan weer bepaald welke call bij wie geinvoked moet worden.
Wat ik me afvraag is of ik goed omga met de instancing modes van de services. De clients die met hun services verbinding houden moeten dit in een sessie doen. De eventing service moet een singleton zijn. De event receivers op de andere services moet ik ook een singleton maken omdat dat de engie manier is om het event ook bij dezelfde instance te ontvangen i.p.v. dat er een nieuwe wordt gespawned (met de parameterless constructor, en waarbij ik dus geen referentie naar het callback channel van de client heb). Ik heb dus een service, met een InstanceContextMode die PerSession is, die vervolgens weer een child object heeft (de event receiver) die een InstanceContextMode Single heeft.
Is dit design-technisch gezien een nette oplossing wat ik hier heb of is er iets beters te verzinnen? (Ik heb 1 vertical slice geprogrammeerd als PoC en dat werkt prima overigens)