zoukankan      html  css  js  c++  java
  • MQTT协议笔记之mqtt.io项目HTTP协议支持

    前言

    MQTT协议诞生之初,就未曾考虑通过HTTP传输。这也正常,网络受限、不稳定网络不太适合HTTP(2G/3G网络大家使用WAP不也OK嘛)。在网络较为充裕的桌面端而言,虽纯文本对比二进制而言没多大优势,受制于历史遗留和使用习惯,以及一大票传统基础设施方便控制事宜,传统互联网/企业型应用,HTTP协议都是默认最佳选择,安全可控,人机友好。选择HTTP也在情理之中。

    虽桌面端日渐式微,但做统一的全平台化消息系统/消息中间件,也是趋势。

    MQTT OVER HTTP,为WEB环境提供HTTP通道协议支持,在统一平台化这样的考量下,就显得合情合理。 MQTT相比其它基于HTTP的交换协议而言(比如socket.io),流量节省,消息质量可控。

    一句话,比它强大的,没有它轻量。比它还轻的,没有它可控。

    总之,在资源受限环境下表现如此优异,那么桌面端会表现的更为优秀。

    HTTP支持情况

    二进制支持,针对浏览器端JavaScript而言,处理起来,如同在石器时代要处理工业时代一些通讯方式,非常吃力。支持Javascript二进制操作的浏览器现状:

    xhr2

    来源于:http://caniuse.com/xhr2

    这和支持Websocket的浏览器的基本重叠。

    要想让HTTP传输MQTT具体消息二进制,然后由浏览器javascript脚本进行解析,无法做到支持所有常见浏览器,需要考虑纯文本方式的传输。

    设计摘要

    AJAX方式,支持跨域,支持所有主流平台,桌面+移动设备;所有浏览器,移动的,桌面的,包括IE6+。那么最理想方式就是JSONP,基于文本通信的Long-polling JSONP方式。

    MQTT 协议关键交互点: 1. 连接获取授权 1. 订阅/退订主题 1. 发布消息 1. 等待订阅消息 1. 关闭连接

    若支持HTTP方式完成以上功能/步骤,服务器端需要支持接收HTTP纯文本内容请求,拼装、转换成Java对象,业务层面实现数据流转、交换,直接插入到更具体业务中,这样就很容易。虽类似于桥接,但减少了桥接的路径(HTTP —》MQTT),减少资源占用,性能上有所保证。

    HTTP 文本方式,和MQTT二进制之间需要某些规则的转换,为了兼容,需要单独定义接口传输接口,ChannelEntry,双通道和单通道处理数据的方式不同,单通道的HTTP JSONP需要支持短暂缓存消息并等待客户端的依次获取。发布/接收订阅消息时,TCP/Websocket利用双通道对应Channel可直接发送。

    HTTP通道已经预留出接口,便于支持其它类型的HTTP传输通道,比如需要在非浏览器环境中实现常规的long polling/Http Streaming,仅仅需要做到实现相应接口即可。

    客户端ID的生成方式,一般是由服务器端生成的SessionId决定。传输纯文本方式比较结构化JSON结构比较合适。

    JSONP只支持HTTP GET方式,这一点需要牢记。

    传输接口定义

    1. 连接获取授权 /jsonp/connect
    2. 订阅主题 /jsonp/subscribe
    3. 等待订阅消息 /jsonp/waiting
    4. 发布主题 /jsonp/publish
    5. 退订主题 /jsonp/unsubscrible
    6. 关闭连接 /jsonp/disconnect

    要求返回的消息类型都是JSON字符串形式,订阅/发布的消息,一定要包含{id:10, msg:'具体消息内容'}类似json字符串。

    简单示范

    一般传输的是文字内容,但具有结构化的,非json莫属。无论是走TCP方式二进制流还是JSONP传输的内容体,json都是不错的可结构化数据的选择。

    浏览器端jquery,支持jsonp请求,这里有一个简单示范:

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>jsonp example</title>
    <script src="http://libs.baidu.com/jquery/1.5.0/jquery.js"></script>
    <script type="text/javascript">
    var clientId = "";
    var urlPrefix = "http://127.0.0.1:8080/jsonp";
    $(document).ready(function(){
    doConnect();
    });
     
    function doConnect(){
    jreq(urlPrefix + '/connect', '', function(data){
    if(data.status){
    log("connected!");
    clientId = data.clientId;
    doSub();
    }else{
    alert("failure !");
    }
    });
    }
     
    function doSub(){
    jreq(urlPrefix + '/subscribe', 'topic=sub-msg/webclient1', function(data){
    if(data.status){
    log("subscribed!");
    doWaiting();
    }else{
    log("bad!");
    }
    });
    }
     
    function doWaiting(){
    jreq(urlPrefix + '/waiting', '', function(data){
    log("Got Message : id = " + data.id + " msg = " + data.msg);
    doWaiting();
    });
    }
     
    function jreq(url, parameter, fn){
    $.ajax({
    url:url,
    dataType:"jsonp",
    jsonp:"jsonpcallback",
    data: parameter,
    timeout: 300000,
    async:true,
    success:function(data){
    fn(data);
    }
    });
    }
     
    function log(val){
    $("#log").html(val + "<br/>" + $("#log").html());
    }
    </script>
    </head>
    <body>
    <div id="log"></div>
    </body>
    </html>
    view rawjsonp.html hosted with ❤ by GitHub

    填写好地址,自动执行连接,订阅,接收消息,一个最简单的Demo表现了其流程。

    小结

    简单实现jsonp形式的MQTT OVER HTTP,做到文本和二进制彼此之间交换数据。总之在纯HTTP环境下使用MQTT协议,是一个不错的选择。

     原文 http://www.blogjava.net/yongboy/archive/2014/06/06/414474.html

  • 相关阅读:
    7-3色彩平衡
    Flex 布局
    JS获取当前周
    虚树学习笔记
    当然,perl等脚本服务器是一般默认安装了,你入侵了一台主机,总不能先装配 Java 环境然后再开干吧?
    还有这种书,程序开发心理学(豆瓣)
    Codeforces Round #143 (Div. 2)
    Codeforces Round #142 (Div. 2)
    Codeforces Round #141 (Div. 2)
    2018-2019-1 20189221 书籍速读 第 1 周
  • 原文地址:https://www.cnblogs.com/yudar/p/4642421.html
Copyright © 2011-2022 走看看