ln.application/ApplicationWebSocket.cs

152 lines
5.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-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-04 09:57:20 +01:00
public IApplicationInterface ApplicationInterface { get; }
Dictionary<string, Func<JSONValue, object>> messageConverters = new Dictionary<string, Func<JSONValue, object>>();
public ApplicationWebSocket(IApplicationInterface applicationInterface,HttpRequest httpRequest)
:base(httpRequest)
2019-08-20 08:33:38 +02:00
{
2019-11-04 09:57:20 +01:00
ApplicationInterface = applicationInterface;
2019-08-20 08:33:38 +02:00
}
2019-11-04 09:57:20 +01:00
public void AddMessageConverter(string messageType, Func<JSONValue, object> converter)
{
messageConverters[messageType] = converter;
}
2019-08-20 08:33:38 +02:00
2019-11-04 09:57:20 +01:00
public Func<JSONValue, object> FindConverter(string messageType)
{
return messageConverters[messageType];
}
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);
return ReceivedMessage(messageId, messageType, convertedMessage);
} catch (Exception e)
{
Logging.Log(e);
SendError(messageId, e.ToString(), e.InnerException.ToString());
return false;
}
2019-11-04 09:57:20 +01:00
}
public virtual bool ReceivedMessage(long messageId, string messageType, object message)
{
switch (messageType)
{
case "RPCCall":
SendMessage(messageId, ApplicationInterface.RPCContainer.Invoke(message as RPCCall));
return true;
case "SlotRequest":
SlotAllocation slotAllocation = ApplicationInterface.BinarySlots.RequestSlot(message as SlotRequest);
return true;
default:
return false;
}
}
public override bool Received(byte[] binaryMessage)
{
return base.Received(binaryMessage);
}
public void SendMessage(long messageID, object message)
{
string messageType = message.GetType().Name;
JSONObject jsonMessage = 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);
}
public void a()
2019-08-20 08:33:38 +02:00
{
try
{
Logging.Log(LogLevel.DEBUGDETAIL, "ApplicationWebSocket: Received: {0}",textMessage);
JSONObject json = (JSONObject)JSONParser.Parse(textMessage);
RPCCall rpcCall = json.ToObject<RPCCall>();
requestContext.HttpRequest.HTTPServer.ThreadPool.Enqueue(() =>
{
RPCResult rpcResult = Invoke(rpcCall);
string resultText = JSONObject.From(rpcResult).ToString();
2019-08-20 08:33:38 +02:00
Logging.Log(LogLevel.DEBUGDETAIL, "ApplicationWebSocket: Sending: {0}", resultText);
requestContext.WebSocket.Send(resultText);
});
2019-08-20 08:33:38 +02:00
}
catch (Exception e)
{
Logging.Log(e);
}
}
public virtual RPCResult Invoke(RPCCall call)
{
RPCResult result = null;
2019-11-04 09:57:20 +01:00
result = ApplicationInterface.RPCContainer.Invoke(call);
2019-08-20 08:33:38 +02:00
return result;
}
}
}