| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Taobao.Top.Link.Channel;
- namespace Taobao.Top.Link.Endpoints
- {
- /// <summary>logic endpoint local proxy object
- /// </summary>
- public class EndpointProxy
- {
- private IList<IChannelSender> _senders;
- private Random _random;
- private EndpointHandler _handler;
- /// <summary>get id
- /// </summary>
- public Identity Identity { get; internal set; }
- /// <summary>known by both side, like a sessionId
- /// </summary>
- public string Token { get; internal set; }
- public EndpointProxy(EndpointHandler handler)
- {
- this._senders = new List<IChannelSender>();
- 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--;
- }
- }
- }
- /// <summary>check is there any sender can be used to send
- /// </summary>
- /// <returns></returns>
- public bool hasValidSender()
- {
- foreach (IClientChannel sender in this._senders)
- {
- if (sender.IsConnected)
- return true;
- }
- return false;
- }
- /// <summary>send message and wait reply
- /// </summary>
- /// <param name="message"></param>
- /// <returns></returns>
- public IDictionary<string, object> SendAndWait(IDictionary<string, object> message)
- {
- return this.SendAndWait(message, Endpoint.TIMEOUT);
- }
- /// <summary>send message and wait reply
- /// </summary>
- /// <param name="message"></param>
- /// <param name="timeout">timeout in milliseconds</param>
- /// <returns></returns>
- public IDictionary<string, object> SendAndWait(IDictionary<string, object> message, int timeout)
- {
- return this.SendAndWait(null, message, timeout);
- }
- /// <summary>send message and wait reply
- /// </summary>
- /// <param name="sender">use to send, must belong this proxy</param>
- /// <param name="message"></param>
- /// <param name="timeout">timeout in milliseconds</param>
- /// <returns></returns>
- internal IDictionary<string, object> SendAndWait(IChannelSender sender, IDictionary<string, object> message, int timeout)
- {
- return this._handler.SendAndWait(this,
- this.GetSender(sender),
- this.CreateMessage(message),
- timeout);
- }
- /// <summary>send message
- /// </summary>
- /// <param name="message"></param>
- public void Send(IDictionary<string, object> message)
- {
- this.Send(null, message);
- }
- /// <summary>send message
- /// </summary>
- /// <param name="sender">use to send, must belong this proxy</param>
- /// <param name="message"></param>
- internal void Send(IChannelSender sender, IDictionary<string, object> message)
- {
- this._handler.Send(this.CreateMessage(message), this.GetSender(sender));
- }
- private Message CreateMessage(IDictionary<string, object> 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)];
- }
- }
- }
|