如何正确管理 websocket 消息?

Posted

技术标签:

【中文标题】如何正确管理 websocket 消息?【英文标题】:How to manage correctly websocket messages? 【发布时间】:2021-02-22 10:20:18 【问题描述】:

我有一个通过 WebSocket 与 WinForm 通信的网页,这是我第一次使用 WebSocket,我已经为与我的网页通信设置了一个 json 结构,然后通过检查 json 参数“类型”我做一些关于它的价值的东西。

到目前为止,它是else if 的链,但它是管理它的正确方法吗?

我的代码如下所示:

  websocket.onmessage = function (e) 
    var data = JSON.parse(e.data);
    if (data.type === "err_login") 
      var feedback = $("#modalLogin .invalid-feedback");
      $("#modalLogin .codope").val("");
      $("#modalLogin .password").val("");
      feedback.find("h5").text(data.content.title);
      feedback.addClass("d-block");
     else if (data.type === "err") 
      var content = data.content;
      Swal.fire(
        heightAuto: false,
        title: content.title,
        text: content.text,
        icon: "warning",
        allowOutsideClick: false,
        showDenyButton: true,
        buttonsStyling: false,
        customClass: 
          confirmButton: "btn btn-lg btn-primary btn-swal",
          denyButton: "btn btn-lg btn-warning ml-3 btn-swal",
        ,
        confirmButtonText: "OK",
        denyButtonText: arrLang[lang]["assistenza"],
      ).then((result) => 
        if (result.isDenied) 
          $("#modalAssistenza").modal("show");
        
      );
     else if (data.type === "prod") 
      addProdotto(data.content);
     else if (data.type === "sbt") 
      subtotale(data.content);
     else if (data.type === "fid") 
      addFidelity(data.content);
     else if (data.type === "lot") 
      addLotteria(data.content.lotteria);
     else if (data.type === "reset") 
      reset();
     else if (data.type === "closed") 
      $("#modalOffline").modal("show");
     else if (data.type === "lang") 
      changeLanguage(data.content.lang);
    else if (data.type === "payement_text") 
      setPaymentText(data.content)
    else if (data.type === "payement_success") 
      var content = data.content;
      Swal.fire(
        heightAuto: false,
        title: content.title,
        text: content.text,
        icon: "success",
        showConfirmButton: false,
        allowOutsideClick: false,
        allowEscapeKey: false,
      )
    else if (data.type === "payement_success_close") 
      Swal.close();
    else if (data.type === "payement_error") 
      var content = data.content;
      Swal.fire(
        heightAuto: false,
        title: content.title,
        text: content.text,
        icon: "error",
        allowOutsideClick: false,
        buttonsStyling: false,
        customClass: 
          confirmButton: "btn btn-lg btn-primary btn-swal",
        ,
        confirmButtonText: "OK",
      ).then((result) => 
        if (result.isConfirmed) 
          websocket.send(`<PAY></PAY>`);
          pagamentoIndietro();
        
      );
    
  ;

我应该以不同的方式管理它吗?

【问题讨论】:

【参考方案1】:

我不是一个经验丰富的开发者(所以一些比我聪明的人可能有更好的解决方案),但我的建议是:

我会在不同的函数中创建切换逻辑,例如messageHandler(msg),并用简单的switch 语句替换if ... else if 语句。它将具有相同的功能,但代码看起来会更清晰。

另外,对于每种情况,我都会将它们移到单独的函数中。这使得阅读、测试和记录变得更容易。只需将每个功能放在不同的功能中,该功能在顶部有很好的评论并且经过了很好的测试。我能找到的唯一缺点是测试耦合会很痛苦(如果你这样做的话),但对我来说,好处大于损失。

一种更高级的方法(如果您想提供灵活性)是有一个map [key, function],它将键映射到需要调用的适当函数。这比较复杂,但如果您只是需要一个简单的解决方案来解决这个问题,我会推荐它。

【讨论】:

以上是关于如何正确管理 websocket 消息?的主要内容,如果未能解决你的问题,请参考以下文章

WebSocket 实战

什么项目将使用 websocket 而不是 webrtc?

springboot整合websocket

WebSocket入门及使用指南

无法通过 tomcat 中的 websocket 发送二进制消息,但可以在 glassfish 中使用。使用 IllegalArgumentException 在 tomcat 中失败

了解一下websocket