SERemoteControl/SEClient/SECommandDispatcher.cs
longfellowJian 76792ef9ad 初始化
2025-03-27 16:06:44 +08:00

223 lines
6.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using log4net;
using MT.pHLab.SE.V1;
using MT.Platform.Common;
using SERemoteLib;
using Services.NotificationBroker.Notifications;
namespace SERemoteConnection
{
public abstract class AbstractCommand
{
private ManualResetEvent m_eventResponse;
private int m_requestId;
static int mg_requestId = 300000000;
public AbstractCommand()
{
m_eventResponse = new ManualResetEvent(false);
m_requestId = mg_requestId++;
}
public int GetRequestId()
{
return m_requestId;
}
public abstract bool OnResponse(XmlReader reader);
public abstract bool Submit(SEConnection connection);
public void setResponse()
{
m_eventResponse.Set();
}
public bool WaitForResponse()
{
return m_eventResponse.WaitOne();
}
}
public abstract class ResultMessageSubscriber : ISubscriber
{
public string ObserverName { get; private set; }
public ResultMessageSubscriber(string name)
{
this.ObserverName = name;
}
public abstract void Update( uint jobId, string xmlResultMessage );
}
interface ISubscriber
{
void Update( uint jobId, string xmlResultMessage );
}
public class CommandDispatcher
{
private static readonly ILog logger = LogManager.GetLogger(typeof(CommandDispatcher));
private List<AbstractCommand> m_commandList;
private SEConnection m_connection;
private List<ResultMessageSubscriber> m_observers = new List<ResultMessageSubscriber>();
public CommandDispatcher(SEConnection connection)
{
m_connection = connection;
m_connection.OnTelegram = new OnTelegramDelegate(this.OnTelegram);
m_commandList = new List<AbstractCommand>();
}
~CommandDispatcher()
{
}
public void Subscribe(ResultMessageSubscriber observer)
{
m_observers.Add(observer);
}
public void Unsubscribe(ResultMessageSubscriber observer)
{
m_observers.Remove(observer);
}
public bool Submit(AbstractCommand command)
{
bool success = false;
m_commandList.Add(command);
if (command.Submit(m_connection))
{
success = command.WaitForResponse();
}
return success;
}
public bool OnResponse(XmlReader reader)
{
bool success = false;
int requestId = Int32.Parse(reader.GetAttribute("requestId"));
if (requestId >= 0)
{
foreach (var iCommand in m_commandList)
{
if (iCommand.GetRequestId() == requestId)
{
success= iCommand.OnResponse(reader);
m_commandList.Remove(iCommand);
break;
}
}
}
return success;
}
private void OnResultMessage(uint jobId, XmlReader reader)
{
string xmlResultMessage = reader.ReadOuterXml();
m_observers.ForEach(x => x.Update(jobId, xmlResultMessage));
try
{
ResultMessage rm = SEResultMessageSerializer.Deserialize(xmlResultMessage);
Log(string.Format(CultureInfo.InvariantCulture, "notifyAnalysisResult: #{0} {1}"
, jobId
, SEResultMessageSerializer.SerializeString(rm)
));
}
catch (Exception ex)
{
Log(string.Format(CultureInfo.InvariantCulture, "notifyAnalysisResult: #{0} ERROR DESERIALIZING \n{1}\n{2}"
, jobId, ex.ToString(), xmlResultMessage));
}
}
//<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
//<Telegram xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="LancePlatform">
// <Notification jobId="1">
// <method>
// <mf type="MFTitleRecord">
// <param-list>
// ...
private void OnNotification(XmlReader reader)
{
string jobId = reader.GetAttribute("jopId");
if (reader.Read())
{
if (reader.Name.Equals("ResultMessage") && (reader.NodeType == XmlNodeType.Element))
{
uint id = Convert.ToUInt32(jobId, 16);
OnResultMessage(id, reader);
}
else
if (reader.Name.Equals("EndOfMethod") && (reader.NodeType == XmlNodeType.Element))
{
}
}
}
public void OnTelegram(byte[] telegram)
{
UTF8Encoding utf8 = new UTF8Encoding();
string dump = utf8.GetString(telegram);
logger.DebugFormat("OnTelegram: {0}", dump);
using (XmlReader reader = XmlReader.Create(new StringReader(dump)))
{
if (reader.ReadToFollowing("Telegram"))
{
if (reader.Read())
if (reader.Name.Equals("Response") && (reader.NodeType == XmlNodeType.Element))
{
OnResponse(reader);
}
else
if (reader.Name.Equals("Notification") && (reader.NodeType == XmlNodeType.Element))
{
OnNotification(reader);
}
}
}
}
/// <summary>
/// Logs the specified text by raising the LogWritten event.
/// </summary>
/// <param name="text">The text.</param>
private void Log(string text)
{
text = "[C] " + text;
NotificationBroker.Send(new LogWrittenNotification { Text = text, Sender = this.GetType().FullName, Stamp = DateTime.Now }, NotificationScope.Local);
}
}
}