android消息推送,使用MQTT协议,谁有用java写过服务端
socket编程是吧? 我有。。。 demo也有。。
package com.zgnet.billing.service; import org.json.JSONObject;import android.annotation.SuppressLint;import android.app.AlarmManager;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.SharedPreferences;import android.media.MediaPlayer;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.IBinder;import android.os.StrictMode;import android.util.Log;import com.ibm.mqtt.IMqttClient;import com.ibm.mqtt.MqttClient;import com.ibm.mqtt.MqttException;import com.ibm.mqtt.MqttPersistence;import com.ibm.mqtt.MqttPersistenceException;import com.ibm.mqtt.MqttSimpleCallback;import com.zgnet.billing.utils.WebServiceConfig;/** PushService that does all of the work.* Most of the logic is borrowed from KeepAliveService.*http://code.google.com/p/android-random/source/browse/trunk/TestKeepAlive/src/org/devtcg/demo/keepalive/KeepAliveService.java?r=219*/public class PushService extends Service {// this is the log tagpublic static final String TAG = "ZgnetPushService";// the IP address, where your MQTT broker is running.服务器ipprivate static final String MQTT_HOST = "192.168.10.4";// private static final String MQTT_HOST = "10.10.15.113";// the port at which the broker is running. 服务器端口private static int MQTT_BROKER_PORT_NUM = 1883;// Let's not use the MQTT persistence.private static MqttPersistence MQTT_PERSISTENCE = null;// We don't need to remember any state between the connections, so we use a// clean start.private static boolean MQTT_CLEAN_START = true;// Let's set the internal keep alive for MQTT to 15 mins. I haven't tested// this value much. It could probably be increased.private static short MQTT_KEEP_ALIVE = 60 * 15;// Set quality of services to 0 (at most once delivery), since we don't want// push notifications// arrive more than once. However, this means that some messages might get// lost (delivery is not guaranteed)private static int[] MQTT_QUALITIES_OF_SERVICE = { 0 };private static int MQTT_QUALITY_OF_SERVICE = 0;// The broker should not retain any messages.private static boolean MQTT_RETAINED_PUBLISH = false;// MQTT client ID, which is given the broker. In this example, I also use// this for the topic header.// You can use this to run push notifications for multiple apps with one// MQTT broker.public static String MQTT_CLIENT_ID = "zgnet";// These are the actions for the service (name are descriptive enough)private static final String ACTION_START = MQTT_CLIENT_ID + ".START";private static final String ACTION_STOP = MQTT_CLIENT_ID + ".STOP";private static final String ACTION_KEEPALIVE = MQTT_CLIENT_ID+ ".KEEP_ALIVE";private static final String ACTION_RECONNECT = MQTT_CLIENT_ID+ ".RECONNECT";// Connection log for the push service. Good for debugging.// private ConnectionLog mLog;// Connectivity manager to determining, when the phone loses connectionprivate ConnectivityManager mConnMan;// Notification manager to displaying arrived push notifications@SuppressWarnings("unused")private NotificationManager mNotifMan;// Whether or not the service has been started.private boolean mStarted;// This the application level keep-alive interval, that is used by the// AlarmManager// to keep the connection active, even when the device goes to sleep.private static final long KEEP_ALIVE_INTERVAL = 1000 * 60 * 28;// Retry intervals, when the connection is lost.private static final long INITIAL_RETRY_INTERVAL = 1000 * 10;private static final long MAXIMUM_RETRY_INTERVAL = 1000 * 60 * 30;// Preferences instanceprivate SharedPreferences mPrefs;// We store in the preferences, whether or not the service has been startedpublic static final String PREF_STARTED = "isStarted";// We also store the deviceID (target)public static final String PREF_DEVICE_ID = "deviceID";// We store the last retry intervalpublic static final String PREF_RETRY = "retryInterval";// Notification titlepublic static String NOTIF_TITLE = "Tokudu";// Notification id@SuppressWarnings("unused")private static final int NOTIF_CONNECTED = 0;// This is the instance of an MQTT connection.private MQTTConnection mConnection;private long mStartTime;JSONObject js = null;@SuppressWarnings("unused")private MediaPlayer mp;// Static method to start the servicepublic static void actionStart(Context ctx) {Intent i = new Intent(ctx, PushService.class);i.setAction(ACTION_START);ctx.startService(i);}// Static method to stop the servicepublic static void actionStop(Context ctx) {Intent i = new Intent(ctx, PushService.class);i.setAction(ACTION_STOP);ctx.startService(i);}// Static method to send a keep alive messagepublic static void actionPing(Context ctx) {Intent i = new Intent(ctx, PushService.class);i.setAction(ACTION_KEEPALIVE);ctx.startService(i);}@Overridepublic void onCreate() {super.onCreate();log("Creating service");mStartTime = System.currentTimeMillis();// try {// mLog = new ConnectionLog();// Log.i(TAG, "Opened log at " + mLog.getPath());// } catch (IOException e) {// Log.e(TAG, "Failed to open log", e);// }// Get instances of preferences, connectivity manager and notification// managermPrefs = getSharedPreferences(TAG, MODE_PRIVATE);mConnMan = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);mNotifMan = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);/** If our process was reaped by the system for any reason we need to* restore our state with merely a call to onCreate. We record the last* "started" value and restore it here if necessary.*/handleCrashedService();}// This method does any necessary clean-up need in case the server has been// destroyed by the system// and then restartedprivate void handleCrashedService() {if (wasStarted() == true) {log("Handling crashed service...");// stop the keep alivesstopKeepAlives();// Do a clean startstart();}}@Overridepublic void onDestroy() {log("Service destroyed (started=" + mStarted + ")");// Stop the services, if it has been startedif (mStarted == true) {stop();}// try {// if (mLog != null)// mLog.close();// } catch (IOException e) {}}@SuppressWarnings("deprecation")@Overridepublic void onStart(Intent intent, int startId) {super.onStart(intent, startId);log("Service started with intent=" + intent);// Do an appropriate action based on the intent.if (intent.getAction().equals(ACTION_STOP) == true) {stop();stopSelf();} else if (intent.getAction().equals(ACTION_START) == true) {start();} else if (intent.getAction().equals(ACTION_KEEPALIVE) == true) {keepAlive();} else if (intent.getAction().equals(ACTION_RECONNECT) == true) {if (isNetworkAvailable()) {reconnectIfNecessary();}}}@Overridepublic IBinder onBind(Intent intent) {return null;}// log helper functionprivate void log(String message) {System.out.println("----------------------------" + message);}// Reads whether or not the service has been started from the preferencesprivate boolean wasStarted() {return mPrefs.getBoolean(PREF_STARTED, false);}// Sets whether or not the services has been started in the preferences.private void setStarted(boolean started) {mPrefs.edit().putBoolean(PREF_STARTED, started).commit();mStarted = started;}private synchronized void start() {log("Starting service...");// Do nothing, if the service is already running.if (mStarted == true) {Log.w(TAG, "Attempt to start connection that is already active");return;}// Establish an MQTT connectionconnect();// Register a connectivity listenerregisterReceiver(mConnectivityChanged, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));}private synchronized void stop() {// Do nothing, if the service is not running.if (mStarted == false) {Log.w(TAG, "Attempt to stop connection not active.");return;}// Save stopped state in the preferencessetStarted(false);// Remove the connectivity receiverunregisterReceiver(mConnectivityChanged);// Any existing reconnect timers should be removed, since we explicitly// stopping the service.cancelReconnect();// Destroy the MQTT connection if there is oneif (mConnection != null) {mConnection.disconnect();mConnection = null;}}//private synchronized void connect() {log("Connecting...");// fetch the device ID from the preferences.String deviceID = mPrefs.getString(PREF_DEVICE_ID, null);// Create a new connection only if the device id is not NULLif (deviceID == null) {log("Device ID not found.");} else {try {mConnection = new MQTTConnection(MQTT_HOST,new String[] { "billing"+ WebServiceConfig.DEPARTMENTID });} catch (MqttException e) {// Schedule a reconnect, if we failed to connectlog("MqttException: "+ (e.getMessage() != null ? e.getMessage() : "NULL"));if (isNetworkAvailable()) {scheduleReconnect(mStartTime);}}setStarted(true);}}private synchronized void keepAlive() {try {// Send a keep alive, if there is a connection.if (mStarted == true && mConnection != null) {mConnection.sendKeepAlive();}} catch (MqttException e) {mConnection.disconnect();mConnection = null;cancelReconnect();}}// Schedule application level keep-alives using the AlarmManagerprivate void startKeepAlives() {Intent i = new Intent();i.setClass(this, PushService.class);i.setAction(ACTION_KEEPALIVE);PendingIntent pi = PendingIntent.getService(this, 0, i, 0);AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + KEEP_ALIVE_INTERVAL,KEEP_ALIVE_INTERVAL, pi);} // Remove all scheduled keep alives
看起来很麻烦的样子。我用xmpp貌似没这么麻烦。有个openfire已经帮我们实现。

如何通过javascript 使用 MQTT
启动方式: 解压缩,进入apache-activemq-5.9.0-binapache-activemq-5.9.0bin,双击activemq.bat,即可启动activeMQ服务启动之后: android客户端推送采用mqtt(paho-mqtt-client-1.0.1.jar),
做法是通过socket.io做中转,websocket连接到socekt.io上,后台nodejs再连接到mqtt server上。

如何采用mqtt协议实现android消息推送
使用一个代理服务器message broker,客户端client连接上这个服务器,然后告诉服务器,可以接收哪些类型的消息,同时client也可以发布自己的消息,这些消息根据协议的内容,可以别的client获取。这样就实现了消息推送。 消息推送是通过一定的技术标准或协议,在互联网上通过定期传送用户需要的信息来减少信息过载的一项新技术。如果想要使用消息推送,推荐使用深圳极光的消息推送系统。深圳极光是国内首个为移动应用开发者提供专业、高效的消息推送服务的产品。品牌成长的过程,就是与客户肩并肩迈向成功的过程。极光将以市场为导向,以创新为动力,以技术为支持,不断用心努力,为每一位尊贵的客户提供极致的服务。
MQTT是一项消息传递技术,由IBM再2001年发布。 总结一下,机制就是使用一个代理服务器messagebroker,客户端client连接上这个服务器,然后告诉服务器说,我可以接收哪些类型的消息,同时,client也可以发布自己的消息,这些消息根据协议的内容,可以被其他client获取。只要手机客户端,连上服务器,然后就可以接收和发布消息了,不用自己写socket什么了,低带宽,低耗电量,代码量也少,很简单吧。package com.pig.test.mqtt;import com.ibm.mqtt.MqttClient;importcom.ibm.mqtt.MqttException;import com.ibm.mqtt.MqttSimpleCallback;public class SubscribeClient {private final static StringCONNECTION_STRING = "tcp://192.168.1.60:1883";private final static booleanCLEAN_START = true;private final static short KEEP_ALIVE =30;//低耗网络,但是又需要及时获取数据,心跳30sprivate final static String CLIENT_ID ="client1";private final static String[] TOPICS ={"Test/TestTopics/Topic1","Test/TestTopics/Topic2","Test/TestTopics/Topic3","tokudu/client1"};privatefinal static int[] QOS_VALUES = {0, 0, 2,0};//////////////////private MqttClient mqttClient =null;public SubscribeClient(String i){try {mqttClient =new MqttClient(CONNECTION_STRING);SimpleCallbackHandlersimpleCallbackHandler = newSimpleCallbackHandler();mqttClient.registerSimpleHandler(simpleCallbackHandler);//注册接收消息方法mqttClient.connect(CLIENT_ID+i,CLEAN_START, KEEP_ALIVE);mqttClient.subscribe(TOPICS,QOS_VALUES);//订阅接主题/***完成订阅后,可以增加心跳,保持网络通畅,也可以发布自己的消息*/mqttClient.publish(PUBLISH_TOPICS, "keepalive".getBytes(), QOS_VALUES[0],true);} catch (MqttException e) {// TODO Auto-generatedcatch blocke.printStackTrace();}}/*** 简单回调函数,处理client接收到的主题消息* @author pig**/class SimpleCallbackHandler implements MqttSimpleCallback{/*** 当客户机和broker意外断开时触发* 可以再此处理重新订阅*/@Overridepublic void connectionLost() throws Exception {//TODO Auto-generated methodstubSystem.out.println("客户机和broker已经断开");}/*** 客户端订阅消息后,该方法负责回调接收处理消息*/@Overridepublic voidpublishArrived(String topicName, byte[] payload, int Qos, boolean retained)throws Exception {// TODO Auto-generated methodstubSystem.out.println("订阅主题: " +topicName);System.out.println("消息数据: " + newString(payload));System.out.println("消息级别(0,1,2): " +Qos);System.out.println("是否是实时发送的消息(false=实时,true=服务器上保留的最后消息): " +retained);}}/*** 高级回调* @author pig**/class AdvancedCallbackHandler implements MqttSimpleCallback{@Overridepublic void connectionLost() throws Exception {//TODO Auto-generated method stub}@Overridepublic void publishArrived(String arg0, byte[] arg1, intarg2,boolean arg3) throws Exception {// TODO Auto-generatedmethod stub}}/*** @param args*/public static void main(String[] args) {// TODO Auto-generatedmethod stubnew SubscribeClient("" + i);}}broker服务器,MQTT的jar包,记得下载啊,没有就消息我咯~到这里,如果完成IBM的MQTT协议实现push消息的实例的,都会有个问题,好像没考虑到安全问题,如果客户端连上来作乱怎么办呢?上面用的broker时rsmb的,mqtt的简单服务器。IBM已经推出了MQTT V3.1版本,已经加入了安全验证机制,不要怕啦。 转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦

【内部分享】MQTT协议解读及使用经验
时间:2018-07-26Q: 什么是网络连接?A:网络连接是传输层定义的概念,在传输层以下只存在网络数据包的相互交换。所谓连接,其实也不是在网络上有一条真实存在的数据通道。只要通信双方在一段时间内持续保持数据包交换,就可以视为双方建立的连接并没有断开。连接的建立是依托于TCP协议的三次握手,一旦连接已经建立完毕,通信双方就可以复用这条虚拟通道进行数据交换。如果连接保持长时间工作一直没有被中断,那么这样的TCP连接就俗称为长连接。Message Queue Telemetry Transport ,中文直译:消息队列遥测传输协议。在MQTT协议被设计出来的年代,还没有物联网这么时髦的词汇,当年叫做遥测设备。MQTT协议真正开始声名鹊起的原因,是其正好恰恰踩中移动互联网发展的节拍,为消息推送场景提供了一个既简便又具有良好扩展性的现成解决方案。http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html可以看出,MQTT对消息头的规定十分精简,固定头部占用空间大小仅为1个字节,一个最小的报文占用的空间也只有两个字节(带一字节的长度标识位)。这也是MQTT协议针对不稳定及带宽低下的网络环境做出的特定设计 - - - -尽可能地节省一切不必要的网络开销。Q:为什么MQTT协议需要心跳报文(PINGREQ, PINGRESP)来维护连接状态,只监控该TCP的连接状态是否可以实现目的?A:TCP数据传输默认的超时时间过长,不符合应用层上细粒度的要求。TCP数据传输超时的情况可分成三种: 服务端断开 、 客户端断开 、 中间网络断开 。在前两种场景下,若断开操作是一方主动发起的,即表示为TCP连接正常结束,双方走四次挥手流程;若程序异常结束,则会触发被动断开事件,通信另一方也能立刻感知到本次连接所打开的 Socket 出现中断异常。唯独中间网络的状态是通信双方不能掌握的。在Linux系统下,TCP的连接超时由内核参数来控制,如果通信中的一方没有得到及时回复,默认会主动再尝试6次。如果还没有得到及时回应,那么其才会认定本次数据超时。连带首次发包与六次重试,Linux系统下这7次发包的超时时间分别为2的0次方至2的6次方,即1秒、2秒、4秒、8秒、16秒、32秒、64秒,一共127秒。MQTT协议认为如此长的超时时间对应用层而言粒度太大,因此其在应用层上还单独设计属于自身的心跳响应控制。常见的MQTT连接超时多被设定为 60秒 。扩展知识- TCP的KeepAlive机制: http://hengyunabc.github.io/why-we-need-heartbeat/由通信中的报文标识符(Packet Identifier )传达。Q:仅Publish与Pubrec能保证消息只被投递一次吗?A:业务上可以实现,但MQTT协议并没有如此设计,原因如下:每个消息都会拥有属于自己的报文标识符,但如果需要两次数据交换就实现消息仅只收到一次,就需要通信双方记录下每次使用的报文标识符,并且在处理每一条消息时都需要去重处理,以防消息被重复消费。但MQTT协议最初被设计的工作对象是轻量级物联设备,为此在协议的设计中报文标识符被约定为可重用,以减少对设备性能的消耗,换回的代价不得不使用四次网络数据交换,才能确保消息正好被消费一次。Q:两个不同客户端在发布与订阅同一Topic下的消息时,都可以提出通信Qos要求,此时以哪项为基准?A:伪命题,故意在分享时埋下坑,等人来踩。两个不同客户端的通信是需要 Broker 进行中转,而不是直连。因此,通信中存在两个不同的会话,双方的Qos要求仅仅作用于它们与 Broker 之间的会话,最终的Qos基准只会向最低要求方看齐。例:遗嘱消息的正确使用方式可参考此篇文章: https://www.hivemq.com/blog/mqtt-essentials-part-9-last-will-and-testament虽然可以借助Retain Message实现绑定一条消息至某个Topic,以达到消息的暂时保留目的。但首先Retain Message并不是为存储场景而设计的,再次MQTT协议并没有对消息的持久化作出规定,也就是说Broker重启后,现有保留消息也将丢失。Q:两种特殊消息的使用场景?A:遗嘱消息,多用于客户端间获取互相之间异常断线的消息通知;保留消息,可保存最近一条广播通知,多用于公告栏信息的发布。Eclipse Mosquitto :MQTT协议的最小集实现有 EMQ ,HiveMQ ,RabbitMQ MQTT Adapter 等。Qos=2 消息保障的网络I/O次数过多,如果不是必需,尽少在程序里使用此类消息。毕竟当初其设计的目的是为了减少设备的性能占用,但若应用场景并不是物联网,而是用于手机、电脑或浏览器端等现在已不缺性能的设备上,最好在报文体中,使用UUID生成全局唯一的消息ID,然后自行在业务解析中判断此报文是否被消费过。或者,业务方在处理消息时保证其被消费的幂等性,也可消除重复消息对系统带来的影响。正如MQTT协议并没有依赖TCP连接状态,自己在应用层协议上实现心跳报文来控制连接状态,业务方作为MQTT协议的使用者,也不要完全依赖协议的工作状态,而是依托MQTT协议建立属于业务本身的信息汇报机制,以加强系统的稳健性。Retain Message 可视为客户端主动拉取的行为。如果业务系统采用HTTP+MQTT双协议描述业务过程,主动拉取的操作也可使用HTTP请求替代。作为一个长连接型的应用,上线前需要根据业务量级,评估对操作系统端口数与文件描述符的占用要求,以防服务器资源被打满。在服务端的配置文件和客户端的连接参数中,都拥有 max_inflight_messages 此项配置,来维护 Qos=1 or 2 消息是否被成功消费的状态。MQTT 最初被设计为物联网级的通信协议,因此此参数的默认配额较小(大多数情况下被限制到10至20)。但如果将MQTT协议应用至手机、PC或Web端的推送场景时,硬件性能已不在是瓶颈,在实际使用中推荐把此参数调大。Mosquitto提供Bridge功能,需要我们自己配置。Bridge 意为桥接,当我们把两台Broker桥接在一起时,只需要修改一台Broker的配置,填上另一台Broker的运行地址。前一台Broker将作为客户端发布与订阅后一台Broker的所有Topic,实现消息互通的目的。桥接带来的问题有以下几点:我的建议:Websockets协议被设计的目的是为浏览器提供一个全双工的通信协议,方便实现消息推送功能。在Websockets协议被设计出来前,受限于HTTP协议的一问一答模型,消息的推送只能靠轮询来实现,在资源消耗与时效性保障上,均难以达到令人满意的效果。Websockets协议复用了HTTP协议的头部信息,告知浏览器接下来的操作将触发协议升级,然后通信双方继续复用HTTP的Header,但报文内容已转变为双方均接受的新协议的格式。Websockets协议改进了网页浏览中的消息推送的方式,因此被广泛应用在聊天、支付通知等实时性要求比较高的场合下。MQTT协议重点在于消息队列的实现,其对消息投递的方式作出约定,并提供一些额外的通信保障。MQTT可采取原生的TCP实现,也有基于Websockets的实现版本。当然后者在网络字节的利用率上,不如前者那么精简。但浏览器端无法直接使用TCP协议,所以就只能基于Websockets协议开发。不过基于Websockets的应用也有方便之处:一是证书不需要额外配置,直接与网站共用一套基础设施;二是可使用Nginx等工具管理流量,与普通HTTP流量可共用一套配置方法。MQTT非常适合入门,原因如下:实际的应用场景远比理想中的复杂,无法一招走遍天下,必须做好取舍。MQTT协议在这方面做得很优秀,以后工作中可以作为参考,设计好自己负责的业务系统。

MQTT和Websocket的区别是什么
MQTT跟WebSocket关系不大。他们不是在一个层级的。WebSocket 很多网站使用轮询实现推送技术。轮询是在特定的的时间间隔(比如1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给浏览器。轮询的缺点很明显,浏览器需要不断的向服务器发出请求,然而HTTP请求的header是非常长的,而实际传输的数据可能很小,这就造成了带宽和服务器资源的浪费。Comet使用了AJAX改进了轮询,可以实现双向通信。但是Comet依然需要发出请求,而且在Comet中,普遍采用了长链接,这也会大量消耗服务器带宽和资源。于是,WebSocket协议应运而生。 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器通过 TCP 连接直接交换数据。WebSocket 连接本质上是一个 TCP 连接。WebSocket在数据传输的稳定性和数据传输量的大小方面,具有很大的性能优势。Websocket.org 比较了轮询和WebSocket的性能优势:HTTP 轮训每次需要返回871个字节,websocket每次只需要2个字节Use Case A: 1,000个客户端每秒接受一个message,网络吞吐量 (2*1,000)=2,000 bytes = 16,000 每秒bitsUse Case B: 10,000个客户端每秒接受一个message,网络吞吐量 (2*10,000)=20,000 bytes = 160,000 每秒bitsUse Case C: 100,000个客户端每秒接受一个message,网络吞吐量 (2*100,000)=200,000 bytes = 1,600,000 每秒bitsMQTT 协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:非常小的通信开销(最小的消息大小为 2 字节),小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。支持各种流行编程语言(包括 C,Java,Ruby,Python 等等)且易于使用的客户端;使用发布 / 订阅消息模式,提供一对多的消息发布,解除应用程序耦合。对负载内容屏蔽的消息传输。使用 TCP/IP 提供网络连接。有三种消息发布服务质量,让消息能按需到达目的地,适应在不稳定工作的网络传输需求 :"至多一次",消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。"至少一次",确保消息到达,但消息重复可能会发生。"只有一次",确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
简单回答一下, MQTT ( MQ Telemetry Transport ) 是针对物联网而设计的, 如手机对家里的智能开关, 而 WebSocket 是针对浏览器与服务器之间而设计的. 两者基本上是两个世界的东西. MQTT 只是一个接口, 让两个 "物件" 能够透过 TCP 协议通讯, 但并没有规定(在应用层面上)通讯中要怎样"对答", 如 pop3 邮件伺服器会有:S: 220 我是 xxx 服务器C: HELO myServerS: 250 Nice to meet youC: auth login....这些是没有硬性被定义的, 两个 "物件" 之间要怎麼"聊天", 由你自己来定.WebSocket 则是一个 http 协议中的伸延 (先这麼理解吧!), 而 http 协议, 基本上就是一个请求, 一个回答, 然後就自动挂线, 客端和服务器端不会婆婆妈妈. 但即使就前面说的, 一问一答, 当中便有大量的 header 字串来往, 如果要处理串流这样大的数据再 + 一大堆 header, 这样就是很庞大的负担, websocket 就开了这个婆妈之门, 客端和服务器端可以以 full duplex 的形式做大量 binary 的数据传输, 决省了一大堆 header, 其中一些安全机制也保证了大堆资料不被搞乱. 但无论如何, WebSocket 离不开 HTTP!!! 以上, 只是很概念的说法, 便於你理解, 详细你得自己翻下文献了.
MQTT 跟 Websocket 可以认为是不同层面的协议。MQTT 做原生设备的通信,MQTT over WebSocket 主要用于 MQTT 设备跟 Web 端通信。 MQTT是为了物联网场景设计的基于TCP的Pub/Sub协议,有许多为物联网优化的特性,比如适应不同网络的QoS、层级主题、遗言等等。WebSocket是为了HTML5应用方便与服务器双向通讯而设计的协议,HTTP握手然后转TCP协议,用于取代之前的Server Push、Comet、长轮询等老旧实现。两者之所有有交集,是因为一个应用场景:如何通过HTML5应用来作为MQTT的客户端,以便接受设备消息或者向设备发送信息,那么MQTT over WebSocket自然成了最合理的途径了。作者:张琪链接:http://www.zhihu.com/question/21816631/answer/81953429来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
根据你的描述: MQTT 跟 Websocket 可以认为是不同层面的协议。MQTT 做原生设备的通信,MQTT over WebSocket 主要用于 MQTT 设备跟 Web 端通信。

本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/59947.html。