You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.5 KiB
92 lines
2.5 KiB
using System.Net.Sockets;
|
|
using System.Text;
|
|
|
|
namespace Housing.Services;
|
|
|
|
public sealed class TcpScpiClient : IScpiClient
|
|
{
|
|
private readonly TcpClient _tcpClient;
|
|
private readonly NetworkStream _stream;
|
|
private readonly int _timeoutMilliseconds;
|
|
|
|
private TcpScpiClient(TcpClient tcpClient, int timeoutMilliseconds)
|
|
{
|
|
_tcpClient = tcpClient;
|
|
_stream = _tcpClient.GetStream();
|
|
_timeoutMilliseconds = timeoutMilliseconds;
|
|
}
|
|
|
|
public static async Task<TcpScpiClient> ConnectAsync(string host, int port, int timeoutMilliseconds)
|
|
{
|
|
var tcpClient = new TcpClient();
|
|
using var cancellation = new CancellationTokenSource(timeoutMilliseconds);
|
|
|
|
try
|
|
{
|
|
await tcpClient.ConnectAsync(host, port, cancellation.Token);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
tcpClient.Dispose();
|
|
throw new TimeoutException($"{host}:{port} 장비 연결 시간이 초과되었습니다.");
|
|
}
|
|
catch
|
|
{
|
|
tcpClient.Dispose();
|
|
throw;
|
|
}
|
|
|
|
return new TcpScpiClient(tcpClient, timeoutMilliseconds);
|
|
}
|
|
|
|
public async Task SendAsync(string command)
|
|
{
|
|
using var cancellation = new CancellationTokenSource(_timeoutMilliseconds);
|
|
var bytes = Encoding.ASCII.GetBytes(command.Trim() + "\n");
|
|
await _stream.WriteAsync(bytes, cancellation.Token);
|
|
await _stream.FlushAsync(cancellation.Token);
|
|
}
|
|
|
|
public async Task<string> QueryAsync(string command)
|
|
{
|
|
await SendAsync(command);
|
|
|
|
using var cancellation = new CancellationTokenSource(_timeoutMilliseconds);
|
|
var buffer = new byte[1024];
|
|
var response = new StringBuilder();
|
|
|
|
while (true)
|
|
{
|
|
int bytesRead;
|
|
try
|
|
{
|
|
bytesRead = await _stream.ReadAsync(buffer, cancellation.Token);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
throw new TimeoutException($"{command} 응답 시간이 초과되었습니다.");
|
|
}
|
|
|
|
if (bytesRead == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
var chunk = Encoding.ASCII.GetString(buffer, 0, bytesRead);
|
|
response.Append(chunk);
|
|
|
|
if (chunk.Contains('\n'))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return response.ToString().Trim();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_stream.Dispose();
|
|
_tcpClient.Dispose();
|
|
}
|
|
}
|
|
|