Select Git revision
ScrollDisplay.prefab
-
Marco Zimmer authored
+Added Scenes: MainMenue, LoadingScreen +Stage: Save-Load fuctionality +Sorted Prefabs and Scripts Folder
Marco Zimmer authored+Added Scenes: MainMenue, LoadingScreen +Stage: Save-Load fuctionality +Sorted Prefabs and Scripts Folder
SallyDocument.cs 12.54 KiB
using System;
using System.Collections.Generic;
using ConnectToSally;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using log4net;
using Apache.NMS;
using Apache.NMS.Util;
using SallySchemas;
namespace SallyConnect
{
/// <summary>
/// Delegate to handle SallyMessages
/// </summary>
/// <param name="msg"></param>
/// <param name="decoded"></param>
public delegate void SallyResponseHandler(IMessage msg, Object decoded);
class SallyDocument
{
#region Constructor
/// <summary>
/// the SallyClient associated to this document.
/// </summary>
public DotNetSallyClient client { get; private set; }
/// <summary>
/// The environmentID of this Document
/// </summary>
public string environmentID { get; private set; }
/// <summary>
/// The interfaces supported by this Document
/// </summary>
public string[] interfaces { get; private set; }
public SallyDocument(DotNetSallyClient client, string environmentID, string[] interfaces)
{
// connect to the client
this.client = client;
// set up environment Id and interfaces
this.environmentID = environmentID;
this.interfaces = interfaces;
}
#endregion
#region Handlers
/// <summary>
/// Contains all doc Queue handlers
/// </summary>
private Dictionary<int, Tuple<Type, SallyResponseHandler>> handlers = new Dictionary<int, Tuple<Type, SallyResponseHandler>>();
/// <summary>
/// contains the number of handlers (for id purposes)
/// </summary>
private int handler_count = 0;
/// <summary>
/// registers a handler for a specific type of message.
/// </summary>
/// <param name="T"></param>
/// <param name="handler"></param>
/// <returns></returns>
public int handleType(Type T, SallyResponseHandler handler)
{
int new_handler_id = handler_count++;
handlers.Add(new_handler_id, new Tuple<Type, SallyResponseHandler>(T, handler));
return new_handler_id;
}
/// <summary>
/// removes a certain handler.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool removeHandler(int id)
{
if(handlers.ContainsKey(id))
{
return handlers.Remove(id);
} else
{
return false;
}
}
/// <summary>
/// calls all handlers.
/// </summary>
/// <param name="msg"></param>
private void handleMessage(IMessage msg)
{
// turn the message into a string.
System.Byte[] content = (msg as IBytesMessage).Content;
String xmlMsg = System.Text.Encoding.Default.GetString(content);
// the object we want to decode.
object decoded;
// iterate over all the handlers
foreach (KeyValuePair<int, Tuple<Type, SallyResponseHandler>> entry in handlers)
{
// get the handler
Tuple<Type, SallyResponseHandler> handler = entry.Value;
// try building a reader
XmlSerializer serializer = new XmlSerializer(handler.Item1);
XmlReader reader = XmlReader.Create(new StringReader(xmlMsg));
// try to decode the object
try
{
decoded = serializer.Deserialize(reader);
} catch (InvalidOperationException) { continue;
} catch (XmlException) { continue; }
// if it is null, continue
if (decoded == null){ continue; }
// and try to handle it.
handler.Item2(msg, decoded);
}
}
#endregion
#region Send & Receive Helpers
/// <summary>
/// responds to a certain message.
/// </summary>
/// <param name="msg"></param>
/// <param name="response"></param>
/// <param name="onResponse"></param>
public void respondToMessage(IMessage msg, IMessage response, MessageListener onResponse = null)
{
// create a temporary queue and consumer
ITemporaryQueue tempQueue = this.client.getSallySession().CreateTemporaryQueue();
IMessageConsumer tempQueueConsumer = this.client.getSallySession().CreateConsumer(tempQueue);
// handle responses if needed
if(onResponse != null)
{
tempQueueConsumer.Listener += onResponse;
}
// set the reply to and ids for the message
response.NMSReplyTo = tempQueue;
response.NMSCorrelationID = msg.NMSCorrelationID;
// finally make a consumer and send the message.
IMessageProducer producer = this.client.getSallySession().CreateProducer(msg.NMSReplyTo);
producer.Send(response);
}
/// <summary>
/// Sends a message.
/// </summary>
/// <param name="msg"></param>
/// <param name="to"></param>
/// <param name="onResponse"></param>
public void sendMessage(IMessage msg, IDestination to, MessageListener onResponse = null)
{
// create a temporary queue and consumer
ITemporaryQueue tempQueue = this.client.getSallySession().CreateTemporaryQueue();
IMessageConsumer tempQueueConsumer = this.client.getSallySession().CreateConsumer(tempQueue);
// handle responses if needed
if (onResponse != null)
{
tempQueueConsumer.Listener += onResponse;
msg.NMSReplyTo = tempQueue;
}
// set the reply to and ids for the message
msg.NMSDestination = to;
// finally make a consumer and send the message.
IMessageProducer producer = this.client.getSallySession().CreateProducer(to);
producer.Send(msg);
}
public void sendMessage(IMessage msg, MessageListener onResponse = null)
{
// send the message to the send Queue
sendMessage(msg, createDestination(sendQueueId), onResponse);
}
/// <summary>
/// creates a message to be sent with Sally
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public IMessage createMessage(object obj)
{
return this.client.getSallySession().CreateTextMessage(
Apache.NMS.Util.XmlUtil.Serialize(obj)
);
}
/// <summary>
/// Returns a destination
/// </summary>
/// <param name="queue"></param>
/// <returns></returns>
public IDestination createDestination(string queue)
{
return SessionUtil.GetDestination(this.client.getSallySession(), "queue://" + queue);
}
/// <summary>
/// Creates a listener for a message.
/// </summary>
/// <param name="T"></param>
/// <param name="handler"></param>
/// <returns></returns>
public MessageListener createListener(Type T, SallyResponseHandler handler)
{
return new MessageListener(msg =>
{
logInfo("hello!!!");
//read the message text
System.Byte[] content = (msg as IBytesMessage).Content;
String xmlMsg = System.Text.Encoding.Default.GetString(content);
// deserialse the message
XmlSerializer serializer = new XmlSerializer(T);
XmlReader reader = XmlReader.Create(new StringReader(xmlMsg));
// and call the handler
handler(msg, serializer.Deserialize(reader));
});
}
#endregion
#region Registration
/// <summary>
/// Contains the ID of the send Queue
/// </summary>
private string sendQueueId;
/// <summary>
/// Registers this document with Sally and starts listening to Heartbeats and messages.
/// </summary>
/// <param name="queueID"></param>
public void register(String queueID = null)
{
// if we do not have a queueId, then we generate one.
if(queueID == null)
{
queueID = "dotnet_client_" + Guid.NewGuid().ToString();
}
//register to the Queue#
IDestination docQueue = SessionUtil.GetDestination(this.client.getSallySession(), "queue://" + queueID);
// build and register a listener
IMessageConsumer regConsumer = this.client.getSallySession().CreateConsumer(docQueue);
regConsumer.Listener += new MessageListener(handleMessage);
// register as a listener
logInfo("Registered document queue listener. ");
//create a request to send
RegisterClientRequest regRequest = new RegisterClientRequest();
regRequest.ListenQueue = queueID;
regRequest.Schemas = interfaces;
regRequest.EnvironmentID = environmentID;
// prepare to send and receive nmessage
IMessage message = createMessage(regRequest);
IDestination dest = createDestination("sally_register");
MessageListener handler = createListener(
typeof(RegisterClientResponse),
new SallyResponseHandler(_handleSallyRegister)
);
// send it.
sendMessage(message, dest, handler);
logInfo("Sent registration message");
}
/// <summary>
/// Handles the registration
/// </summary>
/// <param name="msg"></param>
/// <param name="decoded"></param>
private void _handleSallyRegister(IMessage msg, object decoded)
{
// get the response
RegisterClientResponse response = (RegisterClientResponse)decoded;
logInfo("Got registration response");
// listen to heart beats
logInfo("Registering heartbeat responder...");
handleType(typeof(HeartbeatRequest), new SallyResponseHandler(_handleHeartBeat));
// store the send Queue
sendQueueId = response.SendQueue;
}
#endregion
#region Heartbeats
/// <summary>
/// Handles Heart Beats
/// </summary>
/// <param name="msg"></param>
/// <param name="decoded"></param>
private void _handleHeartBeat(IMessage msg, object decoded)
{
logInfo("Responding to heartbeat request");
// i take your request
HeartbeatRequest request = (HeartbeatRequest)decoded;
// and raise you a response
HeartbeatResponse response = new HeartbeatResponse();
// we send it
respondToMessage(msg, createMessage(response));
}
#endregion
#region Logging
/// <summary>
/// A logger for this document.
/// </summary>
private static readonly ILog logger = LogManager.GetLogger(typeof(SallyDocument));
/// <summary>
/// Generates a log message
/// </summary>
/// <param name="message">Message content</param>
/// <returns></returns>
private string logMessage(string message)
{
return "SallyDocument <" + environmentID + ">: " + message;
}
/// <summary>
/// Logs an info message to console and to the log.
/// </summary>
/// <param name="message"></param>
private string logInfo(string message)
{
string msg = logMessage(message);
logger.Info(msg);
return msg;
}
/// <summary>
/// Logs a warning message to console and to the log.
/// </summary>
/// <param name="message"></param>
private string logWarn(string message)
{
string msg = logMessage(message);
logger.Warn(msg);
return msg;
}
/// <summary>
/// Logs a fatal message to console and to the log.
/// </summary>
/// <param name="message"></param>
private string logFatal(string message)
{
string msg = logMessage(message);
logger.Fatal(msg);
return msg;
}
#endregion
}
}