{
Type: "AUTH_MESSAGE",
Payload: {
UserName: "dailydose"
}
}
{
Type: "CHAT_MESSAGE",
Payload: {
Message: "hello world"
}
}
server.OnMessage = webSocketMessage => Router.Handle(socket, webSocketMessage, this);
public static class Router
{
static Router()
{
Handlers = new List<BaseHandler>()
{
new ChatHandler(),
// new UsersListHandler(),
new AuthHandler(),
new InvalidHandler()
};
}
private static List<BaseHandler> Handlers { get; }
public static void Handle(IWebSocketConnection socket, string webSocketMessage, IServer server)
{
var messageType = Newtonsoft.Json.JsonConvert
.DeserializeObject<WebSocketMessage<Payloads.ChatMessage>>(webSocketMessage).Type;
foreach (var handler in Handlers)
{
if (handler.CanHandle(socket, messageType, server))
{
handler.Handle(socket, webSocketMessage, server);
return;
}
}
}
}
public abstract class BaseHandler
{
protected abstract string Target { get; }
public abstract void Handle(IWebSocketConnection socket, string webSocketMessage, IServer server);
public virtual bool CanHandle(IWebSocketConnection socket, string messageType, IServer server)
{
return messageType == Target;
}
}
public class AuthHandler : BaseHandler
{
protected override string Target => AuthMessage.Type;
public override bool CanHandle(IWebSocketConnection socket, string messageType, IServer server)
{
return base.CanHandle(socket, messageType, server) && !server.ConnectedSockets.ContainsKey(socket);
}
public override void Handle(IWebSocketConnection socket, string webSocketMessage, IServer server)
{
Authorize(socket, webSocketMessage, server);
}
private void Authorize(IWebSocketConnection socket, string webSocketMessage, IServer server)
{
try
{
var data =
Newtonsoft.Json.JsonConvert.DeserializeObject<WebSocketMessage<AuthMessage>>(webSocketMessage);
if (server.ConnectedSockets.ContainsValue(data.Payload.UserName))
{
DisconnectSocket(socket, data, server);
}
else
{
ConnectSocket(socket, data, server);
}
}
catch (System.Exception e)
{
System.Console.WriteLine(e.ToString());
}
}
}
public class ChatHandler : BaseHandler
{
protected override string Target => ChatMessage.Type;
public override void Handle(IWebSocketConnection socket, string webSocketMessage, IServer server)
{
try
{
var data =
Newtonsoft.Json.JsonConvert.DeserializeObject<WebSocketMessage<ChatMessage>>(webSocketMessage);
var chatMessage = new ChatMessage()
{
UserName = server.ConnectedSockets[socket],
Message = data.Payload.Message
};
SendToAll(chatMessage, server);
}
catch (System.Exception e)
{
System.Console.WriteLine(e.ToString());
}
}
public void SendToAll(ChatMessage chatMessage, IServer server)
{
var message = Helper.BuildMessage(chatMessage);
foreach (var client in server.ConnectedSockets)
{
client.Key.Send(message);
}
}
}
public class InvalidHandler : BaseHandler
{
protected override string Target => string.Empty;
public override bool CanHandle(IWebSocketConnection socket, string messageType, IServer server)
{
return true;
}
public override void Handle(IWebSocketConnection socket, string webSocketMessage, IServer server)
{
var invalidMessage = new Payloads.InvalidMessage()
{
Message = "Обнаружена ошибка. Предоставьте, пожалуйста, эту информацию разработчикам: "
+ webSocketMessage
};
socket.Send(Helper.BuildMessage(invalidMessage));
}
}
public class WebSocketMessage<T> where T : Payloads.BaseMessage
{
public string Type { get; set; }
public T Payload { get; set; }
}
public class BaseMessage
{
protected virtual string MessageType { get; } = string.Empty;
public override string ToString() => MessageType;
}
public partial class AuthMessage : BaseMessage
{
public const string Type = "AUTH_MESSAGE";
public string Message { get; set; }
public StatusCode Status { get; set; }
public string UserName { get; set; }
protected override string MessageType => Type;
}
public class ChatMessage : BaseMessage
{
public const string Type = "CHAT_MESSAGE";
public string Message { get; set; }
public string Time { get; set; } = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
public string UserName { get; set; }
protected override string MessageType => Type;
}
public class InvalidMessage : BaseMessage
{
public const string Type = "INVALID_MESSAGE";
public string Message { get; set; }
protected override string MessageType => Type;
}
if (handler.CanHandle(socket, messageType, server))
{
handler.Handle(socket, webSocketMessage, server);
return;
}
public BaseHandler HandlerFactory(messageType)
switch(messageType)
{
case ChatMessage.Type:
retun new ChatHandler();
break;
case AuthMessage.Type:
retun new AuthHandler();
break;
...
}
}
var handler = Successor.HandlerFactory(messageType);
handler.Handle(socket, webSocketMessage, server);
var handler = Handlers.FirstOdefault(x => x.CanHandle(socket, messageType, server));
if(handle != null)
handler.Handle(socket, webSocketMessage, server);
Handlers[messageType].Handle(socket, webSocketMessage, server);
class HandlerParam
{
public IWebSocketConnection socket { get; set; }
public string webSocketMessage { get; set; }
public IServer server { get; set; }
}
var handlerParam = new HandlerParam
{
...
}
handler.Handle(handlerParam);