150 lines
4.9 KiB
C#
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;
|
|
}
|
|
}
|
|
|
|
}
|