Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#Web MVC 5项目中不断阅读SslStream_C#_Multithreading_Visual Studio_Sslstream - Fatal编程技术网

在C#Web MVC 5项目中不断阅读SslStream

在C#Web MVC 5项目中不断阅读SslStream,c#,multithreading,visual-studio,sslstream,C#,Multithreading,Visual Studio,Sslstream,tl;dr:“我想用C#连续阅读SSL流,但我想不出最好的方法。” 一些背景:我从一个流中获取股票数据,我想在一个web界面中显示它。该流每5秒发送一次心跳,您还可以订阅/取消订阅股票价格和新闻等 目前,我正在使用MSDN示例中的SslTcpClient来读取和写入流,它工作正常 我的问题是,流不断地发送数据,我真的不确定如何使用这些数据并以最佳方式呈现它们 我现在的解决方案是每五秒钟进行一次ajax调用,以“清除”流并获取新数据。这感觉不像是一个健壮的解决方案,我经常会遇到错误“当另一个读

tl;dr:“我想用C#连续阅读SSL流,但我想不出最好的方法。”

一些背景:我从一个流中获取股票数据,我想在一个web界面中显示它。该流每5秒发送一次心跳,您还可以订阅/取消订阅股票价格和新闻等

目前,我正在使用MSDN示例中的SslTcpClient来读取和写入流,它工作正常

我的问题是,流不断地发送数据,我真的不确定如何使用这些数据并以最佳方式呈现它们

我现在的解决方案是每五秒钟进行一次ajax调用,以“清除”流并获取新数据。这感觉不像是一个健壮的解决方案,我经常会遇到错误“当另一个读取操作挂起时无法调用读取方法”

更新:

@phuzi:ajax和SignalR调用之间的区别如下。不幸的是,这不能帮助我连续读取流,因为我仍然需要每五秒钟调用一次该方法。解决方案可能是将Hangfire与Signal结合使用,尽管我不知道如何最好地实现这一点

$.connection.hub.start().done(函数(){
setInterval(函数(){
stockHub.server.getHeartBeat();
}, 5000);
});
setInterval(函数(){
$.ajax({
url:“@url.Action(“getHeartBeat”)”,
键入:“POST”,
数据:{
},
成功:功能(消息){
控制台日志(消息);
},
错误:函数(){
}
);
}, 5000);
@usr:以下是一些示例数据:

我使用此字符串订阅特定市场的股票深度

“{”cmd:“subscribe”,“args:{”t:“depth”,“i:“5110”,“m”:11}}\n“

然后,我读取提要并向我的read方法添加一个期望值,响应应该包含该值,以成为我正在查找的字符串,例如:

response.Contains("{"type":"depth","data":{"i":"5110","m":11")
然后我得到一个字符串,作为回报,它看起来像这样:

"{"type":"depth","data":{"i":"5110","m":11,"tick_timestamp":1439894747189,"bid1":1.02,"bid_volume1":734827,"bid_orders1":30,"ask1":1.03,"ask_volume1":393598,"ask_orders1":8,"bid2":1.01,"bid_volume2":805705,"bid_orders2":35,"ask2":1.04,"ask_volume2":404815,"ask_orders2":15,"bid3":1.00,"bid_volume3":1387177,"bid_orders3":62,"ask3":1.05,"ask_volume3":601579,"ask_orders3":29,"bid4":0.995,"bid_volume4":123610,"bid_orders4":9,"ask4":1.06,"ask_volume4":313060,"ask_orders4":15,"bid5":0.990,"bid_volume5":386543,"bid_orders5":31,"ask5":1.07,"ask_volume5":741100,"ask_orders5":11}}"
使用锁解决了“当另一个读取操作挂起时无法调用读取方法”错误

私有静态只读对象_readBytesLock=new object();
私有静态易失性bool_readingBytes=false;
公共静态字符串ReadMessage(SslStream SslStream,string expectedValue=“heartbeat”)
{
//阅读服务器发送的消息。
//使用
//”“马克。
字符串消息;
字节[]缓冲区=新字节[2048];
StringBuilder messageData=新建StringBuilder();
int字节=-1;
做
{
//字节=sslStream.Read(缓冲区,0,缓冲区长度);
字节=GetBytes(sslStream,buffer);
//使用Decoder类将字节转换为UTF8
//如果一个字符跨越两个缓冲区。
解码器解码器=Encoding.UTF8.GetDecoder();
char[]chars=new char[decoder.GetCharCount(缓冲区,0,字节)];
GetChars(缓冲区,0,字节,字符,0);
message=messageData.Append(chars.ToString();
Debug.WriteLine(messageData);
if(message.Contains(expectedValue))
{
返回消息;
}
if(Regex.Matches(messageData.ToString(),“heartbeat”).Count>=3)
{
WriteLine(“出现了一些问题,接收到3个心跳,没有任何与预期值一致的内容:“+expectedValue”);
返回消息;
}
}while(字节!=0);
返回消息;
}
公共静态int GetBytes(SslStream SslStream,byte[]缓冲区)
{
尝试
{
if(buffer==null)
返回-1;
var字节=-1;
锁(_readBytesLock)
{
如果(!\u读取字节)
{
_readingBytes=true;
字节=sslStream.Read(缓冲区,0,缓冲区长度);
}
_readingBytes=false;
返回字节;
}
}
捕获(例外情况除外)
{
var methodName=System.Reflection.MethodBase.GetCurrentMethod().Name;
Debug.WriteLine(“方法”+methodName+“失败”+ex.Message);
返回0;
//投掷;
}
}

最后一段代码运行得非常好。非常感谢@usr和其他人的帮助

private Task\u feedTask;
私有SslStream _SslStream;
私人StreamReader_StreamReader;
专用静态只读log4net.ILog\u记录器
=log4net.LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod()
.DeclaringType);
public void CreateNewTaskAndStartReadingFeed()
{
_feedTask=新任务(()=>StartReadingFeed());
_feedTask.Start();
}
public void startedingfeed()
{
尝试
{
while(true)
{
var message=GetStreamMessage();
如果(消息!=null)
{
Debug.WriteLine(“StartReadingFeed message:+message”);
收到某件东西(信息);
}
其他的
{
WriteLine(“StartReadingFeed消息为空”);
}
}
}
捕获(例外情况除外)
{
var methodName=System.Reflection.MethodBase.GetCurrentMethod().Name;
Debug.WriteLine($“Method{methodName}失败”+ex.Message);
WriteLine(“创建新任务并再次开始reed提要”);
_logger.错误(“StartReadingFeed失败”,ex);
CreateNewTaskAndStartReadingFeed();
}
}
公共字符串GetStreamMessage()
{
尝试
{
返回_sslStream.CanRead?_streamReader.ReadLine():null;
}
捕获(例外情况除外)
{
var methodName=System.Reflection.MethodBase.GetCurrentMethod().Name;
Debug.WriteLine($“Method{methodName}失败”+ex.Message);
_错误($“{methodName}失败。”,ex);
返回null;
}
}

您看过signalR吗?您能举例说明服务器发送数据所使用的格式吗?It i