Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Microsoft.Extensions.Logging;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Eventing.Reader;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading.Tasks;
- using Prescott.Messages;
- namespace Prescott
- {
- public class PrescottTcpClient: IDisposable
- {
- private Socket _server;
- private NetworkStream _networkStream;
- private StreamReader _streamReader;
- private StreamWriter _streamWriter;
- private readonly IPAddress _ipAddress;
- private readonly int _port;
- private readonly string _username;
- private readonly string _password;
- private const int Timeout = 120000; // milliseconds
- private bool _isDisposing = false;
- private bool _closeConnection = false;
- private long _openSequenceNumber;
- private readonly ILogger<PrescottTcpClient> _logger;
- public PrescottTcpClient(IPAddress ipAddress, int port, string username, string password, ILoggerFactory loggerFactory)
- {
- this._ipAddress = ipAddress;
- this._port = port;
- this._username = username;
- this._password = password;
- _logger = loggerFactory.CreateLogger<PrescottTcpClient>();
- }
- public void Start()
- {
- _closeConnection = false;
- var ipep = new IPEndPoint(_ipAddress, this._port);
- _server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- try
- {
- _logger.LogInformation("Connecting to {1}:{2}", DateTime.Now, _ipAddress, _port);
- _server.Connect(ipep);
- }
- catch (SocketException ex)
- {
- // TODO Do we want to retry a few times? Failover?
- _logger.LogError("Unable to connect to server. Ex {0}", ex.ToString());
- return;
- }
- _networkStream = new NetworkStream(_server);
- _streamReader = new StreamReader(_networkStream);
- _streamWriter = new StreamWriter(_networkStream);
- Login();
- EventLoop();
- }
- private void Login()
- {
- var login = $"loginmessage";
- _streamWriter.WriteLine(login);
- _streamWriter.Flush();
- _logger.LogTrace(login);
- }
- // If the message ID's skip, we want to request missed messages
- private void GetSnapshot(long priorSequenceNumber, long currentSequenceNumber)
- {
- var snapshot = $"requestMissedMessages";
- _streamWriter.WriteLine(snapshot);
- _streamWriter.Flush();
- _logger.LogInformation(snapshot);
- }
- private void EventLoop()
- {
- var reconnect = false;
- try
- {
- while (!_closeConnection)
- {
- var data = _streamReader.ReadLineAsync();
- var hasMessage = data.Wait(Timeout);
- if (hasMessage)
- {
- try
- {
- var message = Mapper.ToPrescottMessage(data.Result);
- if (message is Message1)
- HandleMessage((Message1)message);
- else if (message is Message2)
- HandleMessage((Message2)message);
- /*
- * More message types here
- */
- MessageRecieved?.Invoke(this, message);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex.ToString());
- }
- }
- else
- {
- //Attempt to reconnect, because the timeout was hit.
- //TODO Reconnect limit maybe?
- _logger.LogInformation("Server did not respond, reconnecting");
- _closeConnection = true;
- reconnect = true;
- }
- }
- }
- catch (Exception ex)
- {
- //TODO Handle Server force shut downs
- _logger.LogError(ex.ToString());
- }
- if (reconnect)
- Restart();
- }
- public event EventHandler<MsrbMessage> MessageRecieved;
- #region Message Handlers
- private void HandleMessage(Message1 message)
- {
- // do stuff
- }
- private void HandleMessage(Message2 message)
- {
- // do stuff
- }
- /*
- * 5 or 6 different HandleMessage Methods here, all messages
- * inherit from abstract base "message"
- */
- #endregion
- public void Dispose()
- {
- if (!_isDisposing)
- Close();
- }
- public void Restart()
- {
- Close();
- Start();
- }
- public void Close()
- {
- _closeConnection = true;
- //_server?.Shutdown(SocketShutdown.Both); // This might displose the streams and network..
- _server?.Dispose();
- _streamReader?.Dispose();
- _streamWriter?.Dispose();
- _networkStream?.Dispose();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement