FastTunnel/FastTunnel.Core.Client/FastTunnelClient.cs

190 lines
5.7 KiB
C#
Raw Permalink Normal View History

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
2019-12-16 10:29:06 +08:00
using System;
2022-07-10 22:34:13 +08:00
using System.Buffers;
using System.Net.Sockets;
using System.Net.WebSockets;
2019-12-16 10:29:06 +08:00
using System.Text;
2024-01-16 13:57:10 +08:00
using System.Text.Json;
using System.Text.Json.Serialization;
2022-07-10 22:34:13 +08:00
using System.Threading;
2019-12-16 10:29:06 +08:00
using System.Threading.Tasks;
2022-07-10 22:34:13 +08:00
using FastTunnel.Core.Config;
2019-12-25 10:11:58 +08:00
using FastTunnel.Core.Extensions;
using FastTunnel.Core.Handlers.Client;
2022-07-10 22:34:13 +08:00
using FastTunnel.Core.Models;
2022-06-29 15:48:53 +08:00
using FastTunnel.Core.Models.Massage;
2022-07-10 22:34:13 +08:00
using FastTunnel.Core.Utilitys;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
2019-12-16 10:29:06 +08:00
2022-07-10 22:34:13 +08:00
namespace FastTunnel.Core.Client;
2024-01-16 13:57:10 +08:00
#if NET6_0_OR_GREATER
[JsonSourceGenerationOptions(WriteIndented = false)]
[JsonSerializable(typeof(LogInMassage))]
[JsonSerializable(typeof(Message<TunnelMassage>))]
public partial class SourceGenerationContext : JsonSerializerContext
{
}
#endif
2022-07-10 22:34:13 +08:00
public class FastTunnelClient : IFastTunnelClient
{
private ClientWebSocket socket;
2021-08-05 01:30:28 +08:00
2022-07-10 22:34:13 +08:00
protected readonly ILogger<FastTunnelClient> _logger;
protected DefaultClientConfig ClientConfig { get; private set; }
2021-06-13 00:18:34 +08:00
2022-07-10 22:34:13 +08:00
private readonly SwapHandler swapHandler;
private readonly LogHandler logHandler;
2020-04-07 23:56:46 +08:00
2022-07-10 22:34:13 +08:00
private static ReadOnlySpan<byte> EndSpan => new ReadOnlySpan<byte>(new byte[] { (byte)'\n' });
2022-07-10 22:34:13 +08:00
public SuiDaoServer Server { get; protected set; }
2021-08-06 22:45:03 +08:00
2022-07-10 22:34:13 +08:00
public FastTunnelClient(
ILogger<FastTunnelClient> logger,
SwapHandler newCustomerHandler,
LogHandler logHandler,
IOptionsMonitor<DefaultClientConfig> configuration)
{
ReadOnlySpan<int> span = new ReadOnlySpan<int>();
_logger = logger;
swapHandler = newCustomerHandler;
this.logHandler = logHandler;
ClientConfig = configuration.CurrentValue;
Server = ClientConfig.Server;
}
2021-08-06 22:45:03 +08:00
2022-07-10 22:34:13 +08:00
/// <summary>
/// 启动客户端
/// </summary>
public virtual async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("===== FastTunnel Client Start =====");
2021-08-01 18:32:32 +08:00
2022-07-10 22:34:13 +08:00
while (!cancellationToken.IsCancellationRequested)
2021-06-13 00:18:34 +08:00
{
try
{
2022-07-10 22:34:13 +08:00
await loginAsync(cancellationToken);
await ReceiveServerAsync(cancellationToken);
2021-06-13 00:18:34 +08:00
}
2022-07-10 22:34:13 +08:00
catch (Exception ex)
2021-06-13 00:18:34 +08:00
{
2022-07-10 22:34:13 +08:00
_logger.LogError(ex.Message);
2021-06-13 00:18:34 +08:00
}
2022-12-29 16:17:16 +08:00
await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);
2021-08-08 20:36:42 +08:00
}
2021-06-13 00:18:34 +08:00
2022-07-10 22:34:13 +08:00
_logger.LogInformation("===== FastTunnel Client End =====");
}
2021-06-13 00:18:34 +08:00
2022-07-10 22:34:13 +08:00
private async Task loginAsync(CancellationToken cancellationToken)
{
var logMsg = GetLoginMsg(cancellationToken);
if (socket != null)
2021-06-17 20:10:45 +08:00
{
2022-07-10 22:34:13 +08:00
socket.Abort();
2021-07-09 00:32:51 +08:00
}
2022-07-10 22:34:13 +08:00
// 连接到的目标IP
socket = new ClientWebSocket();
socket.Options.RemoteCertificateValidationCallback = delegate { return true; };
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_VERSION, AssemblyUtility.GetVersion().ToString());
socket.Options.SetRequestHeader(FastTunnelConst.FASTTUNNEL_TOKEN, ClientConfig.Token);
_logger.LogInformation($"正在连接服务端 {Server.ServerAddr}:{Server.ServerPort}");
await socket.ConnectAsync(
new Uri($"{Server.Protocol}://{Server.ServerAddr}:{Server.ServerPort}"), cancellationToken);
_logger.LogDebug("连接服务端成功");
// 登录
await socket.SendCmdAsync(MessageType.LogIn, logMsg, cancellationToken);
}
2024-01-16 13:57:10 +08:00
2022-07-10 22:34:13 +08:00
protected virtual string GetLoginMsg(CancellationToken cancellationToken)
{
Server = ClientConfig.Server;
2024-01-16 13:57:10 +08:00
# if NET8_0_OR_GREATER
return new LogInMassage
{
Webs = ClientConfig.Webs,
Forwards = ClientConfig.Forwards,
}.ToJson(jsonTypeInfo: SourceGenerationContext.Default.LogInMassage);
#else
2022-07-10 22:34:13 +08:00
return new LogInMassage
2019-12-16 10:29:06 +08:00
{
2022-07-10 22:34:13 +08:00
Webs = ClientConfig.Webs,
Forwards = ClientConfig.Forwards,
}.ToJson();
2024-01-16 13:57:10 +08:00
#endif
2022-07-10 22:34:13 +08:00
}
2021-08-08 20:36:42 +08:00
2022-07-10 22:34:13 +08:00
protected async Task ReceiveServerAsync(CancellationToken cancellationToken)
{
var utility = new WebSocketUtility(socket, ProcessLine);
await utility.ProcessLinesAsync(cancellationToken);
}
private void ProcessLine(ReadOnlySequence<byte> line, CancellationToken cancellationToken)
{
HandleServerRequestAsync(line, cancellationToken);
}
private void HandleServerRequestAsync(ReadOnlySequence<byte> line, CancellationToken cancellationToken)
{
try
{
var row = line.ToArray();
var cmd = row[0];
IClientHandler handler;
switch ((MessageType)cmd)
2021-08-01 23:23:58 +08:00
{
2022-07-10 22:34:13 +08:00
case MessageType.SwapMsg:
case MessageType.Forward:
handler = swapHandler;
break;
case MessageType.Log:
handler = logHandler;
break;
default:
throw new Exception($"未处理的消息cmd={cmd}");
2021-08-01 23:23:58 +08:00
}
2022-07-10 22:34:13 +08:00
2022-11-11 22:54:00 +08:00
#if NETCOREAPP3_1
var content = Encoding.UTF8.GetString(line.Slice(1).ToArray());
#endif
#if NET5_0_OR_GREATER
2022-07-10 22:34:13 +08:00
var content = Encoding.UTF8.GetString(line.Slice(1));
2022-11-11 22:54:00 +08:00
#endif
2022-07-10 22:34:13 +08:00
handler.HandlerMsgAsync(this, content, cancellationToken);
2019-12-16 10:29:06 +08:00
}
2022-07-10 22:34:13 +08:00
catch (Exception ex)
{
_logger.LogError(ex);
}
}
2021-08-07 23:54:48 +08:00
2022-07-10 22:34:13 +08:00
public async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("===== FastTunnel Client Stoping =====");
if (socket != null)
2021-08-07 23:54:48 +08:00
{
2022-07-10 22:34:13 +08:00
socket.Abort();
2021-08-07 23:54:48 +08:00
}
2019-12-16 10:29:06 +08:00
}
}