Esempio n. 1
0
        /// <summary>
        /// 构建转发连接处理服务
        /// </summary>
        /// <param name="heartbeatLifetime"></param>
        /// <param name="heartbeatService"></param>
        /// <returns></returns>
        private IEnumerable <Task> BuildHeartbeatService(IServiceProvider heartbeatLifetime, HeartbeatService heartbeatService)
        {
            foreach (var client in _settings.Clients)
            {
                _logger.LogWarning("侦听客户端的连接端口:{0}", client.ClientId);

                foreach (var rule in client.ForwardRules)
                {
                    var detail = new ForwardRuleDetail
                    {
                        ClientId     = client.ClientId,
                        ClientKey    = client.ClientKey,
                        RuleId       = rule.RuleId,
                        ListenerPort = rule.ListenerPort
                    };

                    var rcs = heartbeatLifetime.GetRequiredService <RequestConnectionService>();
                    rcs.RequestConnectionEvent += GetRequestConnectionEventHandle(heartbeatService, detail);
                    yield return(rcs.Start(detail.ListenerPort));

                    _logger.LogWarning("侦听连接端口:{0}, {1}:{2}", client.ClientId, rule.RuleId, rule.ListenerPort);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 获取连接请求处理 委托
        /// </summary>
        /// <param name="heartbeatService"></param>
        /// <returns></returns>
        private Func <TcpClient, CancellationToken, Task> GetRequestConnectionEventHandle(HeartbeatService heartbeatService, ForwardRuleDetail forwardRuleDetail)
        {
            return(async(tcp, serviceToken) =>
            {
                var remoteEndPoint = tcp.Client.RemoteEndPoint;
                Action EndNotice = null;
                try
                {
                    _logger.LogInformation("接收到访问请求:ClientId, {0}:{1}, 访问者:{2}", forwardRuleDetail.ClientId, forwardRuleDetail.RuleId, remoteEndPoint);
                    var(serverTcp, EndNotice2) = await heartbeatService.GetRequestTcpClient(serviceToken, forwardRuleDetail);

                    EndNotice = EndNotice2;

                    if (serverTcp == null)
                    {
                        _logger.LogInformation("连接请求失败: 未获得服务端tcp连接");
                        return;
                    }
                    using (var forwarder = new Forwarder(tcp, serverTcp))
                    {
                        await forwarder.Start();
                    }
                }
                catch (IOException ex)
                {
                    _logger.LogInformation("数据转发连接断开:ClientId, {0}:{1}, 访问者:{2}, {3}", forwardRuleDetail.ClientId, forwardRuleDetail.RuleId, remoteEndPoint, ex.Message);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "数据转发出现异常:ClientId, {0}:{1}, 访问者:{2}", forwardRuleDetail.ClientId, forwardRuleDetail.RuleId, remoteEndPoint);
                }
                EndNotice?.Invoke();
            });
        }
Esempio n. 3
0
        /// <summary>
        /// 获取客户端连接
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task <(TcpClient RequestTcpClient, Action EndNotice)> GetRequestTcpClient(CancellationToken token, ForwardRuleDetail forwardRuleDetail)
        {
            var forwardId = Guid.NewGuid().ToString("n");
            var tcp       = _heartbeatTcpClients.FirstOrDefault(u => u.ClientId == forwardRuleDetail.ClientId);
            var result    = default(TcpClient);

            var tcsEndNotice = new TaskCompletionSource <TcpClient>();

            if (tcp != null)
            {
                var tcs         = new TaskCompletionSource <TcpClient>();
                var cacheKey    = $"/CancellationToken/{forwardId}";
                var requestInfo = new ForwardRequesInfo
                {
                    CompletionSource = tcs,
                    EndNotice        = tcsEndNotice.Task
                };
                _cache.Set(cacheKey, requestInfo, TimeSpan.FromSeconds(20));

                var message = $"connection:{forwardId},{forwardRuleDetail.RuleId}";
                var buff    = Encoding.ASCII.GetBytes(message);
                _logger.LogInformation("请求连接客户端连接, 回复客户端消息:{0}", message);
                await tcp.TcpClient.GetStream().WriteAsync(buff, 0, buff.Length, token).TimeoutAfter(TimeSpan.FromMilliseconds(_sendTimeout), token);;
                _logger.LogInformation("请求连接客户端连接, 回复客户端消息:{0}, 成功", message);

                await Task.WhenAny(tcs.Task.ContinueWith(t => { result = t.Result; }), Task.Delay(10 * 1000, token));
            }
            return(result, () => tcsEndNotice.SetResult(result));
        }