Skip to content

Commit

Permalink
[OneBot] Forward Websocket Supported
Browse files Browse the repository at this point in the history
  • Loading branch information
Linwenxuan authored and Linwenxuan committed Oct 25, 2023
1 parent 42ce36d commit 28565ea
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 103 deletions.
2 changes: 1 addition & 1 deletion Lagrange.OneBot/Core/Message/MessageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using Lagrange.Core.Message;
using Lagrange.Core.Utility.Extension;
using Lagrange.OneBot.Core.Entity.Message;
using Lagrange.OneBot.Core.Network;
using Lagrange.OneBot.Core.Network.Service;
using Lagrange.OneBot.Database;

namespace Lagrange.OneBot.Core.Message;
Expand Down
96 changes: 0 additions & 96 deletions Lagrange.OneBot/Core/Network/ReverseWSService.cs

This file was deleted.

81 changes: 81 additions & 0 deletions Lagrange.OneBot/Core/Network/Service/ForwardWSService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System.Net.NetworkInformation;
using System.Text.Json;
using Fleck;
using Lagrange.OneBot.Core.Entity.Meta;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Lagrange.OneBot.Core.Network.Service;

public sealed class ForwardWSService : LagrangeWSService
{
private const string Tag = nameof(ForwardWSService);
public override event EventHandler<MsgRecvEventArgs>? OnMessageReceived = delegate { };

private readonly WebSocketServer _server;

private IWebSocketConnection? _connection;

private readonly Timer _timer;

public ForwardWSService(IConfiguration config, ILogger<LagrangeApp> logger) : base(config, logger)
{
var ws = config.GetSection("Implementation").GetSection("ForwardWebSocket");
string url = $"ws://{ws["Host"]}:{ws["Port"]}";

_server = new WebSocketServer(url)
{
RestartAfterListenError = true
};

_timer = new Timer(OnHeartbeat, null, int.MaxValue, ws.GetValue<int>("HeartBeatInterval"));
}

public override Task StartAsync(CancellationToken cancellationToken)
{
return Task.Run(() =>
{
_server.Start(conn =>
{
_connection = conn;

conn.OnMessage = s =>
{
Logger.LogTrace($"[{Tag}] Receive: {s}");
OnMessageReceived?.Invoke(this, new MsgRecvEventArgs(s));
};

conn.OnOpen = () =>
{
Logger.LogInformation($"[{Tag}]: Connected");

var lifecycle = new OneBotLifecycle(Config.GetValue<uint>("Account:Uin"), "connect");
SendJsonAsync(lifecycle, cancellationToken).GetAwaiter().GetResult();
};
});
}, cancellationToken);
}

public override Task StopAsync(CancellationToken cancellationToken)
{
_timer.Dispose();
_server.ListenerSocket.Close();
_server.Dispose();

return Task.CompletedTask;
}

public override Task SendJsonAsync<T>(T json, CancellationToken cancellationToken = default)
{
string payload = JsonSerializer.Serialize(json);

Logger.LogTrace($"[{Tag}] Send: {payload}");
return _connection?.Send(payload) ?? Task.CompletedTask;
}

private static bool IsPortInUse(uint port)
{
return IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners().Any(endpoint => endpoint.Port == port);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Lagrange.OneBot.Core.Network;
namespace Lagrange.OneBot.Core.Network.Service;

public sealed class HttpPostService : ILagrangeWebService
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Hosting;

namespace Lagrange.OneBot.Core.Network;
namespace Lagrange.OneBot.Core.Network.Service;

public interface ILagrangeWebService : IHostedService
{
Expand Down
30 changes: 30 additions & 0 deletions Lagrange.OneBot/Core/Network/Service/LagrangeWSService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Lagrange.OneBot.Core.Entity.Meta;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Lagrange.OneBot.Core.Network.Service;

public abstract class LagrangeWSService(IConfiguration config, ILogger<LagrangeApp> logger) : ILagrangeWebService
{
protected readonly ILogger Logger = logger;

protected readonly IConfiguration Config = config;

protected void OnHeartbeat(object? sender)
{
var status = new OneBotStatus(true, true);
var heartBeat = new OneBotHeartBeat(
Config.GetValue<uint>("Account:Uin"),
Config.GetValue<int>("Implementation:ReverseWebSocket:HeartBeatInterval"),
status);

SendJsonAsync(heartBeat);
}

public abstract Task StartAsync(CancellationToken cancellationToken);

public abstract Task StopAsync(CancellationToken cancellationToken);

public abstract event EventHandler<MsgRecvEventArgs>? OnMessageReceived;
public abstract Task SendJsonAsync<T>(T json, CancellationToken cancellationToken = default);
}
77 changes: 77 additions & 0 deletions Lagrange.OneBot/Core/Network/Service/ReverseWSService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System.Net.WebSockets;
using System.Text.Json;
using Lagrange.OneBot.Core.Entity.Meta;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Websocket.Client;
using Timer = System.Threading.Timer;

namespace Lagrange.OneBot.Core.Network.Service;

public sealed class ReverseWSService : LagrangeWSService
{
private const string Tag = nameof(ReverseWSService);
public override event EventHandler<MsgRecvEventArgs>? OnMessageReceived = delegate { };

private readonly WebsocketClient _socket;

private readonly Timer _timer;

public ReverseWSService(IConfiguration config, ILogger<LagrangeApp> logger) : base(config, logger)
{
var ws = Config.GetSection("Implementation").GetSection("ReverseWebSocket");
string url = $"ws://{ws["Host"]}:{ws["Port"]}{ws["Suffix"]}";

_socket = new WebsocketClient(new Uri(url), () =>
{
var socket = new ClientWebSocket();

SetRequestHeader(socket, new Dictionary<string, string>
{
{ "X-Client-Role", "Universal" },
{ "X-Self-ID", Config.GetValue<uint>("Account:Uin").ToString() },
{ "User-Agent", Constant.OneBotImpl }
});
socket.Options.KeepAliveInterval = TimeSpan.FromSeconds(5);
if (Config["AccessToken"] != null) socket.Options.SetRequestHeader("Authorization", $"Bearer {Config["AccessToken"]}");

return socket;
});

_timer = new Timer(OnHeartbeat, null, int.MaxValue, ws.GetValue<int>("HeartBeatInterval"));
_socket.MessageReceived.Subscribe(resp =>
{
Logger.LogTrace($"[{Tag}] Receive: {resp.Text}");
OnMessageReceived?.Invoke(this, new MsgRecvEventArgs(resp.Text ?? ""));
});
}

public override async Task StartAsync(CancellationToken cancellationToken)
{
await _socket.Start();

var lifecycle = new OneBotLifecycle(Config.GetValue<uint>("Account:Uin"), "connect");
await SendJsonAsync(lifecycle, cancellationToken);
}

public override Task StopAsync(CancellationToken cancellationToken)
{
_timer.Dispose();
_socket.Dispose();

return Task.CompletedTask;
}

public override Task SendJsonAsync<T>(T json, CancellationToken cancellationToken = default)
{
string payload = JsonSerializer.Serialize(json);

Logger.LogTrace($"[{Tag}] Send: {payload}");
return _socket.SendInstant(payload);
}

private static void SetRequestHeader(ClientWebSocket webSocket, Dictionary<string, string> headers)
{
foreach (var (key, value) in headers) webSocket.Options.SetRequestHeader(key, value);
}
}
2 changes: 1 addition & 1 deletion Lagrange.OneBot/Core/Operation/OperationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Lagrange.Core;
using Lagrange.Core.Utility.Extension;
using Lagrange.OneBot.Core.Entity.Action;
using Lagrange.OneBot.Core.Network;
using Lagrange.OneBot.Core.Network.Service;

namespace Lagrange.OneBot.Core.Operation;

Expand Down
1 change: 1 addition & 0 deletions Lagrange.OneBot/Lagrange.OneBot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Fleck" Version="1.2.0" />
<PackageReference Include="LiteDB" Version="5.0.17" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Websocket.Client" Version="5.0.0" />
Expand Down
2 changes: 1 addition & 1 deletion Lagrange.OneBot/LagrangeApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Lagrange.Core.Common.Interface.Api;
using Lagrange.Core.Utility.Sign;
using Lagrange.OneBot.Core.Message;
using Lagrange.OneBot.Core.Network;
using Lagrange.OneBot.Core.Network.Service;
using Lagrange.OneBot.Core.Operation;
using Lagrange.OneBot.Utility;
using Microsoft.Extensions.Configuration;
Expand Down
12 changes: 10 additions & 2 deletions Lagrange.OneBot/LagrangeAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Lagrange.Core.Common.Interface;
using Lagrange.Core.Utility.Sign;
using Lagrange.OneBot.Core.Message;
using Lagrange.OneBot.Core.Network;
using Lagrange.OneBot.Core.Network.Service;
using Lagrange.OneBot.Core.Operation;
using Lagrange.OneBot.Database;
using Lagrange.OneBot.Utility;
Expand Down Expand Up @@ -77,8 +77,16 @@ public LagrangeAppBuilder ConfigureBots()

public LagrangeAppBuilder ConfigureOneBot()
{
if (Configuration.GetSection("Implementation:ReverseWebSocket").Value != null)
{
Services.AddSingleton<ILagrangeWebService, ReverseWSService>();
}
else if (Configuration.GetSection("Implementation:ForwardWebSocket").Value != null)
{
Services.AddSingleton<ILagrangeWebService, ForwardWSService>();
}

Services.AddSingleton<ContextBase, LiteDbContext>();
Services.AddSingleton<ILagrangeWebService, ReverseWSService>();
Services.AddSingleton<SignProvider, OneBotSigner>();

Services.AddSingleton<MessageService>();
Expand Down

0 comments on commit 28565ea

Please sign in to comment.