2022-06-29 15:48:53 +08:00
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License").
|
2022-01-02 00:23:39 +08:00
|
|
|
|
// You may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
// https://github.com/FastTunnel/FastTunnel/edit/v2/LICENSE
|
|
|
|
|
// Copyright (c) 2019 Gui.H
|
|
|
|
|
|
|
|
|
|
using FastTunnel.Core.Config;
|
2019-12-16 10:29:06 +08:00
|
|
|
|
using FastTunnel.Core.Models;
|
|
|
|
|
using System;
|
|
|
|
|
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.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-07-21 23:52:26 +08:00
|
|
|
|
using Microsoft.Extensions.Options;
|
2021-08-01 18:32:32 +08:00
|
|
|
|
using System.Net.WebSockets;
|
2021-08-10 20:33:29 +08:00
|
|
|
|
using FastTunnel.Core.Utilitys;
|
2022-06-29 15:48:53 +08:00
|
|
|
|
using FastTunnel.Core.Models.Massage;
|
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-08 20:36:42 +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;
|
2021-08-08 20:36:42 +08:00
|
|
|
|
Server = ClientConfig.Server;
|
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-08 20:36:42 +08:00
|
|
|
|
private async Task loginAsync(CancellationToken cancellationToken)
|
2021-06-13 00:18:34 +08:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2021-08-13 00:55:55 +08:00
|
|
|
|
var logMsg = GetLoginMsg(cancellationToken);
|
2021-08-08 20:36:42 +08:00
|
|
|
|
|
2021-06-13 00:18:34 +08:00
|
|
|
|
// 连接到的目标IP
|
2021-08-05 01:30:28 +08:00
|
|
|
|
socket = new ClientWebSocket();
|
|
|
|
|
socket.Options.RemoteCertificateValidationCallback = delegate { return true; };
|
2021-08-10 20:33:29 +08:00
|
|
|
|
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_VERSION, AssemblyUtility.GetVersion().ToString());
|
2021-08-08 22:27:36 +08:00
|
|
|
|
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_TOKEN, ClientConfig.Token);
|
2021-07-04 22:36:12 +08:00
|
|
|
|
|
2021-08-08 20:36:42 +08:00
|
|
|
|
_logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
|
2021-08-01 18:32:32 +08:00
|
|
|
|
await socket.ConnectAsync(
|
2021-08-22 12:18:11 +08:00
|
|
|
|
new Uri($"{Server.Protocol}://{Server.ServerAddr}:{Server.ServerPort}"), cancellationToken);
|
2021-06-13 00:18:34 +08:00
|
|
|
|
|
2021-08-07 14:51:37 +08:00
|
|
|
|
_logger.LogDebug("连接服务端成功");
|
2021-08-08 20:36:42 +08:00
|
|
|
|
|
|
|
|
|
// 登录
|
|
|
|
|
await socket.SendCmdAsync(MessageType.LogIn, logMsg, cancellationToken);
|
2021-06-13 00:18:34 +08:00
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|
{
|
|
|
|
|
throw;
|
|
|
|
|
}
|
2021-08-08 20:36:42 +08:00
|
|
|
|
}
|
2021-06-13 00:18:34 +08:00
|
|
|
|
|
2021-08-13 00:55:55 +08:00
|
|
|
|
public virtual string GetLoginMsg(CancellationToken cancellationToken)
|
2021-08-08 20:36:42 +08:00
|
|
|
|
{
|
|
|
|
|
Server = ClientConfig.Server;
|
|
|
|
|
return new LogInMassage
|
2021-08-05 01:30:28 +08:00
|
|
|
|
{
|
|
|
|
|
Webs = ClientConfig.Webs,
|
|
|
|
|
Forwards = ClientConfig.Forwards,
|
2021-08-08 20:36:42 +08:00
|
|
|
|
}.ToJson();
|
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-10 20:33:29 +08:00
|
|
|
|
byte[] buffer = new byte[FastTunnelConst.MAX_CMD_LENGTH];
|
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-08 20:36:42 +08:00
|
|
|
|
await Task.Yield();
|
|
|
|
|
|
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:
|
|
|
|
|
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 =====");
|
|
|
|
|
}
|
2019-12-16 10:29:06 +08:00
|
|
|
|
}
|
|
|
|
|
}
|