using System; using System.Collections.Generic; using System.Text; using Taobao.Top.Link.Channel; namespace Taobao.Top.Link.Endpoints { /// logic endpoint local proxy object /// public class EndpointProxy { private IList _senders; private Random _random; private EndpointHandler _handler; /// get id /// public Identity Identity { get; internal set; } /// known by both side, like a sessionId /// public string Token { get; internal set; } public EndpointProxy(EndpointHandler handler) { this._senders = new List(); this._random = new Random(); this._handler = handler; } internal void Add(IChannelSender sender) { if (!this._senders.Contains(sender)) lock (this._senders) if (!this._senders.Contains(sender)) this._senders.Add(sender); } internal void Remove(IChannelSender sender) { lock (this._senders) this._senders.Remove(sender); } internal void Remove(string uri) { lock (this._senders) { for (var i = 0; i < this._senders.Count; i++) { var channel = this._senders[i] as IClientChannel; if (channel == null) continue; if (!channel.Uri.ToString().Equals(uri)) continue; this._senders.Remove(channel); i--; } } } internal void Close(string uri, string reason) { lock (this._senders) { for (var i = 0; i < this._senders.Count; i++) { var channel = this._senders[i] as IClientChannel; if (channel == null) continue; if (!channel.Uri.ToString().Equals(uri)) continue; channel.Close(reason); this._senders.Remove(channel); i--; } } } /// check is there any sender can be used to send /// /// public bool hasValidSender() { foreach (IClientChannel sender in this._senders) { if (sender.IsConnected) return true; } return false; } /// send message and wait reply /// /// /// public IDictionary SendAndWait(IDictionary message) { return this.SendAndWait(message, Endpoint.TIMEOUT); } /// send message and wait reply /// /// /// timeout in milliseconds /// public IDictionary SendAndWait(IDictionary message, int timeout) { return this.SendAndWait(null, message, timeout); } /// send message and wait reply /// /// use to send, must belong this proxy /// /// timeout in milliseconds /// internal IDictionary SendAndWait(IChannelSender sender, IDictionary message, int timeout) { return this._handler.SendAndWait(this, this.GetSender(sender), this.CreateMessage(message), timeout); } /// send message /// /// public void Send(IDictionary message) { this.Send(null, message); } /// send message /// /// use to send, must belong this proxy /// internal void Send(IChannelSender sender, IDictionary message) { this._handler.Send(this.CreateMessage(message), this.GetSender(sender)); } private Message CreateMessage(IDictionary message) { Message msg = new Message(); msg.MessageType = MessageType.SEND; msg.Content = message; msg.Token = this.Token; return msg; } private IChannelSender GetSender(IChannelSender sender) { if (this._senders.Count == 0) throw new ChannelException(Text.E_NO_SENDER); if (this._senders.Contains(sender)) return sender; return this._senders[this._random.Next(this._senders.Count)]; } } }