Fixed several socket issues. Added backoff for reconnection.
This commit is contained in:
@ -2,9 +2,8 @@ using CommonSocketLibrary.Abstract;
|
||||
|
||||
namespace CommonSocketLibrary.Common
|
||||
{
|
||||
public interface IWebSocketHandler
|
||||
public interface IWebSocketHandler : ICodedOperation
|
||||
{
|
||||
int OperationCode { get; }
|
||||
Task Execute<Data>(SocketClient<WebSocketMessage> sender, Data data);
|
||||
}
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
using System.Text.Json;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using CommonSocketLibrary.Abstract;
|
||||
using Serilog;
|
||||
|
||||
@ -6,21 +8,22 @@ namespace CommonSocketLibrary.Common
|
||||
{
|
||||
public class WebSocketClient : SocketClient<WebSocketMessage>
|
||||
{
|
||||
private readonly HandlerManager<WebSocketClient, IWebSocketHandler> _handlerManager;
|
||||
private readonly HandlerTypeManager<WebSocketClient, IWebSocketHandler> _handlerTypeManager;
|
||||
protected IDictionary<int, IWebSocketHandler> _handlers;
|
||||
private readonly MessageTypeManager<IWebSocketHandler> _messageTypeManager;
|
||||
|
||||
public WebSocketClient(
|
||||
ILogger logger,
|
||||
HandlerManager<WebSocketClient, IWebSocketHandler> handlerManager,
|
||||
HandlerTypeManager<WebSocketClient, IWebSocketHandler> typeManager,
|
||||
JsonSerializerOptions serializerOptions
|
||||
IEnumerable<IWebSocketHandler> handlers,
|
||||
MessageTypeManager<IWebSocketHandler> typeManager,
|
||||
JsonSerializerOptions serializerOptions,
|
||||
ILogger logger
|
||||
) : base(logger, serializerOptions)
|
||||
{
|
||||
_handlerManager = handlerManager;
|
||||
_handlerTypeManager = typeManager;
|
||||
_handlers = handlers.ToDictionary(h => h.OperationCode, h => h);
|
||||
_messageTypeManager = typeManager;
|
||||
}
|
||||
|
||||
protected override WebSocketMessage GenerateMessage<T>(int opcode, T data)
|
||||
|
||||
protected WebSocketMessage GenerateMessage<T>(int opcode, T data)
|
||||
{
|
||||
return new WebSocketMessage()
|
||||
{
|
||||
@ -29,28 +32,61 @@ namespace CommonSocketLibrary.Common
|
||||
};
|
||||
}
|
||||
|
||||
protected override async Task OnResponseReceived(WebSocketMessage? data)
|
||||
protected override async Task OnResponseReceived(WebSocketMessage? message)
|
||||
{
|
||||
if (data == null)
|
||||
if (message == null)
|
||||
return;
|
||||
|
||||
string content = data.Data?.ToString() ?? string.Empty;
|
||||
_logger.Verbose("RX #" + data.OpCode + ": " + content);
|
||||
string content = message.Data?.ToString() ?? string.Empty;
|
||||
_logger.Verbose("RX #" + message.OpCode + ": " + content);
|
||||
|
||||
if (!_handlerTypeManager.HandlerTypes.TryGetValue(data.OpCode, out Type? type) || type == null)
|
||||
var type = _messageTypeManager.GetMessageTypeByCode(message.OpCode);
|
||||
if (type == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = JsonSerializer.Deserialize(content, type, _options);
|
||||
await _handlerManager.Execute(this, data.OpCode, obj);
|
||||
var data = JsonSerializer.Deserialize(content, type, _options);
|
||||
if (!_handlers.TryGetValue(message.OpCode, out IWebSocketHandler? handler) || handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await handler.Execute(this, data);
|
||||
}
|
||||
|
||||
protected override async Task OnMessageSend(int opcode, string? content)
|
||||
|
||||
public async Task Send<T>(int opcode, T data)
|
||||
{
|
||||
_logger.Verbose("TX #" + opcode + ": " + content);
|
||||
}
|
||||
if (_socket == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var message = GenerateMessage(opcode, data);
|
||||
var content = JsonSerializer.Serialize(message, _options);
|
||||
|
||||
protected override async Task OnConnection()
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(content);
|
||||
var array = new ArraySegment<byte>(bytes);
|
||||
var total = bytes.Length;
|
||||
var current = 0;
|
||||
|
||||
while (current < total)
|
||||
{
|
||||
var size = Encoding.UTF8.GetBytes(content.Substring(current), array);
|
||||
await _socket!.SendAsync(array, WebSocketMessageType.Text, current + size >= total, _cts!.Token);
|
||||
current += size;
|
||||
}
|
||||
_logger.Verbose("TX #" + opcode + ": " + content);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (_socket.State.ToString().Contains("Close") || _socket.State == WebSocketState.Aborted)
|
||||
{
|
||||
await DisconnectAsync(new SocketDisconnectionEventArgs(_socket.CloseStatus.ToString()!, _socket.CloseStatusDescription ?? string.Empty));
|
||||
_logger.Warning($"Socket state on closing = {_socket.State} | {_socket.CloseStatus?.ToString()} | {_socket.CloseStatusDescription}");
|
||||
}
|
||||
_logger.Error(e, $"Failed to send a websocket message [op code: {opcode}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,9 +4,9 @@ using Serilog;
|
||||
|
||||
namespace CommonSocketLibrary.Socket.Manager
|
||||
{
|
||||
public abstract class WebSocketHandlerTypeManager : HandlerTypeManager<WebSocketClient, IWebSocketHandler>
|
||||
public abstract class WebSocketMessageTypeManager : MessageTypeManager<IWebSocketHandler>
|
||||
{
|
||||
public WebSocketHandlerTypeManager(ILogger logger, HandlerManager<WebSocketClient, IWebSocketHandler> handlers) : base(logger, handlers)
|
||||
public WebSocketMessageTypeManager(IEnumerable<IWebSocketHandler> handlers, ILogger logger) : base(handlers, logger)
|
||||
{
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user