ln.application/ApplicationWebSocket.cs

165 lines
6.1 KiB
C#
Raw Normal View History

2019-08-20 08:33:38 +02:00
using System;
using ln.http.websocket;
using ln.json;
using ln.logging;
using ln.types.rpc;
2019-11-04 09:57:20 +01:00
using ln.http;
using System.Collections.Generic;
using ln.application.slots;
2019-11-15 13:46:08 +01:00
using ln.json.mapping;
using ln.identities;
2019-11-26 12:22:09 +01:00
using ln.application.messages;
using ln.http.resources;
2019-08-20 08:33:38 +02:00
namespace ln.application
{
2019-11-04 09:57:20 +01:00
public class ApplicationWebSocket : WebSocket
2019-08-20 08:33:38 +02:00
{
2019-11-15 13:46:08 +01:00
static Dictionary<string, Func<JSONValue, object>> messageConverters = new Dictionary<string, Func<JSONValue, object>>();
static public void RegisterMessageConverter(string messageType, Func<JSONValue, object> converter) => messageConverters[messageType] = converter;
static public Func<JSONValue, object> FindConverter(string messageType) => messageConverters[messageType];
2019-11-04 09:57:20 +01:00
2019-11-15 13:46:08 +01:00
public Application Application { get; }
2019-11-26 12:22:09 +01:00
public ApplicationSession ApplicationSession => (Hello != null) ? Application.GetApplicationSession(Hello.ApplicationSessionID) : null;
2019-11-04 09:57:20 +01:00
2019-11-26 12:22:09 +01:00
public WSHello Hello { get; set; }
2019-08-20 08:33:38 +02:00
2019-11-15 13:46:08 +01:00
static ApplicationWebSocket()
2019-11-04 09:57:20 +01:00
{
2019-11-26 12:22:09 +01:00
RegisterMessageConverter("WSHello", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(WSHello)));
2019-11-15 13:46:08 +01:00
RegisterMessageConverter("RPCCall", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(RPCCall)));
RegisterMessageConverter("SlotRequest", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(SlotRequest)));
RegisterMessageConverter("AuthenticationProve", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(AuthenticationProve)));
RegisterMessageConverter("AuthenticationRequest", (JSONValue json) => JSONMapper.DefaultMapper.FromJson(json, typeof(AuthenticationRequest)));
2019-11-04 09:57:20 +01:00
}
2019-08-20 08:33:38 +02:00
2019-11-15 13:46:08 +01:00
public ApplicationWebSocket(Application application, HttpRequest httpRequest)
: base(httpRequest)
2019-11-04 09:57:20 +01:00
{
2019-11-15 13:46:08 +01:00
Application = application;
2019-11-04 09:57:20 +01:00
}
2019-08-20 08:33:38 +02:00
2019-11-04 09:57:20 +01:00
public override bool Received(string textMessage)
{
JSONObject json = (JSONObject)JSONParser.Parse(textMessage);
2019-08-20 08:33:38 +02:00
2019-11-04 09:57:20 +01:00
if (!json.ContainsKey("id"))
{
Logging.Log(LogLevel.WARNING, "ApplicatioNWebSocket received json message without id");
return false;
}
2019-08-20 08:33:38 +02:00
2019-11-04 09:57:20 +01:00
long messageID = (long)json["id"].ToNative();
2019-08-20 08:33:38 +02:00
2019-11-04 09:57:20 +01:00
if (!json.ContainsKey("type"))
{
SendError(messageID, "type missing", "ApplicationWebSocket received message without 'type' attribute");
return false;
}
2019-08-20 08:33:38 +02:00
2019-11-04 09:57:20 +01:00
string messageType = json["type"].ToNative() as string;
JSONValue message = json.ContainsKey("message") ? json["message"] : JSONNull.Instance;
return ReceivedMessage(messageID,messageType,message);
}
public virtual bool ReceivedMessage(long messageId,string messageType,JSONValue message)
{
try
{
object convertedMessage = FindConverter(messageType)(message);
2019-11-15 13:46:08 +01:00
ReceivedMessage(messageId, messageType, convertedMessage);
return true;
2019-11-04 09:57:20 +01:00
} catch (Exception e)
{
Logging.Log(e);
2019-11-15 13:46:08 +01:00
SendError(messageId, e.ToString(), e.InnerException?.ToString());
2019-11-04 09:57:20 +01:00
return false;
}
2019-11-04 09:57:20 +01:00
}
2019-11-15 13:46:08 +01:00
public virtual void ReceivedMessage(long messageId, string messageType, object message)
2019-11-04 09:57:20 +01:00
{
2019-11-15 13:46:08 +01:00
ApplicationSession.SetCurrentSession(ApplicationSession);
try
2019-11-04 09:57:20 +01:00
{
2019-11-26 12:22:09 +01:00
object result;
if (message is WSHello hello)
2019-11-15 13:46:08 +01:00
{
2019-11-26 12:22:09 +01:00
if (Hello == null)
{
Hello = hello;
hello.ApplicationSessionID = ApplicationSession.SessionID;
result = hello;
}
else
{
throw new ArgumentException("WSHello already received!");
}
2019-11-15 13:46:08 +01:00
}
2019-11-26 12:22:09 +01:00
else
2019-11-15 13:46:08 +01:00
{
2019-11-26 12:22:09 +01:00
result = ApplicationSession?.ProcessMessage(message);
if (result is null)
{
result = Application.ProcessMessage(message);
}
if (result is null)
{
throw new NotImplementedException();
}
2019-11-15 13:46:08 +01:00
}
SendMessage(messageId, result);
} catch (Exception e)
{
SendError(messageId, e.ToString(), e.InnerException?.ToString());
}
finally
{
ApplicationSession.ClearCurrentSession();
2019-11-04 09:57:20 +01:00
}
}
public override bool Received(byte[] binaryMessage)
{
return base.Received(binaryMessage);
}
public void SendMessage(long messageID, object message)
{
string messageType = message.GetType().Name;
2019-11-15 13:46:08 +01:00
JSONObject jsonMessage = message is JSONObject ? message as JSONObject : JSONObject.From(message);
2019-08-20 08:33:38 +02:00
2019-11-04 09:57:20 +01:00
SendMessage(messageID, messageType, jsonMessage);
}
public virtual void SendMessage(long messageID,string messageType,JSONObject message)
{
JSONObject messageFrame = new JSONObject();
messageFrame["id"] = new JSONNumber(messageID);
messageFrame["type"] = new JSONString(messageType);
messageFrame["message"] = message;
Send(messageFrame.ToString());
}
public virtual void SendError(long messageId, string error, string cause) => SendError(messageId, error, cause, null);
public virtual void SendError(long messageId, string error,string cause,JSONValue details)
{
JSONObject failed = new JSONObject();
failed["message"] = new JSONString(error);
failed["cause"] = new JSONString(cause);
failed["details"] = details;
Logging.Log(LogLevel.WARNING, "ApplicationWebSocket sends error: {0}\n{1}",error,cause);
SendMessage(messageId, "error", failed);
}
2019-08-20 08:33:38 +02:00
}
}