/// <summary> /// Receive request context from frontend and send request to service host /// </summary> /// <param name="request">indicating the request message</param> /// <param name="callback">indicating the callback</param> public void ReceiveRequest(Message request, IDuplexCallbackService callback) { // Try to get a dispatcher from the dispatcher list // Put the loadbalancing logic here to choose a service host for dispatching messages Dispatcher dispatcher; while (true) { if (this.dispatcherList.Count > 0) { lock (this.dispatcherList) { if (this.dispatcherList.Count > 0) { // Randomly choose a service client as a sample dispatching tacitc Random r = new Random(); int index = r.Next(this.dispatcherList.Count); dispatcher = this.dispatcherList.Values[index]; break; } } } // Sleep 1 second to wait for service host ready Thread.Sleep(1000); } dispatcher.ProcessRequest(request, callback); }
/// <summary> /// Callback raised when response is received /// </summary> /// <param name="result">indicating the async result</param> private void ReceiveResponse(IAsyncResult result) { object[] objArr = result.AsyncState as object[]; UniqueId messageId = objArr[0] as UniqueId; IDuplexCallbackService callback = objArr[1] as IDuplexCallbackService; Message response; try { lock (this.client) { response = this.client.EndProcessMessage(result); } } catch (Exception e) { // Communication/Timeout/EndpointNotFound exception could throw here // Build fault message instead and send back to client Trace.TraceError("[ServiceClientManager] Failed to process the message: {0}", e); response = this.BuildFaultMessage(messageId, e); } try { // Send back response to client side callback.SendResponse(response); } catch (Exception e) { // Failed to send response // Swallow the exception and log it Trace.TraceError("[ServiceClientManager] Failed to send back response: {0}", e); } }
/// <summary> /// Process request /// </summary> /// <param name="request">indicating the request message</param> /// <param name="callback">indicating the callback</param> public void ProcessRequest(Message request, IDuplexCallbackService callback) { // Send request to service host for processing lock (this.client) { this.client.BeginProcessMessage(request, this.ReceiveResponse, new object[] { request.Headers.MessageId, callback }); } }