public void SendRequest(Uri uri, BplMessage request, Action<BplContextNode> onResponse, Action<GeneralFailure> onFailure) { if (uri == null) { var formatter = BplXmlFormatter.Minimal; var info = formatter.Format(request) ? formatter.Output : "(unknown)"; throw new BplServiceHandlerException("Unspecified URI invoking request: " + info); } var entry = onResponse != null ? new InboxEntry { Request = request, ResponseHandler = onResponse, FailureHandler = onFailure } : null; // connection state is deliberatelly not checked, because the connection can be in BeginConnect-ing state // in which there's no problem to add to Outbox/Inbox and call NextAction (which will do nothing, // because _canWrite/_canRead are false, and the sending will be done later, when EndConnect happens). // Besides, this is designed to well-connected clients, so polling socket for no real reason is not a good idea. // var c = _outConnections.Find(uri); if (c == null) { c = new Connection(); c.BeginConnect(uri); } else { if (c.Outbox.RequestCount >= CommunicationManager.MaxOutgoingRequests) { Log.Warn("Outgoing requests queue is full ({0} items)", c.Outbox.RequestCount); if (onFailure != null) onFailure(new GeneralFailure(GeneralFailureCode.ServiceUnavailable)); return; } } c.Outbox.Add(request, null); c.Inbox.Add(entry); c.NextAction(); }