我正在使用带有signalR的mvc在web上使用telnet模拟器,同时异步发送和接收telnet流,而如果长时间保持循环挂起页面,则无法完成。试过很多解决方案,但没有运气。
以下是在不断查找流字节时卡住的代码。
/// <summary>
/// Wait for data from the telnet server and send it to the emulation.
/// </summary>
public async Task ReadLoop(string connectionId, BaseDecoder decoder, CancellationToken ct, string PanelId)
{
var client = Get(connectionId);
if (client == null) { return; }
string script = string.Empty;
if (string.IsNullOrWhiteSpace(panelScript))
{
panelScript = objAccn.ExecuteQueryPanelScript(Convert.ToInt32(PanelId)).ToString();
script = panelScript.Replace(@"\n", Environment.NewLine);
commands = Regex.Split(script, "\r\n");
}
string loginPrompt = null;
if (PanelId != "1")
loginPrompt = "login: ";
else
loginPrompt = "name?: ";
var login = commands[0];// WebConfigurationManager.AppSettings["login"];
if (!_panelCommands.ContainsKey(0))
_panelCommands.Add(0, true);
var passwordPrompt = WebConfigurationManager.AppSettings["passwordPrompt"];
var password = commands[1];//WebConfigurationManager.AppSettings["password"];
if (!_panelCommands.ContainsKey(1))
_panelCommands.Add(1, true);
var loginAuto = (!String.IsNullOrEmpty(loginPrompt) && !String.IsNullOrEmpty(login));
var passwordAuto = (!String.IsNullOrEmpty(passwordPrompt) && !String.IsNullOrEmpty(password));
var DefaultCommandsForm60 = false;
var DefaultCommandsForm50 = false;
var DefaultScreenm50 = false;
decoder.ScriptFunc = async (string str) =>
{
if (!String.IsNullOrEmpty(str))
{
if (loginAuto && str.EndsWith(loginPrompt, StringComparison.Ordinal))
{
await client.StreamWriter.WriteAsync(login + "\r\n");
loginAuto = false;
str = str.Remove(str.Length - loginPrompt.Length);
}
if (passwordAuto && str.EndsWith(passwordPrompt, StringComparison.Ordinal))
{
await client.StreamWriter.WriteAsync(password + "\r\n");
passwordAuto = false;
str = str.Remove(str.Length - passwordPrompt.Length);
if (PanelId != "1")
DefaultCommandsForm60 = true;
else
DefaultCommandsForm50 = true;
//System.Threading.Thread.Sleep(1500);
}
if (PanelId != "1")
{
if (DefaultCommandsForm60)
{
System.Threading.Thread.Sleep(1500);
await client.StreamWriter.WriteAsync(commands[2] + "\r\n");
if (commands.Length > 2)
{
System.Threading.Thread.Sleep(1500);
await client.StreamWriter.WriteAsync(commands[3] + "\r\n");
}
if (commands.Length > 3)
{
System.Threading.Thread.Sleep(1500);
await client.StreamWriter.WriteAsync(commands[4] + "\r\n");
}
DefaultCommandsForm60 = false;
}
}
else
{
if (DefaultCommandsForm50)
{
if (commands.Length > 1)
{
// System.Threading.Thread.Sleep(2500);
if (!_panelCommands.ContainsKey(3))
{
// System.Threading.Thread.Sleep(1500);
await client.StreamWriter.WriteAsync(commands[3] + "\r\n");
_panelCommands.Add(3, true);
}
else
{
if (commands.Length > 2)
{
if (!_panelCommands.ContainsKey(4))
{
// System.Threading.Thread.Sleep(1500);
await client.StreamWriter.WriteAsync(commands[3] + "\r\n");
_panelCommands.Add(4, true);
}
DefaultCommandsForm50 = false;
}
}
DefaultScreenm50 = true;
}
}
else
{
if (DefaultScreenm50)
if (str.EndsWith("$ "))
{
await client.StreamWriter.WriteAsync("Screen" + "\r\n");
str = str.Remove(str.Length - ("$ ").Length);
DefaultScreenm50 = false;
}
}
}
}
return str;
};
const int bufferSize = 4096;
//if (ns.CanRead)
//{
// byte[] readBuffer = new byte[1024];
// int numBytesRead = 0;
// do
// {
// numBytesRead = ns.Read(readBuffer, 0, readBuffer.Length);
// //var data = Encoding.UTF8.GetString(readBuffer);
// // ss= Encoding.GetEncoding(1252).GetString(readBuffer.ToArray());
// //sb.Append(readBuffer[0].ToString);
// sb.AppendFormat("{0}", Encoding.ASCII.GetString(readBuffer, 0, numBytesRead));
// sb.Replace(Convert.ToChar(24), ' ');
// sb.Replace(Convert.ToChar(255), ' ');
// sb.Replace('?', ' ');
// //sb.Replace(Environment.NewLine, "<br />").ToString();
// }
// while (ns.DataAvailable);
//}
//if (client._stream.CanRead)
//{
// do
// {
// var inBytes = await client.ReadAsync(bufferSize, ct);
// foreach (var b in inBytes)
// {
// await decoder.AddByte(b);
// }
// await decoder.Flush();
// } while (client.IsConnected );
////}
//Disconnect(connectionId);
//var readTask = client.ReadAsync(bufferSize, ct);
while (client.IsConnected && !ct.IsCancellationRequested)
{
if (client._stream.CanRead)
{
var inBytes = await client.ReadAsync(bufferSize, ct);
foreach (var b in inBytes)
{
await decoder.AddByte(b);
}
await decoder.Flush();
}
}
Disconnect(connectionId);
}
}
在上面的方法中,代码的一部分被卡住了,永远不会结束。
while (client.IsConnected && !ct.IsCancellationRequested)
{
if (client._stream.CanRead)
{
var inBytes = await client.ReadAsync(bufferSize, ct);
foreach (var b in inBytes)
{
await decoder.AddByte(b);
}
await decoder.Flush();
}
}
Disconnect(connectionId);
任何建议和帮助都会很明显!