websocket + 异步task 线程死循环

w_hair 2017-03-24 06:55:45
参考的这种示例写法:http://blog.csdn.net/sq111433/article/details/29856857
现在做的是用websocket建立链接,然后服务器定时推送消息到客户端(global里面写的Timer定时执行一个向当前websocket发送消息的方法)。

public HttpResponseMessage Comm(string ticket)
{
if (HttpContext.Current.IsWebSocketRequest)
{
HttpContext.Current.AcceptWebSocketRequest(OfflineMessage);
}
return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
}

/// <summary>
/// 发送离线消息
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private async Task OfflineMessage(AspNetWebSocketContext context)
{
WebSocket socket = context.WebSocket;
if (!httpResult.Result)
{
//当前用户不存在or失效(记录错误)
return;
}
string userGuid = new SSOHelper().GetUserGUID();
try
{
if (!IsExist(userGuid))
{
RemoveUser(userGuid);
AddUser(userGuid, socket);
}
string result = new MessageBLL().GetMessage(userGuid);
if (!string.IsNullOrEmpty(result))
{
//将消息推送到客户端
await socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(result)), WebSocketMessageType.Text, true, CancellationToken.None);
//SendMessageSuccess(result);
}
while (true)
{
if (socket.State != WebSocketState.Open)
{
RemoveUser(userGuid);
break;
}
}
}
catch (Exception)
{
//整体异常处理移除当前用户
RemoveUser(userGuid);
//throw;
}
}

现在问题就是我的websocket链接建立好以后,iis的CPU使用就开始直线上升了……页面刷新三次后就超级卡,不知道是不是上面方法里的while的原因,但是要是不写while的话,我global里写的定时执行另一个方法调用当前用户websocket发送消息就会提示socket已关闭没法发送
...全文
561 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
w_hair 2017-03-25
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
如果说你看的博客上对于每一个“读取数据”动作都使用一个“死循环+阻塞”线程,还可以理解,那么你为了“等待”Send操作而再弄死循环就太奇怪了。 任何时候要发送数据,你从进程的设置的集合(例如一个 Dictionary<string, WebSocket>,其中你的 ticket 为字典的 key)种取得用于发送的 WebSocket 对象,直接执行其 Send 方法就行了。如果不需要发送消息,什么都不用做,不会执行任何一行代码。怎么会占用CPU还在那循环使用呢? 如果你说“提示socket已关闭没法发送”,那就有 bug,解决 bug 就行了,解决了就能前进一步。不能因此而胡乱拼凑一个交差。
我又查了一下。那个等待Send操作我现在已经去掉了。也不要那个定时器来等Send操作了。实际上这是个Send是第二个问题,怪我没说清楚。关键就是使用的时候对这个理解不透,逻辑条理不够清晰想着解决问题来实现,实现过程中又遇到问题,所以来请教了,“如果你说“提示socket已关闭没法发送”,那就有 bug,解决 bug 就行了,解决了就能前进一步。不能因此而胡乱拼凑一个交差。”谢谢sp老师!鄙人也没想过胡乱拼凑来交差(感觉有点儿蒙)。至于学习设计模式什么的肯定也会去学习,不过与我当下并无太大关联(当然目光长远些总是对嘛)
w_hair 2017-03-25
  • 打赏
  • 举报
回复
引用 1 楼 shingoscar 的回复:
1、基本可以确定是while引起的 2、这种做法有问题,建议使用现成的库来维持连接:https://github.com/SignalR/SignalR/wiki/PersistentConnection
以前用过这个,具体不作讨论用哪个。只是当前这种使用方式有问题,想就目前这种方式而言改进解决下这个问题。
  • 打赏
  • 举报
回复
要学习到设计的模式,肯定比学习到一些雕虫小技更需要悟性。就好像你学习了所有厨师的招式、能把10斤土豆切成1毫米不到的薄片,那么要把土豆丝炒得好吃也要懂得流程、理念。不能用蛮力、抠字眼儿,要用悟性。因此要学设计模式,放弃那些很明显就分析出为什么低效率的模式。
  • 打赏
  • 举报
回复
如果说你看的博客上对于每一个“读取数据”动作都使用一个“死循环+阻塞”线程,还可以理解,那么你为了“等待”Send操作而再弄死循环就太奇怪了。 任何时候要发送数据,你从进程的设置的集合(例如一个 Dictionary<string, WebSocket>,其中你的 ticket 为字典的 key)种取得用于发送的 WebSocket 对象,直接执行其 Send 方法就行了。如果不需要发送消息,什么都不用做,不会执行任何一行代码。怎么会占用CPU还在那循环使用呢? 如果你说“提示socket已关闭没法发送”,那就有 bug,解决 bug 就行了,解决了就能前进一步。不能因此而胡乱拼凑一个交差。
Poopaye 2017-03-24
  • 打赏
  • 举报
回复
1、基本可以确定是while引起的 2、这种做法有问题,建议使用现成的库来维持连接:https://github.com/SignalR/SignalR/wiki/PersistentConnection

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧