ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 09.12.2023
Просмотров: 97
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
73 public string PassiveComponents;
[XmlIgnore] static SettingsStorage _instance;
///
/// Gets the loaded instance of
///
///
[XmlIgnore] public static SettingsStorage Instance { get { if (_instance == null) {
Load (_filePath);
} return _instance;
}
} public static void InitMock ()
{
_instance = new SettingsStorage ();
}
///
/// Initializes a new instance of the
///
{
ConnectionString = "your connection string here;";//"Server=localhost;
Port=1972; Namespace=EVENTCLASS; Password=SYS; User ID=_SYSTEM;";
}
[XmlIgnore] const string _filePath = "./settings.xml";
///
/// Load application settings.
///
{ var fi = new FileInfo (path); if (fi.Exists) { var myXmlReader = new StreamReader (_filePath); try {
Deserialize (myXmlReader); myXmlReader.Close ();
} catch {
_instance = null;
} finally { myXmlReader.Dispose ();
}
}
} public static void LoadFromString (string data)
{
74
Deserialize (data);
} static void Deserialize (string data)
{ using (MemoryStream stream = new MemoryStream ()) {
StreamWriter writer = new StreamWriter (stream); writer.Write (data); writer.Flush (); stream.Position = 0; using (var sr = new StreamReader (stream))
Deserialize (sr);
}
} static void Deserialize (StreamReader stream)
{ var mySerializer = new XmlSerializer (typeof(SettingsStorage));
_instance = (SettingsStorage)mySerializer.Deserialize (stream);
}
///
/// Save application settings.
///
{ if (_instance == null) {
_instance = new SettingsStorage ();
} var mySerializer = new XmlSerializer (typeof(SettingsStorage)); var myXmlWriter = new StreamWriter (_filePath); try { mySerializer.Serialize (myXmlWriter, _instance); myXmlWriter.Dispose ();
} finally { myXmlWriter.Dispose ();
}
}
}
}
AppSocket.cs using System; using Akka.Actor; using System.Net.Sockets; using System.IO; using System.Text; using System.Net.Security; using System.Security.Authentication; namespace EvServerSystem.AppSock
{
///
/// Actual application socket, handles communication with applications.
/// Sends everything to parent
///
{
75
IActorRef _parent;
TcpClient _client; string _sysKeyCode;
Stream _stream;
StreamReader _sr;
StreamWriter _sw;
TimeSpan _actorTimeout = TimeSpan.FromSeconds (1); public string SysKeyCode { get { return _sysKeyCode; } } public bool IsEncrypted { get; private set; }
///
/// Initializes a new instance of the
///
///
Parent actor.
///
Application's TCP socket.
public AppSocket (IActorRef sender, TcpClient client)
{
_parent = sender;
_client = client;
}
///
/// Starts the connection, reading first token and entering read loop.
///
{
_stream = _client.GetStream ();
_sr = new StreamReader (_stream, Encoding.UTF8);
_sw = new StreamWriter (_stream, Encoding.UTF8);
_sw.AutoFlush = true; if (_sr.ReadLineAsync ().Result != "EVAPP1") { await _sw.WriteLineAsync ("Unknown version");
StopSocket (); return;
} await _sw.WriteLineAsync ("301 Waiting for system ID");
_sysKeyCode = _sr.ReadLineAsync ().Result; await _sw.WriteLineAsync ("200 Ready to accept commands");
#if DEBUG
Console.WriteLine ("D: Client accepted");
#endif while (true) { string line = ""; try { line = await _sr.ReadLineAsync (); //TODO: make buffered read
} catch {
#if DEBUG
Console.WriteLine ("D: Client dropped");
#endif
StopSocket (); return;
}
#if DEBUG
Console.WriteLine (String.Format ("D: got {0}", line));
#endif
76 switch (line) { case "bye": await _sw.WriteLineAsync ("250 Goodbye");
StopSocket ();
#if DEBUG
Console.WriteLine ("D: Client discon");
#endif return; case "":
_client.Close (); return; case "secure": if (SettingsStorage.Instance.IsSslEnabled) { await _sw.WriteLineAsync ("201 Upgrading"); var ssl = new SslStream (_stream); ssl.AuthenticateAsServer (SettingsStorage.Instance.ServerCert, true,
SslProtocols.Tls12, false);
_sr = new StreamReader (ssl, Encoding.UTF8);
_sw = new StreamWriter (ssl, Encoding.UTF8);
_stream = ssl;
_sw.WriteLine ("200 Encrypted connection has been established.");
IsEncrypted = true;
} else await _sw.WriteLineAsync ("401 SSL is not supported."); break; default: if (SettingsStorage.Instance.AcceptEncryptedOnly && !IsEncrypted) { await _sw.WriteLineAsync ("501 Server accepts encrypted connections only.");
StopSocket (); return;
}
_parent.Tell (line); var task = _parent.Ask (line, _actorTimeout); var resp = (string)task.Result; await _sw.WriteLineAsync (resp); break;
}
}
} void StopSocket ()
{
_client.Close ();
_parent.GracefulStop (TimeSpan.FromSeconds (30));
}
}
}
AppSocketActor.cs using System; using Akka.Actor; using System.Net.Sockets; using Newtonsoft.Json; using System.IO;
77 using EvServerSystem.DB; using Akka.Monitoring; namespace EvServerSystem.AppSock
{
///
/// Actor wrapper for
/// Akka address: /user/local-sys/app/IP:PORT
///
{
AppSocket _asock;
#region IHandle implementation
///
/// Handles the application's TcpClient socket.
///
///
App socket.
public void Handle (TcpClient message)
{
#if DEBUG
Console.WriteLine ("D: new appsock");
#endif
_asock = new AppSocket (Context.Self, message);
Context.IncrementCounter ("init_success"); try {
_asock.StartConnection ();
} catch {
Context.Stop (Context.Self);
}
}
///
/// Handles the string message from underlying
///
///
Message from application.
public void Handle (string message)
{
//TODO: check if connected
#if NOBASE
Context.Sender.Tell ("402 Database is not available."); return;
#else if (DB.DBConnection.Connection == null) {
Context.Sender.Tell ("402 Database is not available."); return;
} var reader = new JsonTextReader (new StringReader (message)); var msg = new DB.Messages.Event.ActualEvent (DBConnection.Connection); msg.KeyValue = new DB.Messages.Event.KeyValueEvent
(DBConnection.Connection);
//msg.ActualEventKeyValue.Message.Add(new ) var currPair = new DB.Messages.Event.KeyValuePair
(DBConnection.Connection); while (reader.Read ()) { switch (reader.TokenType) {
78 case JsonToken.PropertyName: currPair = new DB.Messages.Event.KeyValuePair
(DBConnection.Connection); currPair.Key = reader.Value.ToString (); break; case JsonToken.String: if (currPair != null) { currPair.Value = reader.Value.ToString (); msg.KeyValue.Message.Add (currPair.Key, currPair); if (currPair.Key == "eventCode") { msg.EventCode = long.Parse
(currPair.Value); long res = 0; if (!long.TryParse (currPair.Value, out res)) {
Context.Sender.Tell (2); return;
}
}
} break;
}
} msg.EventNameComponent = _asock.SysKeyCode.ToString ();
//msg.EventCode =
//Context.ActorSelection ("/user/local-sys/db").Tell (msg); var rval = msg.Commit ().Value;
Context.Sender.Tell (rval);
#if DEBUG
Console.WriteLine (String.Format ("D: return value {0}", rval));
#endif
#endif
}
#endregion
///
/// Monitor unhandled messages. Normally should never happen
///
/// protected override void Unhandled (object message)
{
Context.IncrementUnhandledMessage (); base.Unhandled (message);
}
///
/// Monitor actor startup.
///
{
Context.IncrementActorCreated ();
}
///
/// Monitor actor kills.
///
79
{
Context.IncrementActorStopped ();
}
}
}
DBConnection.cs using InterSystems.Data.CacheClient; namespace EvServerSystem.DB
{
///
/// Connection to Cache database.
///
{ static CacheConnection _cacheConnect;
///
/// Read-only connection.
///
///
}
///
/// Creates the connection from specified Cache ConnectionString.
///
///
Connection string.
public static void CreateConnection (string connString)
{
_cacheConnect = new CacheConnection ();
_cacheConnect.ConnectionString = connString;
_cacheConnect.Open ();
System.Console.WriteLine("I: DB connection created.");
}
}
}
ServerSocket.cs using System.Net.Sockets; using Akka.Actor; using System.Net; using System.Threading; using System.Threading.Tasks; namespace EvServerSystem.SSock
{
///
/// Server socket itself, listens for applications to connect and throws each one at parent actor.
///
{ readonly IActorRef _actor;
80 readonly TcpListener _listener; readonly CancellationTokenSource _cancelsrc = new CancellationTokenSource (); public ServerSocket (IActorRef actor, IPEndPoint ep)
{
_actor = actor;
_listener = new TcpListener (ep);
}
///
/// Start listening.
///
{
_listener.Start (); await AcceptConnections ();
}
///
/// Stop listening.
///
{
_cancelsrc.Cancel ();
}
///
/// Main listening loop.
///
///
{ while (!_cancelsrc.IsCancellationRequested) { var cli = await _listener.AcceptTcpClientAsync ();
_actor.Tell (cli);
} return;
}
}
}
ServerSocketActor.cs using System; using Akka.Actor; using EvServerSystem.SSock; using System.Net; using System.Net.Sockets; using Akka.Monitoring; namespace EvServerSystem.SSock
{
///
/// Actor of main server socket actor, manages underlying
///
{
81
ServerSocket _ssock; readonly IPEndPoint _ep;
///
/// Initializes a new instance of the
///
///
IPEndPoint of address to bind to.
public ServerSocketActor (IPEndPoint ep)
{
Console.WriteLine ("I: Application socket created.");
_ep = ep;
}
#region IHandle implementation
///
/// New client connected and ServerSocketActor receives its socket.
///
///
Client socket public void Handle (TcpClient message)
{
//redirect incoming client to main server
Context.Parent.Tell (message);
Context.IncrementMessagesReceived();
#if DEBUG
Console.WriteLine ("D: Client socket received");
#endif
}
///
/// Handles bool message; post-start hook to create
///
///
Anything.
public void Handle (bool message)
{
_ssock = new ServerSocket (Context.Self, _ep);
_ssock.Start ();
}
#endregion
///
/// Monitor unhandled messages. Normally should never happen
///
/// protected override void Unhandled(object message)
{
Context.IncrementUnhandledMessage(); base.Unhandled(message);
}
///
/// Monitor actor startup.
///
{
Context.IncrementActorCreated();
}
82
///
/// Monitor actor kills.
///
{
Context.IncrementActorStopped();
}
}
}
83
КОДЫ МОДУЛЬНЫХ ТЕСТОВ
Приложение В
84 using NUnit.Framework; using System; using System.Net; using System.Net.Sockets; using System.IO; using EvServerSystem.AppSock; using System.Threading.Tasks; using Akka.Actor; using EvServerSystem; using EvServerSystem.SSock; using System.Runtime.InteropServices; namespace VS_test
{
[TestFixture] public class Test
{
[Test] public void AppSocketTest()
{
{ var ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 32767); var _listener = new TcpListener(ep);
_listener.Start() ;
// Server ’ s client ep var sept = _listener.AcceptTcpClientAsync(); var client = new TcpClient(); client.Connect(ep); var writer = new StreamWriter(client.GetStream()); var reader = new StreamReader(client.GetStream());
SettingsStorage.InitMock(); writer.AutoFlush = true;
{ var system = ActorSystem.Create("local−sys"); var asa = system.ActorOf
} writer.WriteLine("EVAPP1");
Assert.AreEqual(reader.ReadLine(), "301 Waiting for system ID" , "Connection proto check "); writer.WriteLine("test−app");
Assert.AreEqual(reader.ReadLine(), "200 Ready to accept commands" ,
"Connection proto check "); writer.WriteLine("gibberish foo"); var resp = reader.ReadLine();
Assert.AreEqual(resp ,"402 Database is not available." ,"Connection proto check");
_listener.Stop();
}
{ var ep = new IPEndPoint ( IPAddress.Parse("127.0.0.1"), 32767); var _listener = new TcpListener(ep);
_listener.Start(); // Server ’ s client ep var sept = _listener.AcceptTcpClientAsync(); var client = new TcpClient(); client.Connect(ep); var writer = new StreamWriter(client.GetStream()); var reader = new StreamReader(client.GetStream());
SettingsStorage.InitMock();
85 writer.AutoFlush = true;
{ var system = ActorSystem.Create(" local−sys "); var asa = system.ActorOf
} writer.WriteLine("something something");
Assert.Throws
_listener.Stop();
}
} class MockServerSocketParent:UntypedActor
{ public MockServerSocketParent(IPEndPoint obj)
{ var ssock = Context.ActorOf(Props.Create(() => new ServerSocketActor(obj)),
"server−socket"); ssock.Tell(true);
} object _lastObj; protected override void OnReceive(object obj)
{
Console.WriteLine(String.Format("Mock ServerSockParent got {0}", obj.GetType().ToString())); if (obj is bool)
{
Context.Sender.Tell(_lastObj);
}
_lastObj = obj;
}
}
[Test] public void ServerSocketTest()
{ var sys = ActorSystem.Create("mock−sys"); var ep = new
IPEndPoint(IPAddress.Any, (int)32768); var mockp = sys.ActorOf(Props.Create(() => new MockServerSocketParent(ep)),
"mock−parent");
System.Threading.Thread.Sleep(500); var client = new TcpClient(); client.Connect(IPAddress.Parse("127.0.0.1"), (int)32768);
System.Threading.Thread.Sleep(1000); var connt = mockp.Ask(true, TimeSpan.FromSeconds(5)); var conn = connt.Result;
Assert.IsTrue(conn is TcpClient, String.Format("Got {0}",conn.GetType()));
}
[Test] public void SettingsStorageTest()
{
Assert.Throws
SettingsStorage.LoadFromString("erroneous xml"));
}
}
}