wtt
2024-09-20 d9b200d424889c069953ec084ef9d4dd6c4ff66b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.Collections.Generic;
using Taobao.Top.Link.Channel.WebSocket;
using Top.Api;
 
namespace Taobao.Top.Link.Channel
{
    /// <summary>a channel pool that same uri sharing same channel
    /// </summary>
    public class ClientChannelSharedSelector : IClientChannelSelector
    {
        private static readonly int CONNECTTIMEOUT = 5000;
        private ITopLogger _logger;
        private Object _lockObject;
        private IDictionary<string, IClientChannel> _channels;
 
        /// <summary>get or set heartbeat interval time in milliseconds
        /// </summary>
        public int HeartbeatPeriod { get; set; }
 
        public ClientChannelSharedSelector() : this(Log.Instance) { }
        public ClientChannelSharedSelector(ITopLogger logger)
        {
            this._logger = logger;
            this._lockObject = new object();
            this._channels = new Dictionary<string, IClientChannel>();
        }
 
        public IClientChannel GetChannel(Uri uri)
        {
            if (!uri.Scheme.Equals("ws", StringComparison.InvariantCultureIgnoreCase))
                return null;
 
            var url = uri.ToString();
 
            if (!this.HaveChannel(url))
                lock (this._lockObject)
                    if (!this.HaveChannel(url))
                        this.AddChannel(url, this.WrapChannel(this.Connect(uri, CONNECTTIMEOUT)));
 
            return _channels[url];
        }
        public void ReturnChannel(IClientChannel channel) { }
 
        protected virtual IClientChannel Connect(Uri uri, int timeout)
        {
            return WebSocketClient.Connect(this._logger, uri, timeout);
        }
        private IClientChannel WrapChannel(IClientChannel channel)
        {
            if (this.HeartbeatPeriod > 0)
                channel.HeartbeatTimer = new ResetableTimer(this.HeartbeatPeriod);
            return channel;
        }
        private bool HaveChannel(string url)
        {
            return this._channels.ContainsKey(url) && this._channels[url].IsConnected;
        }
        private void AddChannel(string url, IClientChannel channel)
        {
            if (this._channels.ContainsKey(url))
                this._channels[url] = channel;
            else
                this._channels.Add(url, channel);
        }
    }
}