git_bsmd/AIS/bsmd.AIS2Service/SerialTCPReader.cs

104 lines
2.8 KiB
C#

using log4net;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace bsmd.AIS2Service
{
internal class SerialTCPReader : IAISThread
{
private readonly string _host;
private readonly uint _port;
private readonly ConcurrentQueue<string> _inputQueue;
private bool _stopFlag = false;
private TcpClient tcpSocket;
private Thread _thread;
private static readonly ILog _log = LogManager.GetLogger(typeof(SerialTCPReader));
public SerialTCPReader(string host, uint port, ConcurrentQueue<string> inputQueue)
{
_host = host; _port = port; _inputQueue = inputQueue;
}
private void ReadData()
{
try
{
while (!_stopFlag)
{
if (this.tcpSocket == null || !this.tcpSocket.Connected) this.Connect();
foreach(string line in ReadLines(this.tcpSocket.GetStream(), Encoding.ASCII))
{
_inputQueue.Enqueue(line);
if (_stopFlag) return;
}
}
}
catch(Exception ex)
{
_log.ErrorFormat("Something bad has happened: {0}", ex.Message);
this.FatalErrorOccurred?.Invoke(this, new EventArgs());
}
}
private void Connect()
{
this.tcpSocket = new TcpClient(_host, (int)_port);
_log.InfoFormat("TCP stream connected ({0}:{1})", _host, _port);
}
private static IEnumerable<string> ReadLines(Stream source, Encoding encoding)
{
using(StreamReader reader = new StreamReader(source, encoding))
{
string line;
while((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
#region IAISThread implementation
public event EventHandler FatalErrorOccurred;
public void Start()
{
if (_thread != null) return; // may not run twice
ThreadStart runReader = new ThreadStart(this.ReadData);
_thread = new Thread(runReader);
_thread.Start();
}
public void Stop()
{
if(_thread == null) return;
_stopFlag = true;
_thread.Join();
_thread = null;
}
public string Name
{
get { return "Serial stream reader"; }
}
#endregion
}
}