For ease of reference I’m going to talk about 2 services here, A and B. I’m assuming A wants the data and B has the data.
The MSRS model really provides 2 methods for A to get data from B. The most-used version is a publish-subscribe model where A subscribes to changes in B. When a change occurs a message is sent to A with the state of B.
The second model is for service A to send a GET message to service B. The reply to this message will be the entire state of service B.
I’ll give an example for publish/subscribe. Big disclaimer: I’ve done this many times but the code fragments here are just for examples. They might compile directly.
The first thing you need to do near the top of the class is establish ports to the partner service. This can be done statically like this or via communication with the directory service to look them up. There are 2 ports; one is used to communicate to the service and the other is to receive the subscription responses.
[Partner("ServiceB", Contract = serviceB.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
serviceB.ServiceBOperations _serviceBPort = new serviceB.ServiceBOperations();
serviceB.ServiceBOperations _serviceBNotify = new serviceB.ServiceBOperations();
Further down in the code (this can be done in Start() or somewhere else after the constructor is run) we send a subscribe message to service B. This tells it to send us any changes in the service’s state.
Arbiter.Choice(
_serviceBPort.Subscribe(_gameControllerNotify),
delegate(SubscribeResponseType response) { },
delegate(Fault fault) { LogError(fault); }
);
Once the subscription is performed you need to enable a handler to receive notifications when a change has occurred. This example shows it in the concurrent receive group so other messages could be handled at the same time. If this is a problem you can move it up to the exclusive section where only one message at a time will be handled.
Activate(Arbiter.Interleave(
new TeardownReceiverGroup
( // we have no interleaved handlers
),
new ExclusiveReceiverGroup
(
// we have no exclusive handlers
),
new ConcurrentReceiverGroup
(
Arbiter.ReceiveWithIterator<serviceB.Replace>(true, _serviceBNotify, ServiceBReplaceHandler)
)
));
Now we need the actual handler for the message:
public IEnumerator<ITask> ServiceBReplaceHandler(serviceB.Replace replace)
{
// do whatever you wish with the contents of replace.Body
yield break;
}
That’s all it takes for subscription.
Now, performing the GET is a bit different. In this case you format up a GET message:
serviceB.get getRequest = new serviceB.get(new GetRequestType());
Then send it to the service:
_serviceBPort.Post(getRequest);
Then you need to wait for the response. The wait will occur in a separate thread so you can continue operating.
Activate(
Arbiter.Choice(getRequest.ResponsePort,
delegate(serviceB.ServiceBState response)
{
// handle the data back from service B
},
delegate(Fault fault)
{
LogError("Request for service B state failed.");
})
);
When the delegate is invoked it will have as the variable “response” the entire state of the service.
Hope that helps!