Javascript-服务器发送大响应时WebSocket客户端未接收onmessage事件

Javascript-服务器发送大响应时WebSocket客户端未接收onmessage事件,javascript,.net,websocket,Javascript,.net,Websocket,我正在创建基于TcpClient和NetworkStream的.NETWebSocket服务器,该服务器与Javascript客户端通信。握手之后,客户机要求服务器执行特定的操作,服务器生成响应—到目前为止,是短JSON字符串被发送回客户机—并且工作正常 在我得到发送更大字符串响应的要求(即,使用200k或更多字节的base64编码图像)之后,客户机停止接收响应,并且没有触发onmessage事件。如果我切换并发送短json,它会再次正常工作 当我发送大数据时: 当我发送简单数据时: 客户端

我正在创建基于TcpClient和NetworkStream的.NETWebSocket服务器,该服务器与Javascript客户端通信。握手之后,客户机要求服务器执行特定的操作,服务器生成响应—到目前为止,是短JSON字符串被发送回客户机—并且工作正常

在我得到发送更大字符串响应的要求(即,使用200k或更多字节的base64编码图像)之后,客户机停止接收响应,并且没有触发onmessage事件。如果我切换并发送短json,它会再次正常工作

当我发送大数据时:

当我发送简单数据时:

客户端我从所有无关的代码中剥离了代码(行为保持不变)

在服务器端,我在生成响应后隔离了代码(带有base64编码图像的纯字符串,我测试并正确解码):

初始化服务器线程的代码:

 ServerListener.Start();
 clientSocket = ServerListener.AcceptTcpClient();
 NetworkStream networkStream = clientSocket.GetStream();
 while (true)
    {
     if (!networkStream.DataAvailable)
  ...regular loop/server stuff/handshake etc.
方法CreateFrameFromString如下所示。操作码使用值0-10进行测试,在所有情况下,行为都是相同的-客户端没有捕获到响应

 private static byte[] CreateFrameFromString(string message, Opcode opcode = Opcode.Text)
    {
        var payload = Encoding.UTF8.GetBytes(message);

        byte[] frame;

        if (payload.Length < 126)
        {
            frame = new byte[1 /*op code*/ + 1 /*payload length*/ + payload.Length /*payload bytes*/];
            frame[1] = (byte)payload.Length;
            Array.Copy(payload, 0, frame, 2, payload.Length);
        }
        else if (payload.Length >= 126 && payload.Length <= 65535)
        {
            frame = new byte[1 /*op code*/ + 1 /*payload length option*/ + 2 /*payload length*/ + payload.Length /*payload bytes*/];
            frame[1] = 126;
            frame[2] = (byte)((payload.Length >> 8) & 255);
            frame[3] = (byte)(payload.Length & 255);
            Array.Copy(payload, 0, frame, 4, payload.Length);
        }
        else
        {
            frame = new byte[1 /*op code*/ + 1 /*payload length option*/ + 8 /*payload length*/ + payload.Length /*payload bytes*/];
            frame[1] = 127; // <-- Indicates that payload length is in following 8 bytes.
            frame[2] = (byte)((payload.Length >> 56) & 255);
            frame[3] = (byte)((payload.Length >> 48) & 255);
            frame[4] = (byte)((payload.Length >> 40) & 255);
            frame[5] = (byte)((payload.Length >> 32) & 255);
            frame[6] = (byte)((payload.Length >> 24) & 255);
            frame[7] = (byte)((payload.Length >> 16) & 255);
            frame[8] = (byte)((payload.Length >> 8) & 255);
            frame[9] = (byte)(payload.Length & 255);
            Array.Copy(payload, 0, frame, 10, payload.Length);
        }

        frame[0] = (byte)((byte)opcode | 0x80 /*FIN bit*/);

        return frame;
    }
私有静态字节[]CreateFrameFromString(字符串消息,操作码操作码=操作码.Text)
{
var payload=Encoding.UTF8.GetBytes(消息);
字节[]帧;
如果(有效载荷长度<126)
{
帧=新字节[1/*操作码*/+1/*有效负载长度*/+payload.length/*有效负载字节*/];
帧[1]=(字节)payload.Length;
复制(有效载荷,0,帧,2,有效载荷,长度);
}
否则,如果(payload.Length>=126&&payload.Length>8)&255);
帧[3]=(字节)(payload.Length&255);
复制(有效载荷,0,帧,4,有效载荷,长度);
}
其他的
{
帧=新字节[1/*操作代码*/+1/*有效负载长度选项*/+8/*有效负载长度*/+有效负载。长度/*有效负载字节*/];
帧[1]=127;//>56)和255);
帧[3]=(字节)((payload.Length>>48)和255);
帧[4]=(字节)((payload.Length>>40)和255);
帧[5]=(字节)((payload.Length>>32)和255);
帧[6]=(字节)((payload.Length>>24)和255);
帧[7]=(字节)((payload.Length>>16)和255);
帧[8]=(字节)((payload.Length>>8)和255);
帧[9]=(字节)(payload.Length&255);
复制(有效载荷,0,帧,10,有效载荷,长度);
}
帧[0]=(字节)((字节)操作码| 0x80/*FIN位*/);
返回框;
}

我是否遗漏了一些东西-协议/缓冲区大小/等等。?在测试过程中,我注意到使用上述设置,我可以发送最多4250个字符的响应,而无需修改。一旦我找到了这个数字,响应就开始消失。

经过大量的故障排除,结果证明我必须以包的形式发送数据,而不是作为一个整体发送数据。我将响应分成块(50000个字符)并逐个发送,而在客户端,我在onmessage事件中收集信息。在发送了所有的响应块之后,我关闭了会话,这在客户端触发了从base64流创建映像

 ServerListener.Start();
 clientSocket = ServerListener.AcceptTcpClient();
 NetworkStream networkStream = clientSocket.GetStream();
 while (true)
    {
     if (!networkStream.DataAvailable)
  ...regular loop/server stuff/handshake etc.
 private static byte[] CreateFrameFromString(string message, Opcode opcode = Opcode.Text)
    {
        var payload = Encoding.UTF8.GetBytes(message);

        byte[] frame;

        if (payload.Length < 126)
        {
            frame = new byte[1 /*op code*/ + 1 /*payload length*/ + payload.Length /*payload bytes*/];
            frame[1] = (byte)payload.Length;
            Array.Copy(payload, 0, frame, 2, payload.Length);
        }
        else if (payload.Length >= 126 && payload.Length <= 65535)
        {
            frame = new byte[1 /*op code*/ + 1 /*payload length option*/ + 2 /*payload length*/ + payload.Length /*payload bytes*/];
            frame[1] = 126;
            frame[2] = (byte)((payload.Length >> 8) & 255);
            frame[3] = (byte)(payload.Length & 255);
            Array.Copy(payload, 0, frame, 4, payload.Length);
        }
        else
        {
            frame = new byte[1 /*op code*/ + 1 /*payload length option*/ + 8 /*payload length*/ + payload.Length /*payload bytes*/];
            frame[1] = 127; // <-- Indicates that payload length is in following 8 bytes.
            frame[2] = (byte)((payload.Length >> 56) & 255);
            frame[3] = (byte)((payload.Length >> 48) & 255);
            frame[4] = (byte)((payload.Length >> 40) & 255);
            frame[5] = (byte)((payload.Length >> 32) & 255);
            frame[6] = (byte)((payload.Length >> 24) & 255);
            frame[7] = (byte)((payload.Length >> 16) & 255);
            frame[8] = (byte)((payload.Length >> 8) & 255);
            frame[9] = (byte)(payload.Length & 255);
            Array.Copy(payload, 0, frame, 10, payload.Length);
        }

        frame[0] = (byte)((byte)opcode | 0x80 /*FIN bit*/);

        return frame;
    }