草庐IT

javascript - 如何处理奇怪组合的 websocket 消息?

coder 2023-04-30 原文

我正在使用 node ws library 连接到外部 websocket api (Ubuntu 16.04 上的 Node 10.8.0)。我有一个监听器,它只是解析 json 并将其传递给回调:

this.ws.on('message', (rawdata) => {
    let data = null;
    try {
        data = JSON.parse(rawdata);
    } catch (e) {
        console.log('Failed parsing the following string as json: ' + rawdata);
        return;
    }
    mycallback(data);
});

我现在收到错误,其中 rawData 如下所示(我格式化并删除了不相关的内容):

�~A
{
    "id": 1,
    etc..
}�~�
{
    "id": 2,
    etc..

然后我想知道;这些字符是什么?看到这个结构,我最初认为第一个奇怪的符号必须是数组的左括号([),第二个是逗号(),这样它就创建了一个对象数组。

然后我通过在遇到 JSON 解析错误时将 rawdata 写入文件来进一步调查该问题。在一个小时左右的时间里,它已经保存了大约 1500 个这样的错误文件,这意味着这种情况经常发生。我在终端中cat编辑了几个这样的文件,我在下面上传了一个示例:

这里有几件事很有趣:

  1. 文件总是以这些奇怪的符号之一开头。
  2. 这些文件似乎存在于应分别接收的多条消息中。奇怪的标志将这些单独的信​​息分开。
  3. 文件总是以未完成的 json 对象结尾。
  4. 文件的长度各不相同。它们的大小并不总是相同,因此不会在特定长度上被切断。

我对 websockets 不是很有经验,但可能是我的 websocket 以某种方式接收到它连接在一起的消息流,这些奇怪的符号作为分隔符,然后随机切断最后一条消息?也许是因为我不断收到非常快的消息流?

或者可能是因为服务器端的错误(或功能)将这些单独的消息组合在一起?

有人知道这里发生了什么吗?欢迎所有提示!

[编辑]

@bendataclear 建议将其解释为 utf8。所以我做到了,并在下面粘贴了结果的屏幕截图。第一个打印是原样,第二个解释为utf8。对我来说,这看起来没什么。我当然可以转换为 utf8,然后按这些字符分割。虽然最后一条消息总是被切断,但这至少会使一些消息可读。不过仍然欢迎其他想法。

最佳答案

我的假设是您只使用英文/ASCII 字符,并且可能会弄乱流。 (注意:我假设),没有特殊字符,如果是这样,那么我建议你将整个json字符串传递给这个函数:

function cleanString(input) {
    var output = "";
    for (var i=0; i<input.length; i++) {
        if (input.charCodeAt(i) <= 127) {
            output += input.charAt(i);
        }
    }
    console.log(output);
}

//example
cleanString("�~�")

您可以引用How to remove invalid UTF-8 characters from a JavaScript string?

编辑

摘自 Internet Engineering Task Force (IETF) 的文章,

A common class of security problems arises when sending text data using the wrong encoding. This protocol specifies that messages with a Text data type (as opposed to Binary or other types) contain UTF-8- encoded data. Although the length is still indicated and applications implementing this protocol should use the length to determine where the frame actually ends, sending data in an improper


“有效负载数据”是编码为 UTF-8 的文本数据。请注意,特定的文本框架可能包含部分 UTF-8 序列;但是,整个消息必须包含有效的 UTF-8。重组消息中的无效 UTF-8 将按照处理 UTF-8 编码数据中的错误中的描述进行处理,其中指出 当端点将字节流解释为 UTF-8 但发现如果字节流实际上不是有效的 UTF-8 流,那么端点必须WebSocket 连接失败。此规则在打开握手期间和随后的数据交换期间均适用。

我真的相信您的错误(或功能)来自结合了您的个人消息的服务器端,所以我建议提出一个逻辑来确保您的所有字符必须被转换通过首先将字符编码为 UTF-8 从 Unicode 到 ASCII。您可能还想安装 npm install --save-optional utf-8-validate 以有效检查消息是否包含规范要求的有效 UTF-8。

你可能还想传入一个 if 条件来帮助你做一些检查;

this.ws.on('message', (rawdata) => {
    if (message.type === 'utf8') { // accept only text
    }

我希望这会有所帮助。

关于javascript - 如何处理奇怪组合的 websocket 消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51704138/

有关javascript - 如何处理奇怪组合的 websocket 消息?的更多相关文章

  1. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  2. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  3. ruby - 使用 Ruby 通过 Outlook 发送消息的最简单方法是什么? - 2

    我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=

  4. Ruby - 如何将消息长度表示为 2 个二进制字节 - 2

    我正在使用Ruby,我正在与一个网络端点通信,该端点在发送消息本身之前需要格式化“header”。header中的第一个字段必须是消息长度,它被定义为网络字节顺序中的2二进制字节消息长度。比如我的消息长度是1024。如何将1024表示为二进制双字节? 最佳答案 Ruby(以及Perl和Python等)中字节整理的标准工具是pack和unpack。ruby的packisinArray.您的长度应该是两个字节长,并且按网络字节顺序排列,这听起来像是n格式说明符的工作:n|Integer|16-bitunsigned,network(bi

  5. ruby-on-rails - 在 Flash 警报 Rails 3 中显示错误消息 - 2

    如果我在模型中设置验证消息validates:name,:presence=>{:message=>'Thenamecantbeblank.'}我如何让该消息显示在闪光警报中,这是我迄今为止尝试过的方法defcreate@message=Message.new(params[:message])if@message.valid?ContactMailer.send_mail(@message).deliverredirect_to(root_path,:notice=>"Thanksforyourmessage,Iwillbeintouchsoon")elseflash[:error]

  6. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  7. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  8. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  9. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  10. ruby - 最多 n 的组合 - 2

    给定一个数组a,什么是实现其组合直到第n的最佳方法?例如:a=%i[abc]n=2#Expected=>[[],[:a],[:b],[:c],[:a,b],[:b,:c],[:c,:a]] 最佳答案 做如下:a=%w[abc]n=30.upto(n).flat_map{|i|a.combination(i).to_a}#=>[[],["a"],["b"],["c"],["a","b"],#["a","c"],["b","c"],["a","b","c"]] 关于ruby-最多n的组合,我

随机推荐