当前位置: 首页 > 知识库问答 >
问题:

Perl WebSocket Server导致"无法将文本帧解码为UTF-8"Chrome

申辉
2023-03-14

当使用Perl的WebSocket服务器时,如果我使用send_utf8发送一条长度超过16,000个字符的json消息,它会导致与webSocket的连接在消息Chrome被切断:

“无法将文本帧解码为UTF-8”。

此Websocket服务器可以发送的消息长度是否有限制,是否有办法绕过此限制?

共有3个答案

通飞尘
2023-03-14

我认为发出的信息的大小实际上不是问题。我也有同样的问题,将“max_payload_size”设置为更大的值并不能解决它。如果这是问题,你会看到错误消息从Frame.pm"to_bytes"子"有效载荷太大。发送更短的消息或增加max_payload_size”。当我从服务器发送消息Chrome16k我没有看到这个错误(或任何其他)在服务器上,是的我仍然得到无法解码文本帧为UTF-8与一个(操作码-1)"作为Chrome检查员网络选项卡中红色突出显示的帧消息体。

我认为这更可能是一个IO::Socket::SSL问题,因为我是按照Net::WebSocket::Server文档中的规定使用它的。我很好奇您是否健康,或者您是否在常规的未加密套接字中看到此问题。

从IO::Socket::SSL文档:

syswrite(BUF,[LEN,[OFFSET]])此函数在外部的行为与其他IO::Socket对象中的syswrite相同,例如,它将最多向套接字写入LEN字节,但不能保证写入所有LEN字节。它将返回写入的字节数。syswrite将在单个SSL帧内写入所有数据,这意味着一次最多只能写入16384字节,这是SSL帧的最大大小。

Net::WebSocket::Server::Connection正在生成框架后调用syswrite:

syswrite($self->{socket}, $bytes);

我想知道如何处理这个问题。当使用SSL时,框架模块可能应该将16k以下的消息分段,但这必须在连接中处理。我想是下午。

更新了解决方案:

事实证明,如果您愿意修改Connection.pm并将系统写入16k循环,这是一个非常简单的解决方案。记住SSL帧和WebSocket帧不是一回事,我们只需要不要溢出SSL帧大小。见工作解决方案:

sub send {
  my ($self, $type, $data) = @_;

  if ($self->{handshake}) {
    carp "tried to send data before finishing handshake";
    return 0;
  }

  my $frame = new Protocol::WebSocket::Frame(type => $type, max_payload_size => $self->{max_send_size});
  $frame->append($data) if defined $data;

  my $bytes = eval { $frame->to_bytes };
  if (!defined $bytes) {
    carp "error while building message: $@" if $@;
    return;
  }

  # modified to not overflow the 16k SSL frame size
  while( 16384 < length $bytes ) {
    syswrite( $self->{socket}, $bytes, 16384 );
    substr( $bytes, 0, 16384, '' );
  }
  syswrite($self->{socket}, $bytes);
}

我能够将一个27k json字符串发送回以前未通过SSL工作的Chrome。

法和安
2023-03-14

显然,可以在协议::WebSocket::Frame构造函数(https://github.com/vti/protocol-websocket/issues/24#issuecomment-27095561)中设置有效载荷大小。

不幸的是,cban上的文档似乎遗漏了这些信息。

试试这个:

$hs->build_frame(buffer => $my_data, max_payload_size => 200000)->to_bytes);
丰飞龙
2023-03-14

它失败的原因是(从0.001003起)Net::WebSocket::Server::Connection初始化其协议::WebSocket::Frame对象时未设置覆盖65535字节限制的“最大有效负载大小”。如果模块作者更新这些调用以允许更大或更好的缓冲区通过用户定义的值,那么问题就可以很容易地解决。

 类似资料:
  • 问题内容: 这是我的代码, 每当我运行此代码时,都会出现以下错误: 但是,它再次给出了相同的错误。那我该怎么办!请帮忙。 问题答案: 正如Mark Ransom所建议的,我找到了解决该问题的正确编码。编码为,因此替换可以解决该问题。

  • 问题内容: 我从MySql提取的Web服务(php)返回的文本乱码 现在,我正在尝试在Android中将其解码为utf-8,但无法正常工作 我努力了: 1. 不工作: 2. 不工作: 3. 不工作: 以上所有都给出相同的输出: 因此,请有人能帮助我了解我在做什么错吗?还是请提供其他选择? 任何帮助都感激不尽。谢谢 问题答案: 正如Stephen C很好地解释的那样,我遵循了所有这些步骤,但是几乎不

  • 问题内容: 我正在尝试将示例从Primefaces实施到WAB包中。 当我尝试访问JSF页面时,该页面为空。我在Glassfish日志文件中收到此错误: 我该如何解决这个问题?我想这可能是由POM配置引起的吗? 问题答案: JSF / Facelets默认情况下已经使用UTF-8(在还原视图期间进行设置),但是PrimeFaces ajax视图处理程序会在还原视图之前尝试访问请求参数,因此将使用服

  • 这是我导出查询的VBA代码: docmd.transfertext acExportDelim,“miniFlow”,“qry01_cz_test”,“c:\test_cz.txt”,“no docmd.transfertext acExportDelim,”miniFlow“,”qry01_sk_test“,”c:\test_sk.txt“,”no 我还试图修改它,添加65001作为编码参数,结

  • 问题内容: 我有一个提交后钩子脚本,当对存储库进行提交时,该脚本执行工作副本的SVN更新。 当用户使用TortoiseSVN从Windows计算机提交到存储库时,他们会收到以下错误消息: 上面有问题的文件是:注意带重音符号的u。这是因为该站点是德语,并且文件是用德语拼写的。 在Linux命令行上对工作副本执行更新时,不会遇到错误。仅当Windows SVN客户端通过提交执行提交后挂接时,才会出现上

  • 问题内容: 我有一个看起来像这样的python列表: 现在,我想将其编码为UTF-8。因此,尽管我应该使用: 但是打印清单仅给出 表示列表的第一个元素。甚至没有列表了。我究竟做错了什么? 问题答案: