为轮子而生 2022-05-31 16:23 采纳率: 33.3%
浏览 38
已结题

Cowboy.WebSockets遇到问题:无法从传输连接中读取数据

服务端使用Cowboy.WebSockets监听并处理连接,前端使用浏览器内置的WebSocket。

客户端连接服务端:成功。
客户端向服务端发送消息:服务端可正常接收。
服务端向客户端发送消息:第1次,客户端正常接收;第2次发送时报错

错误发生于服务端:

Exception Type: System.IO.IOException
Message: 无法从传输连接中读取数据: 你的主机中的软件中止了一个已建立的连接。。
TargetSite: System.IAsyncResult BeginRead(Byte[], Int32, Int32, System.AsyncCallback, System.Object)
HelpLink: NULL
Source: System
 
Exception StackTrace:
--------------------------------------
   在 System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
   在 System.IO.Stream.<>c.<BeginEndReadAsync>b__43_0(Stream stream, ReadWriteParameters args, AsyncCallback callback, Object state)
   在 System.Threading.Tasks.TaskFactory`1.FromAsyncTrim[TInstance,TArgs](TInstance thisRef, TArgs args, Func`5 beginMethod, Func`3 endMethod)
   在 System.IO.Stream.BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   在 System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   在 System.IO.Stream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count)
   在 Cowboy.WebSockets.AsyncWebSocketSession.<Process>d__65.MoveNext() 位置 Cowboy.WebSockets\Cowboy.WebSockets\Server\AsyncWebSocketSession.cs:行号 398

服务端监听代码:(完全照抄Cowboy的官方示例代码)

var catalog = new AsyncWebSocketServerModuleCatalog();
catalog.RegisterModule(new TestWebSocketModule());
 
var config = new AsyncWebSocketServerConfiguration();
 
var _server = new AsyncWebSocketServer(22222, catalog, config);
_server.Listen();

服务端发送代码:

_server.BroadcastBinaryAsync(Encoding.UTF8.GetBytes(text));
 
或
session.SendTextAsync(text);  //session为用于测试的活动连接

前端代码:

var ws = new WebSocket('ws://127.0.0.1:22222');
console.log('ws连接状态:' + ws.readyState);
 
ws.onopen = function () {
    console.log('ws连接状态:' + ws.readyState);
}
 
ws.onmessage = function (data) {
    console.log('ws接收消息:', data);
}
 
ws.onclose = function () {
    console.log(`ws连接状态:${ws.readyState}`);
}
 
ws.onerror = function (err) {
    console.log('ws发生异常:', err);
}
 
function onsend() {
    var box = document.getElementById('msg');
    ws.send(box.value);
    box.value = '';
}

在两次发送过程中,输出了如下日志:

1次发送
WebSocket server [0.0.0.0:22222] broadcasts binary -> [第1次发送].
第2次发送
WebSocket server [0.0.0.0:22222] broadcasts binary -> [第1次发送].
2022-05-31 17:01:04.7188|DEBUG|Cowboy.WebSockets.AsyncWebSocketSession|Session [SessionKey[c5c9cd05-b53b-4bcb-9a27-30ac0e5e2477], RemoteEndPoint[127.0.0.1:30999], LocalEndPoint[127.0.0.1:22222]] received client side close frame but no status code.
2022-05-31 17:01:04.7228|DEBUG|Cowboy.WebSockets.AsyncWebSocketSession|Session [SessionKey[c5c9cd05-b53b-4bcb-9a27-30ac0e5e2477], RemoteEndPoint[127.0.0.1:30999], LocalEndPoint[127.0.0.1:22222]] sends server side close frame [InvalidPayloadData] [].

能看到第1次发送时,不仅结果是成功的,日志也很干净。而第2次发送,就多了两条日志,似乎是收到了客户端发过来的“请求关闭”指令,我认为这很奇怪,猜测可能是协议不兼容导致,浏览器端大概是不会发送这种指令的,因为经测试使用其他库(如Fleck)作为服务端时不会发生类似异常。
值得注意的是,用Cowboy提供的ClientTest作为客户端测试时,并不会出现以上问题,两端可进行反复通信均正常。

  • 问题猜测1
    难道Cowboy只能对具有特定协议的客户端搭建WebSocket通道,对浏览器无效吗?

  • 问题猜测2
    是不是Cowboy本身的异步代码导致了读取和写入的冲突呢?但是看这个项目已经很多年了,据说在处理高并发连接方面是最成熟的。

特来求解,请不吝赐教!

附Cowboy代码仓库连接(含示例):
https://github.com/gaochundong/Cowboy.WebSockets

  • 写回答

2条回答 默认 最新

      报告相同问题?

      相关推荐 更多相似问题

      问题事件

      • 系统已结题 6月8日
      • 修改了问题 5月31日
      • 修改了问题 5月31日
      • 赞助了问题酬金8元 5月31日
      • 展开全部

      悬赏问题

      • ¥15 写c++代码,第7题说一下使用的计算方法
      • ¥15 postman接口自动化测试报告实践总结
      • ¥15 有关c++的问题,利用相关知识
      • ¥15 求香农编码和解码的matlab代码
      • ¥20 ROS中的TEB局部规划问题
      • ¥20 关于#matlab#的问题:要求测出上面图片中所有同心圆的半径
      • ¥20 epanet软件运行问题
      • ¥15 Python 文件读取
      • ¥60 dpabi进行Alff计算时脑池有干扰信号
      • ¥15 利用kmeans或kshape聚类分析对归一化的无量纲时间-降雨序列进行聚类