PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/org.eclipse.paho.sample.mqttv3app/src/main/java/org/eclipse/paho/sample/mqttv3app/Sample.java

http://github.com/eclipse/paho.mqtt.java
Java | 396 lines | 213 code | 39 blank | 144 comment | 28 complexity | 694518e9dd9a07ca9f0bd7021e15a9b5 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. /*******************************************************************************
  2. * Copyright (c) 2009, 2014 IBM Corp.
  3. *
  4. * All rights reserved. This program and the accompanying materials
  5. * are made available under the terms of the Eclipse Public License v2.0
  6. * and Eclipse Distribution License v1.0 which accompany this distribution.
  7. *
  8. * The Eclipse Public License is available at
  9. * https://www.eclipse.org/legal/epl-2.0
  10. * and the Eclipse Distribution License is available at
  11. * https://www.eclipse.org/org/documents/edl-v10.php
  12. *
  13. * Contributors:
  14. * Dave Locke - initial API and implementation and/or initial documentation
  15. */
  16. package org.eclipse.paho.sample.mqttv3app;
  17. import java.io.IOException;
  18. import java.sql.Timestamp;
  19. import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
  20. import org.eclipse.paho.client.mqttv3.MqttCallback;
  21. import org.eclipse.paho.client.mqttv3.MqttClient;
  22. import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
  23. import org.eclipse.paho.client.mqttv3.MqttException;
  24. import org.eclipse.paho.client.mqttv3.MqttMessage;
  25. import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence;
  26. /**
  27. * A sample application that demonstrates how to use the Paho MQTT v3.1 Client blocking API.
  28. *
  29. * It can be run from the command line in one of two modes:
  30. * - as a publisher, sending a single message to a topic on the server
  31. * - as a subscriber, listening for messages from the server
  32. *
  33. * There are three versions of the sample that implement the same features
  34. * but do so using using different programming styles:
  35. * <ol>
  36. * <li>Sample (this one) which uses the API which blocks until the operation completes</li>
  37. * <li>SampleAsyncWait shows how to use the asynchronous API with waiters that block until
  38. * an action completes</li>
  39. * <li>SampleAsyncCallBack shows how to use the asynchronous API where events are
  40. * used to notify the application when an action completes<li>
  41. * </ol>
  42. *
  43. * If the application is run with the -h parameter then info is displayed that
  44. * describes all of the options / parameters.
  45. */
  46. public class Sample implements MqttCallback {
  47. /**
  48. * The main entry point of the sample.
  49. *
  50. * This method handles parsing of the arguments specified on the
  51. * command-line before performing the specified action.
  52. */
  53. public static void main(String[] args) {
  54. // Default settings:
  55. boolean quietMode = false;
  56. String action = "publish";
  57. String topic = "";
  58. String message = "Message from blocking Paho MQTTv3 Java client sample";
  59. int qos = 2;
  60. String broker = "m2m.eclipse.org";
  61. int port = 1883;
  62. String clientId = null;
  63. String subTopic = "Sample/#";
  64. String pubTopic = "Sample/Java/v3";
  65. boolean cleanSession = true; // Non durable subscriptions
  66. boolean ssl = false;
  67. String password = null;
  68. String userName = null;
  69. // Parse the arguments -
  70. for (int i=0; i<args.length; i++) {
  71. // Check this is a valid argument
  72. if (args[i].length() == 2 && args[i].startsWith("-")) {
  73. char arg = args[i].charAt(1);
  74. // Handle arguments that take no-value
  75. switch(arg) {
  76. case 'h': case '?': printHelp(); return;
  77. case 'q': quietMode = true; continue;
  78. }
  79. // Now handle the arguments that take a value and
  80. // ensure one is specified
  81. if (i == args.length -1 || args[i+1].charAt(0) == '-') {
  82. System.out.println("Missing value for argument: "+args[i]);
  83. printHelp();
  84. return;
  85. }
  86. switch(arg) {
  87. case 'a': action = args[++i]; break;
  88. case 't': topic = args[++i]; break;
  89. case 'm': message = args[++i]; break;
  90. case 's': qos = Integer.parseInt(args[++i]); break;
  91. case 'b': broker = args[++i]; break;
  92. case 'p': port = Integer.parseInt(args[++i]); break;
  93. case 'i': clientId = args[++i]; break;
  94. case 'c': cleanSession = Boolean.valueOf(args[++i]).booleanValue(); break;
  95. case 'k': System.getProperties().put("javax.net.ssl.keyStore", args[++i]); break;
  96. case 'w': System.getProperties().put("javax.net.ssl.keyStorePassword", args[++i]); break;
  97. case 'r': System.getProperties().put("javax.net.ssl.trustStore", args[++i]); break;
  98. case 'v': ssl = Boolean.valueOf(args[++i]).booleanValue(); break;
  99. case 'u': userName = args[++i]; break;
  100. case 'z': password = args[++i]; break;
  101. default:
  102. System.out.println("Unrecognised argument: "+args[i]);
  103. printHelp();
  104. return;
  105. }
  106. } else {
  107. System.out.println("Unrecognised argument: "+args[i]);
  108. printHelp();
  109. return;
  110. }
  111. }
  112. // Validate the provided arguments
  113. if (!action.equals("publish") && !action.equals("subscribe")) {
  114. System.out.println("Invalid action: "+action);
  115. printHelp();
  116. return;
  117. }
  118. if (qos < 0 || qos > 2) {
  119. System.out.println("Invalid QoS: "+qos);
  120. printHelp();
  121. return;
  122. }
  123. if (topic.equals("")) {
  124. // Set the default topic according to the specified action
  125. if (action.equals("publish")) {
  126. topic = pubTopic;
  127. } else {
  128. topic = subTopic;
  129. }
  130. }
  131. String protocol = "tcp://";
  132. if (ssl) {
  133. protocol = "ssl://";
  134. }
  135. String url = protocol + broker + ":" + port;
  136. if (clientId == null || clientId.equals("")) {
  137. clientId = "SampleJavaV3_"+action;
  138. }
  139. // With a valid set of arguments, the real work of
  140. // driving the client API can begin
  141. try {
  142. // Create an instance of this class
  143. Sample sampleClient = new Sample(url, clientId, cleanSession, quietMode,userName,password);
  144. // Perform the requested action
  145. if (action.equals("publish")) {
  146. sampleClient.publish(topic,qos,message.getBytes());
  147. } else if (action.equals("subscribe")) {
  148. sampleClient.subscribe(topic,qos);
  149. }
  150. } catch(MqttException me) {
  151. // Display full details of any exception that occurs
  152. System.out.println("reason "+me.getReasonCode());
  153. System.out.println("msg "+me.getMessage());
  154. System.out.println("loc "+me.getLocalizedMessage());
  155. System.out.println("cause "+me.getCause());
  156. System.out.println("excep "+me);
  157. me.printStackTrace();
  158. }
  159. }
  160. // Private instance variables
  161. private MqttClient client;
  162. private String brokerUrl;
  163. private boolean quietMode;
  164. private MqttConnectOptions conOpt;
  165. private boolean clean;
  166. private String password;
  167. private String userName;
  168. /**
  169. * Constructs an instance of the sample client wrapper
  170. * @param brokerUrl the url of the server to connect to
  171. * @param clientId the client id to connect with
  172. * @param cleanSession clear state at end of connection or not (durable or non-durable subscriptions)
  173. * @param quietMode whether debug should be printed to standard out
  174. * @param userName the username to connect with
  175. * @param password the password for the user
  176. * @throws MqttException
  177. */
  178. public Sample(String brokerUrl, String clientId, boolean cleanSession, boolean quietMode, String userName, String password) throws MqttException {
  179. this.brokerUrl = brokerUrl;
  180. this.quietMode = quietMode;
  181. this.clean = cleanSession;
  182. this.password = password;
  183. this.userName = userName;
  184. //This sample stores in a temporary directory... where messages temporarily
  185. // stored until the message has been delivered to the server.
  186. //..a real application ought to store them somewhere
  187. // where they are not likely to get deleted or tampered with
  188. String tmpDir = System.getProperty("java.io.tmpdir");
  189. MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(tmpDir);
  190. try {
  191. // Construct the connection options object that contains connection parameters
  192. // such as cleanSession and LWT
  193. conOpt = new MqttConnectOptions();
  194. conOpt.setCleanSession(clean);
  195. if(password != null ) {
  196. conOpt.setPassword(this.password.toCharArray());
  197. }
  198. if(userName != null) {
  199. conOpt.setUserName(this.userName);
  200. }
  201. // Construct an MQTT blocking mode client
  202. client = new MqttClient(this.brokerUrl,clientId, dataStore);
  203. // Set this wrapper as the callback handler
  204. client.setCallback(this);
  205. } catch (MqttException e) {
  206. e.printStackTrace();
  207. log("Unable to set up client: "+e.toString());
  208. System.exit(1);
  209. }
  210. }
  211. /**
  212. * Publish / send a message to an MQTT server
  213. * @param topicName the name of the topic to publish to
  214. * @param qos the quality of service to delivery the message at (0,1,2)
  215. * @param payload the set of bytes to send to the MQTT server
  216. * @throws MqttException
  217. */
  218. public void publish(String topicName, int qos, byte[] payload) throws MqttException {
  219. // Connect to the MQTT server
  220. log("Connecting to "+brokerUrl + " with client ID "+client.getClientId());
  221. client.connect(conOpt);
  222. log("Connected");
  223. String time = new Timestamp(System.currentTimeMillis()).toString();
  224. log("Publishing at: "+time+ " to topic \""+topicName+"\" qos "+qos);
  225. // Create and configure a message
  226. MqttMessage message = new MqttMessage(payload);
  227. message.setQos(qos);
  228. // Send the message to the server, control is not returned until
  229. // it has been delivered to the server meeting the specified
  230. // quality of service.
  231. client.publish(topicName, message);
  232. // Disconnect the client
  233. client.disconnect();
  234. log("Disconnected");
  235. }
  236. /**
  237. * Subscribe to a topic on an MQTT server
  238. * Once subscribed this method waits for the messages to arrive from the server
  239. * that match the subscription. It continues listening for messages until the enter key is
  240. * pressed.
  241. * @param topicName to subscribe to (can be wild carded)
  242. * @param qos the maximum quality of service to receive messages at for this subscription
  243. * @throws MqttException
  244. */
  245. public void subscribe(String topicName, int qos) throws MqttException {
  246. // Connect to the MQTT server
  247. client.connect(conOpt);
  248. log("Connected to "+brokerUrl+" with client ID "+client.getClientId());
  249. // Subscribe to the requested topic
  250. // The QoS specified is the maximum level that messages will be sent to the client at.
  251. // For instance if QoS 1 is specified, any messages originally published at QoS 2 will
  252. // be downgraded to 1 when delivering to the client but messages published at 1 and 0
  253. // will be received at the same level they were published at.
  254. log("Subscribing to topic \""+topicName+"\" qos "+qos);
  255. client.subscribe(topicName, qos);
  256. // Continue waiting for messages until the Enter is pressed
  257. log("Press <Enter> to exit");
  258. try {
  259. System.in.read();
  260. } catch (IOException e) {
  261. //If we can't read we'll just exit
  262. }
  263. // Disconnect the client from the server
  264. client.disconnect();
  265. log("Disconnected");
  266. }
  267. /**
  268. * Utility method to handle logging. If 'quietMode' is set, this method does nothing
  269. * @param message the message to log
  270. */
  271. private void log(String message) {
  272. if (!quietMode) {
  273. System.out.println(message);
  274. }
  275. }
  276. /****************************************************************/
  277. /* Methods to implement the MqttCallback interface */
  278. /****************************************************************/
  279. /**
  280. * @see MqttCallback#connectionLost(Throwable)
  281. */
  282. public void connectionLost(Throwable cause) {
  283. // Called when the connection to the server has been lost.
  284. // An application may choose to implement reconnection
  285. // logic at this point. This sample simply exits.
  286. log("Connection to " + brokerUrl + " lost!" + cause);
  287. System.exit(1);
  288. }
  289. /**
  290. * @see MqttCallback#deliveryComplete(IMqttDeliveryToken)
  291. */
  292. public void deliveryComplete(IMqttDeliveryToken token) {
  293. // Called when a message has been delivered to the
  294. // server. The token passed in here is the same one
  295. // that was passed to or returned from the original call to publish.
  296. // This allows applications to perform asynchronous
  297. // delivery without blocking until delivery completes.
  298. //
  299. // This sample demonstrates asynchronous deliver and
  300. // uses the token.waitForCompletion() call in the main thread which
  301. // blocks until the delivery has completed.
  302. // Additionally the deliveryComplete method will be called if
  303. // the callback is set on the client
  304. //
  305. // If the connection to the server breaks before delivery has completed
  306. // delivery of a message will complete after the client has re-connected.
  307. // The getPendingTokens method will provide tokens for any messages
  308. // that are still to be delivered.
  309. }
  310. /**
  311. * @see MqttCallback#messageArrived(String, MqttMessage)
  312. */
  313. public void messageArrived(String topic, MqttMessage message) throws MqttException {
  314. // Called when a message arrives from the server that matches any
  315. // subscription made by the client
  316. String time = new Timestamp(System.currentTimeMillis()).toString();
  317. System.out.println("Time:\t" +time +
  318. " Topic:\t" + topic +
  319. " Message:\t" + new String(message.getPayload()) +
  320. " QoS:\t" + message.getQos());
  321. }
  322. /****************************************************************/
  323. /* End of MqttCallback methods */
  324. /****************************************************************/
  325. static void printHelp() {
  326. System.out.println(
  327. "Syntax:\n\n" +
  328. " Sample [-h] [-a publish|subscribe] [-t <topic>] [-m <message text>]\n" +
  329. " [-s 0|1|2] -b <hostname|IP address>] [-p <brokerport>] [-i <clientID>]\n\n" +
  330. " -h Print this help text and quit\n" +
  331. " -q Quiet mode (default is false)\n" +
  332. " -a Perform the relevant action (default is publish)\n" +
  333. " -t Publish/subscribe to <topic> instead of the default\n" +
  334. " (publish: \"Sample/Java/v3\", subscribe: \"Sample/#\")\n" +
  335. " -m Use <message text> instead of the default\n" +
  336. " (\"Message from MQTTv3 Java client\")\n" +
  337. " -s Use this QoS instead of the default (2)\n" +
  338. " -b Use this name/IP address instead of the default (m2m.eclipse.org)\n" +
  339. " -p Use this port instead of the default (1883)\n\n" +
  340. " -i Use this client ID instead of SampleJavaV3_<action>\n" +
  341. " -c Connect to the server with a clean session (default is false)\n" +
  342. " \n\n Security Options \n" +
  343. " -u Username \n" +
  344. " -z Password \n" +
  345. " \n\n SSL Options \n" +
  346. " -v SSL enabled; true - (default is false) " +
  347. " -k Use this JKS format key store to verify the client\n" +
  348. " -w Passpharse to verify certificates in the keys store\n" +
  349. " -r Use this JKS format keystore to verify the server\n" +
  350. " If javax.net.ssl properties have been set only the -v flag needs to be set\n" +
  351. "Delimit strings containing spaces with \"\"\n\n" +
  352. "Publishers transmit a single message then disconnect from the server.\n" +
  353. "Subscribers remain connected to the server and receive appropriate\n" +
  354. "messages until <enter> is pressed.\n\n"
  355. );
  356. }
  357. }