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已关闭没法发送
...全文
528 5 打赏 收藏 转发到动态 举报
写回复
用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
HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件、客户端组件和Agent组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/C++、C#、Delphi、E(易语言)、Java、Python 等编程语言接口。HP-Socket 对通信层实现完全封装,应用程序不必关注通信层的任何细节;HP-Socket 提供基于事件通知模型的 API 接口,能非常简单高效地整合到新旧应用程序中。    为了让使用者能方便快速地学习和使用 HP-Socket ,迅速掌握框架的设计思想和使用方法,特此精心制作了大量 Demo 示例(如:PUSH 模型示例、PULL 模型示例、PACK 模型示例、性能测试示例以及其它编程语言示例)。HP-Socket 目前运行在 Windows 平台,将来会实现跨平台支持。 [15:47 2018/11/05] 同步更新到5.4.2正式版 [10:37 2018/10/23] 1、英文模块IHttpSyncClient组件大改 2、IWinHttp组件添加若干命令(PS:忘记是哪些了。。。) 3、升级到5.4.2 rc3 版本 4、增加client同步例子 [10:30 2018/9/25] v5.4.2 更新: > SSL 组件更新: ----------------- 1、SSL 组件可以手工启动 SSL 握手,从而可以对 SSL/Https 通信执行代理服务器设置等前置操作 2、SSL 组件(Server/Agent/Client)增加以下接口方法支持手工启动 SSL 握手 1) StartSSLHandShake():手工启动 SSL 握手,当通信组件设置为非自动握手时,需要调用本方法启动 SSL 握手 2) SetSSLAutoHandShake():设置通信组件握手方式(默认:TRUE,自动握手) 3) IsSSLAutoHandShake():获取通信组件握手方式 > 其他功能更新: ----------------- 1、所有可能导致 Socket 关闭的组件接口方法都在 Socket 通信线程异步触发 OnClose 事件 2、Server 与 Agent 组件的 DIRECT 发送策略也支持通过 GetPendingDataLength() 方法实现流控 3、Server 与 Agent 组件的 Disconnect() 方法不再支持‘非强制断开’(仍然保留bForce 参数),调用时都会强制断开 4、OnSend 事件支持 三种同步策略 1) OSSP_NONE:不同步(默认) 1) OSSP_CLOSE:同步 OnClose 1) OSSP_RECEIVE:同步 OnClose 和 OnReceive(只用于 TCP 组件) > 升级说明: ----------------- 1、HP-Socket v5.4.2 完全兼容 HP-Socket v5.4.1 版本,可以直接替换升级 [18:41 2018/8/27] 1、修复英文模块submit_task最后一个参数错误问题,莫名其妙变成了字节集 [11:04 2018/8/27] 1、更新hpsocket为 beta11 2、submit_task 提交的任务不用去管回调里面的ptask参数。内部自动处理。 [16:57 2018/8/24] 1、修复中文模块部分命令错误问题 2、修复英文模块几处命令错误问题 3、增加websocket例程,本来httpclient里面人,有些人就是装看不见。 4、更新hpsocket为 beta9 [12:57 2018/8/15] 1、修复模块汇编的bug,原因是取消了ww汇编库 [11:55 2018/8/15] 1、模块更新为beta8 2、新增api: HP_Agent_IsConnected  -->  Agent.IsConnected() HP_Client_IsConnected  -->  Client.IsConnected() HP_Server_IsConnected  -->  Server.IsConnected() [9:18 2018/8/6] 1、性能优化 2、由于某些人吐槽中文版模块吐槽的厉害,遂决定不再更新中文版。 3、\demo\old 目录下放的是以前旧的例程源码,并不再更新 [12:57 2018/8/1] 修改模块IBufferPtr类,具体调用方式查看 TestEcho-New-Agent.e TestEcho-New-Server.e TestEcho-Http-Serve.e TestEcho-Http-Serve-bigfile.e  改名为 TestEcho-Ht

110,571

社区成员

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

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

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