JS采用WebSocket与后端服务器通信

  我想大家会有个疑问,我为何会采用websocket通信,其实作为新手得我也尝试过用ajax、socket、vue.ajios等方式都失败了,我也没有搞懂什么回事,就是秉着不管白猫黑猫,能抓到老鼠就是好猫,我只要能通信,完成功能即可,暂时不管这么多,至于原理以后再研究。

  我只负责前端,后端服务器是另个同事负责,他用的是C#来编写,所以参照一个网址模板(双方都按照约定方式编写):https://www.cnblogs.com/notyourdog/p/9728047.html

如果后端使用java或者其他写法,网上搜索下服务端的websocket的写法。

尝试我给他发信息可以收到,他给我回得消息我也收的到。

用了一段时间,目前通信正常,没有发现什么异常,满足基本需求,其他得就不太了解了。

 

第一次连接,模板如下:

//第1步 连接后端
   //window.YESconnectServer();//后期修改ip方便
   var wsImpl = window.WebSocket || window.MozWebSocket;
    // 创建新的websocket新连接端口
    window.ws = new wsImpl('ws://192.168.0.1:8888');//192.168.0.1这是后端服务器地址,本地是127.0.0.1或者localhost,这里要注意:要与服务端统一ip写法(或者服务端监听所有得,如0.0.0.0:8888),否则其他电脑无法访问。
    console.log("连接中,等待连接 ..<br/>");
    //没有连接上就给客户提示
    document.getElementById("container").innerHTML = '<img src="img/xxx.gif" style="margin-left:80px;margin-top:50px;"/><span style="margin-left:-80px;color:red">请尝试按F5刷新页面</span>';

    //第2步 当链接对象找到服务端成功对接后,提示正常打开
    ws.onopen = function () {
        console.log("连接成功");
        //连接公共就要取消提示:visibility:hidden;
        document.getElementById("container").innerHTML = '<img src="img/xxx.gif" style="margin-left:80px;margin-top:30px;visibility:hidden;" /><span style="margin-left:-90px;color:red;visibility:hidden;">等待时间久,请尝试刷新页面</span>';

        // id对应刻客户本机的IP
        // console.log("唯一id号:"+id); //打印看看对否

    // 发送数据给后端处理,这里我使用的是json
    let data = {
          "xxx": xx,
          "xxx": xx,
          "xxx": xx,
          "xxx": ""
        }
      var sendStr = JSON.stringify(data);
      // console.log("发送数据(转换后):" + sendStr);
      ws.send(sendStr);
    };

    //第3步 接收到服务端响应的数据时,触发事件
    ws.onmessage = function (evt) {

           // console.log("收到数据(还没转):" + evt.data);
           var myobj = JSON.parse(evt.data);//转对象
           var myooo = JSON.parse(myobj.respData); //转对象
           // console.log("收到数据(转换后2):"+typeof myooo + myooo);
           // console.log("收到得数据"+ JSON.stringify(myooo))//这就是获取后端的数据。
           
           //需要给后端发送得json格式,根据双方得定义
          let tempData =
             [
                  {
                      "xxx": x,
                      "xxx":"xxx",
                      "xxx":xx,
                      "xxx":xx,
                      "xxx":xx,
                      "xxx":myooo
                  }
              ];


          window.shuaxin(tempData);//外部布局得方法,收到数据后显示出来

    };

    //第4步 当服务端关闭后,定时重连操作
    ws.onclose = function () {
        // data.append ( '.. 网络连接失败<br/>');
        console.log("Close:连接关闭");
        // login();//重连
    };

    //第5步 当连接出现异常后,排查下连接错误原因
    ws.onerror = function() {
         console.log("Erro:出现错误");
         // login();//重连
    };

根据上面就知道很简单,其实就分为5步骤:

1.// 连接后端,输入地址

2.//给后端发送内容--数据结构、json等

3.//接收后端回得内容,然后处理这些内容,看你要放在页面得哪个地方

后面两个步骤几乎都是固定得写法,不会变,就是断开服务,或者连接异常给出提示

4. // 当服务端关闭后,定时重连操作
    ws.onclose = function () {
        // data.append ( '.. 网络连接失败<br/>');
        console.log("Close:连接关闭");
        // login();//重连
    };

 5.// 当连接出现异常后,排查下连接错误原因
    ws.onerror = function() {
         console.log("Erro:出现错误");
         // login();//重连
    };

 

非第1次通信,也就是中途由内容需要通信,比如请求数据,用户点击事件要获取数据、操作数据等

如果其他地方需要到发送数据,建议先写个发送模板,因为要频繁发送数据,我这里也分几步:

1.固定模板写法:发送模板sendRequest(xxx,xxx,xxx)

//发送模板
       function sendRequest(moduleType, actionType, reqData) {
           // 当链接对象找到服务端成功对接后,提示正常打开
           // ws.onopen = function () {
               // console.log("连接成功");

           // 发送数据给后端处理
           let  request={
                "xxx": xx,
                "xxxx":xx,
                "xxxx": xx,
                "xxx": xx
                }
             var sendStr = JSON.stringify(request);
             console.log("发送数据模板 reqData:" + reqData+"发送数据模板sendStr:"+sendStr);
             ws.send(sendStr);

       }

2.然后其他经常需要变化得json格式就很灵活得写法了:

请求内容根据与后端约定好的json格式写,调用发送模板即可,这样后端就知道你想做什么,你是想新增、还是修改、或者是删除功能。

         //新加功能--给后端请求
        function sendAdd(reqdata){ //给上面调用
          var  xxx= 1;//新增功能
          var  xxxx= 1;//群组模块
          window.sendRequest(moduleType,actionType,reqdata);//调用发送模板,把参数传过去
        }
        //更新功能(如修改名称)--给后端请求
        function sendUpdata(reqdata){ //给上面调用
          var  xxx= 2;//修改组名
          var  xxx= 2;//群组模块
          window.sendRequest(moduleType,actionType,reqdata);//调用发送模板,把参数传过去
        }
        //删除功能--给后端请求
        function sendDele(reqdata){
          var xxx= 3;
          var xxx= 3;
          window.sendRequest(moduleType,actionType,reqdata);//调用发送模板,把参数传过去
        }

        //其他功能根据具体情况

3. 具体的内容写法就把具体的数据,就是告诉后端你要新增什么内容,或者删除什么内容,由后端操作数据库即可。

例子:告诉后端删除一个什么组的功能

 //----准备数据发送
                       let groupInfo= ID /比如告诉后端要删除某个组对应的ID,后端就知道了
                    //或者发送某种固定json格式
                       // {
                       //     "xxx": xx,
                       //     "xxx": 3,
                       //     "xxx": 3,
                       //     "xxx": ID
                       //     }
                       
                       //后端要求发送string格式,那我们就给他转换下格式
                       senddele=JSON.stringify(groupInfo);
                       console.log("要删除的数据senddele:"+senddele);//打印看下我们发送的什么
                       window.sendDele(senddele);//调用发送的模板
                    //---------

                    window.JSRequest(); //发送后就接收,接收返回的数据并拼接,看下面步骤4

上面的接收时因为我写了一个方法:

发送后,看后端会不会跟我们回什么东西,比如删除成功的提示,或者其他数据,我们要处理,如删除后,我们页面就要同步刷新

 先写个接收模板,注意,接收的内容可能很多,你就选你需要的部分,自己调试时打印看看

//接收模板 --使用模板有可能会出现数据混乱或者其他的bug
      function JSRequest(){
        //接收到服务端响应的数据时,触发事件
        ws.onmessage = function (evt) {
             // console.log("收到组终端(还没转):" + evt.data);
            groupobj = JSON.parse(evt.data);//转对象
            groupoo = JSON.parse(groupobj.respData); //转对象
               // var grouprr = groupoo.respData;
               // console.log("选择返回来的信息:"+ typeof groupoo +groupoo[0].imei);
               // console.log("groupoo444"+typeof groupoo[0] + groupoo[0]);
         //接收信息后你要干嘛,放到表格还是显示在页面哪个位置,例如
          if(groupoo .xxx=="删除成功!"){
             //刷新界面,获取重新像服务端请求数据,随你
           }else{
             alert("可能是网络或服务器原因,删除失败,请重新选择或者刷新页面");
             //由可能时某种原因导致
           }
        };
      }

最后在调用这个方法接收

window.JSRequest(); //接收返回的数据并拼接

 

最后,发现写了很多的页面,但是对方服务器或本地的地址都会频繁变化,然后你每个js页面都修改,好累啊!

所有要写一个通用的方法,新建一个通用的js,比如main.js,所有的Html都引用这个js文件,公用它,每个html页面的</body>添加引用路径

<script type="text/javascript" src="static/Myjs/main.js"></script>


我的main.js写了一个方法,这个就回到第一个步骤:

  /* 连接后端 */
  function YESconnectServer(){//后期修改ip方便

    var wsImpl = window.WebSocket || window.MozWebSocket;

    window.ws = new wsImpl('ws://192.168.0.1:8888');
    console.log("连接中,等待连接 ..<br/>");
  }

这样每次地址变化,就改这个main.js的地址,只改一次就够了,不用改这么多。

第一步连接后端就使用:window.YESconnectServer();//后期修改ip方便

 

最后的websocket的写法为:

//第1步 连接后端
   window.YESconnectServer();//后期修改ip方便
   
    //没有连接上就给客户提示
    document.getElementById("container").innerHTML = '<img src="img/xxx.gif" style="margin-left:80px;margin-top:50px;"/><span style="margin-left:-80px;color:red">请尝试按F5刷新页面</span>';

    //第2步 当链接对象找到服务端成功对接后,提示正常打开
    ws.onopen = function () {
        console.log("连接成功");
        //连接公共就要取消提示:visibility:hidden;
        document.getElementById("container").innerHTML = '<img src="img/xxx.gif" style="margin-left:80px;margin-top:30px;visibility:hidden;" /><span style="margin-left:-90px;color:red;visibility:hidden;">等待时间久,请尝试刷新页面</span>';


    // 要发送的内容--发送json数据给后端处理
    let data = {
          "xxx": xx,
          "xxx": xx,
          "xxx": xx,
          "xxx": ""
        }
      var sendStr = JSON.stringify(data);
      // console.log("发送数据(转换后):" + sendStr);
      
      ws.send(sendStr);//给后端服务器发送
    };

    //第3步 接收到服务端响应的数据时,触发事件
    ws.onmessage = function (evt) {

           // console.log("收到数据(还没转):" + evt.data);
           var myobj = JSON.parse(evt.data);//转对象
           var myooo = JSON.parse(myobj.respData); //转对象
           // console.log("收到数据(转换后2):"+typeof myooo + myooo);
           // console.log("收到得数据"+ JSON.stringify(myooo))
           
           //需要给后端发送得json格式,根据双方得定义
          let tempData =
             [
                  {
                      "xxx": x,
                      "xxx":"xxx",
                      "xxx":xx,
                      "xxx":xx,
                      "xxx":xx,
                      "xxx":myooo
                  }
              ];


          window.shuaxin(tempData);//外部布局得方法,收到数据后显示出来

    };

    //第4步 当服务端关闭后,定时重连操作
    ws.onclose = function () {
        // data.append ( '.. 网络连接失败<br/>');
        console.log("Close:连接关闭");
        // login();//重连
    };

   //第5步 当连接出现异常后,排查下连接错误原因
    ws.onerror = function() {
         console.log("Erro:出现错误");
         // login();//重连
    };

这个通信方法目前适用小型前端开发,可能不像Ajax一样只更新局部,这个全部都替换,也可能会带来风险,耗电,增加服务器压力,频繁不明原因与服务端断开连接。

要了解websocket原理请参考:http://www.ruanyifeng.com/blog/2017/05/websocket.html

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
WebSocket客户端和服务端实例源码 WebSocket ws实例 HTML5 用java实现的服务端 Websocket服务器的正常通信 众所周知,Web 应用的交互过程通常是客户端通过浏览器发出一个请求,服务器端接收请求后进行处理并返回结果给客户端,客户端浏览器将信息呈现,这种机制对于信息变化不是特别频繁的应用尚可,但对于实时要求高、海量并发的应用来说显得捉襟见肘,尤其在当前业界移动互联网蓬勃发展的趋势下,高并发与用户实时响应是 Web 应用经常面临的问题,比如金融证券的实时信息,Web 导航应用中的地理位置获取,社交网络的实时消息推送等。 传统的请求-响应模式的 Web 开发在处理此类业务场景时,通常采用实时通讯方案,常见的是: 轮询,原理简单易懂,就是客户端通过一定的时间间隔以频繁请求的方式向服务器发送请求,来保持客户端和服务器端的数据同步。问题很明显,当客户端以固定频率向服务器端发送请求时,服务器端的数据可能并没有更新,带来很多无谓请求,浪费带宽,效率低下。 基于 Flash,AdobeFlash 通过自己的 Socket 实现完成数据交换,再利用 Flash 暴露出相应的接口为 JavaScript 调用,从而达到实时传输目的。此方式比轮询要高效,且因为 Flash 安装率高,应用场景比较广泛,但在移动互联网终端上 Flash 的支持并不好。IOS 系统中没有 Flash 的存在,在 Android 中虽然有 Flash 的支持,但实际的使用效果差强人意,且对移动设备的硬件配置要求较高。2012 年 Adobe 官方宣布不再支持 Android4.1+系统,宣告了 Flash 在移动终端上的死亡。 从上文可以看出,传统 Web 模式在处理高并发及实时性需求的时候,会遇到难以逾越的瓶颈,我们需要一种高效节能的双向通信机制来保证数据的实时传输。在此背景下,基于 HTML5 规范的、有 Web TCP 之称的 WebSocket 应运而生。 早期 HTML5 并没有形成业界统一的规范,各个浏览器和应用服务器厂商有着各异的类似实现,如 IBM 的 MQTT,Comet 开源框架等,直到 2014 年,HTML5 在 IBM、微软、Google 等巨头的推动和协作下终于尘埃落地,正式从草案落实为实际标准规范,各个应用服务器及浏览器厂商逐步开始统一,在 JavaEE7 中也实现了 WebSocket 协议,从而无论是客户端还是服务端的 WebSocket 都已完备,读者可以查阅HTML5 规范,熟悉新的 HTML 协议规范及 WebSocket 支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

测试狂人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值