2021-08-01 18:32:32 +08:00
|
|
|
|
using FastTunnel.Core.Config;
|
2019-12-16 10:29:06 +08:00
|
|
|
|
using FastTunnel.Core.Models;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
2019-12-25 10:11:58 +08:00
|
|
|
|
using FastTunnel.Core.Extensions;
|
2019-12-26 15:47:36 +08:00
|
|
|
|
using System.Timers;
|
|
|
|
|
using System.Threading;
|
2020-01-02 23:59:31 +08:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2020-04-08 18:37:37 +08:00
|
|
|
|
using FastTunnel.Core.Handlers.Client;
|
2021-06-13 00:18:34 +08:00
|
|
|
|
using Microsoft.Extensions.Configuration;
|
2021-07-04 22:36:12 +08:00
|
|
|
|
using FastTunnel.Core.Sockets;
|
2021-07-21 23:52:26 +08:00
|
|
|
|
using Microsoft.Extensions.Options;
|
2021-08-01 18:32:32 +08:00
|
|
|
|
using System.Net.WebSockets;
|
|
|
|
|
using System.Text.Json;
|
2021-08-01 23:23:58 +08:00
|
|
|
|
using FastTunnel.Core.Protocol;
|
2021-08-05 01:30:28 +08:00
|
|
|
|
using Microsoft.AspNetCore.DataProtection;
|
2019-12-16 10:29:06 +08:00
|
|
|
|
|
2020-11-04 19:05:04 +08:00
|
|
|
|
namespace FastTunnel.Core.Client
|
2019-12-16 10:29:06 +08:00
|
|
|
|
{
|
2021-07-30 00:54:53 +08:00
|
|
|
|
public class FastTunnelClient : IFastTunnelClient
|
2019-12-16 10:29:06 +08:00
|
|
|
|
{
|
2021-08-05 01:30:28 +08:00
|
|
|
|
private ClientWebSocket socket;
|
2019-12-26 15:47:36 +08:00
|
|
|
|
|
2021-08-07 23:54:48 +08:00
|
|
|
|
protected readonly ILogger<FastTunnelClient> _logger;
|
|
|
|
|
private readonly SwapHandler _newCustomerHandler;
|
|
|
|
|
private readonly LogHandler _logHandler;
|
2021-08-05 01:30:28 +08:00
|
|
|
|
|
|
|
|
|
public DefaultClientConfig ClientConfig { get; private set; }
|
2021-06-13 00:18:34 +08:00
|
|
|
|
|
2021-06-18 13:54:23 +08:00
|
|
|
|
public SuiDaoServer Server { get; protected set; }
|
2020-04-07 23:56:46 +08:00
|
|
|
|
|
2020-10-27 09:18:18 +08:00
|
|
|
|
public FastTunnelClient(
|
2021-06-13 00:18:34 +08:00
|
|
|
|
ILogger<FastTunnelClient> logger,
|
2021-08-06 00:13:02 +08:00
|
|
|
|
SwapHandler newCustomerHandler,
|
2021-08-05 01:30:28 +08:00
|
|
|
|
LogHandler logHandler,
|
2021-08-06 00:13:02 +08:00
|
|
|
|
IOptionsMonitor<DefaultClientConfig> configuration)
|
2019-12-16 10:29:06 +08:00
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
2020-04-08 18:37:37 +08:00
|
|
|
|
_newCustomerHandler = newCustomerHandler;
|
|
|
|
|
_logHandler = logHandler;
|
2021-08-05 01:30:28 +08:00
|
|
|
|
ClientConfig = configuration.CurrentValue;
|
2019-12-26 15:47:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-13 00:18:34 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 启动客户端
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
/// <param name="customLoginMsg">自定义登录信息,可进行扩展业务</param>
|
2021-08-06 22:45:03 +08:00
|
|
|
|
public async void StartAsync(CancellationToken cancellationToken)
|
2020-04-01 23:20:35 +08:00
|
|
|
|
{
|
2021-08-01 18:32:32 +08:00
|
|
|
|
_logger.LogInformation("===== FastTunnel Client Start =====");
|
2021-08-06 22:45:03 +08:00
|
|
|
|
|
|
|
|
|
while (!cancellationToken.IsCancellationRequested)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await loginAsync(cancellationToken);
|
|
|
|
|
await ReceiveServerAsync(cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex.Message);
|
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("===== FastTunnel Client End =====");
|
2020-04-01 23:20:35 +08:00
|
|
|
|
}
|
2021-08-01 18:32:32 +08:00
|
|
|
|
|
2021-08-05 01:30:28 +08:00
|
|
|
|
protected virtual async Task loginAsync(CancellationToken cancellationToken)
|
2021-06-13 00:18:34 +08:00
|
|
|
|
{
|
2021-08-05 01:30:28 +08:00
|
|
|
|
Server = ClientConfig.Server;
|
2021-06-18 13:54:23 +08:00
|
|
|
|
_logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
|
2021-06-13 00:18:34 +08:00
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// 连接到的目标IP
|
2021-08-05 01:30:28 +08:00
|
|
|
|
socket = new ClientWebSocket();
|
|
|
|
|
socket.Options.RemoteCertificateValidationCallback = delegate { return true; };
|
2021-08-06 00:13:02 +08:00
|
|
|
|
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_FLAG, "2.0.0");
|
|
|
|
|
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_TYPE, FastTunnelConst.TYPE_CLIENT);
|
2021-07-04 22:36:12 +08:00
|
|
|
|
|
2021-08-01 18:32:32 +08:00
|
|
|
|
await socket.ConnectAsync(
|
2021-08-05 01:30:28 +08:00
|
|
|
|
new Uri($"ws://{ClientConfig.Server.ServerAddr}:{ClientConfig.Server.ServerPort}"), cancellationToken);
|
2021-06-13 00:18:34 +08:00
|
|
|
|
|
2021-08-07 14:51:37 +08:00
|
|
|
|
_logger.LogDebug("连接服务端成功");
|
2021-06-13 00:18:34 +08:00
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 登录
|
2021-08-05 01:30:28 +08:00
|
|
|
|
await socket.SendCmdAsync(MessageType.LogIn, new LogInMassage
|
|
|
|
|
{
|
|
|
|
|
Webs = ClientConfig.Webs,
|
|
|
|
|
Forwards = ClientConfig.Forwards,
|
2021-08-06 22:45:03 +08:00
|
|
|
|
}.ToJson(), cancellationToken);
|
2021-06-13 00:18:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-06 22:45:03 +08:00
|
|
|
|
private async Task ReceiveServerAsync(CancellationToken cancellationToken)
|
2021-06-17 20:10:45 +08:00
|
|
|
|
{
|
2021-08-05 01:30:28 +08:00
|
|
|
|
byte[] buffer = new byte[128];
|
2021-07-09 00:32:51 +08:00
|
|
|
|
|
2021-08-06 22:45:03 +08:00
|
|
|
|
while (!cancellationToken.IsCancellationRequested)
|
2021-06-19 14:26:57 +08:00
|
|
|
|
{
|
2021-08-06 22:45:03 +08:00
|
|
|
|
var res = await socket.ReceiveAsync(buffer, cancellationToken);
|
2021-08-05 01:30:28 +08:00
|
|
|
|
var type = buffer[0];
|
|
|
|
|
var content = Encoding.UTF8.GetString(buffer, 1, res.Count - 1);
|
2021-08-06 22:45:03 +08:00
|
|
|
|
HandleServerRequestAsync(type, content, cancellationToken);
|
2021-06-19 14:26:57 +08:00
|
|
|
|
}
|
2021-07-09 00:32:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-06 22:45:03 +08:00
|
|
|
|
private async void HandleServerRequestAsync(byte cmd, string ctx, CancellationToken cancellationToken)
|
2019-12-16 10:29:06 +08:00
|
|
|
|
{
|
2021-08-01 23:23:58 +08:00
|
|
|
|
try
|
2021-07-09 00:32:51 +08:00
|
|
|
|
{
|
2021-07-30 23:57:39 +08:00
|
|
|
|
IClientHandler handler;
|
2021-08-05 01:30:28 +08:00
|
|
|
|
switch ((MessageType)cmd)
|
2021-07-30 23:57:39 +08:00
|
|
|
|
{
|
2021-08-05 01:30:28 +08:00
|
|
|
|
case MessageType.SwapMsg:
|
2021-07-30 23:57:39 +08:00
|
|
|
|
handler = _newCustomerHandler;
|
|
|
|
|
break;
|
2021-08-05 01:30:28 +08:00
|
|
|
|
case MessageType.Forward:
|
|
|
|
|
handler = _newCustomerHandler;
|
2021-07-30 23:57:39 +08:00
|
|
|
|
break;
|
2021-08-05 01:30:28 +08:00
|
|
|
|
case MessageType.Log:
|
2021-07-30 23:57:39 +08:00
|
|
|
|
handler = _logHandler;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2021-08-05 01:30:28 +08:00
|
|
|
|
throw new Exception($"未处理的消息:cmd={cmd}");
|
2021-07-30 23:57:39 +08:00
|
|
|
|
}
|
2020-04-08 18:37:37 +08:00
|
|
|
|
|
2021-08-06 22:45:03 +08:00
|
|
|
|
await handler.HandlerMsgAsync(this, ctx, cancellationToken);
|
2021-08-01 23:23:58 +08:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex);
|
|
|
|
|
}
|
2019-12-16 10:29:06 +08:00
|
|
|
|
}
|
2021-08-07 23:54:48 +08:00
|
|
|
|
|
|
|
|
|
public void Stop(CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("===== FastTunnel Client Stoping =====");
|
|
|
|
|
if (socket.State == WebSocketState.Connecting)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
socket.CloseAsync(WebSocketCloseStatus.Empty, "客户端主动关闭", cancellationToken);
|
|
|
|
|
}
|
2019-12-16 10:29:06 +08:00
|
|
|
|
}
|
|
|
|
|
}
|