ln.application/ApplicationWebSocket.cs

150 lines
4.9 KiB
C#

using System;
using ln.http.websocket;
using ln.json;
using ln.logging;
using ln.types.rpc;
using ln.http;
using System.Collections.Generic;
using ln.application.slots;
namespace ln.application
{
public class ApplicationWebSocket : WebSocket
{
public IApplicationInterface ApplicationInterface { get; }
Dictionary<string, Func<JSONValue, object>> messageConverters = new Dictionary<string, Func<JSONValue, object>>();
public ApplicationWebSocket(IApplicationInterface applicationInterface,HttpRequest httpRequest)
:base(httpRequest)
{
ApplicationInterface = applicationInterface;
}
public void AddMessageConverter(string messageType, Func<JSONValue, object> converter)
{
messageConverters[messageType] = converter;
}
public Func<JSONValue, object> FindConverter(string messageType)
{
return messageConverters[messageType];
}
public override bool Received(string textMessage)
{
JSONObject json = (JSONObject)JSONParser.Parse(textMessage);
if (!json.ContainsKey("id"))
{
Logging.Log(LogLevel.WARNING, "ApplicatioNWebSocket received json message without id");
return false;
}
long messageID = (long)json["id"].ToNative();
if (!json.ContainsKey("type"))
{
SendError(messageID, "type missing", "ApplicationWebSocket received message without 'type' attribute");
return false;
}
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;
}
}
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);
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()
{
//try
//{
// Logging.Log(LogLevel.DEBUGDETAIL, "ApplicationWebSocket: Received: {0}",textMessage);
// RPCCall rpcCall = json.ToObject<RPCCall>();
// RPCResult rpcResult = Invoke(rpcCall);
// string resultText = JSONObject.From(rpcResult).ToString();
// Logging.Log(LogLevel.DEBUGDETAIL, "ApplicationWebSocket: Sending: {0}", resultText);
// requestContext.WebSocket.Send(resultText);
//}
//catch (Exception e)
//{
// Logging.Log(e);
//}
}
public virtual RPCResult Invoke(RPCCall call)
{
RPCResult result = null;
result = ApplicationInterface.RPCContainer.Invoke(call);
return result;
}
}
}