Skip to content

Commit

Permalink
Bug: 459142 - WebSocket support for the Java client
Browse files Browse the repository at this point in the history
With this change, you can now use the Java client to connect to MQTT brokers supporting WebSockets.
To do this, use either ws or wss as the protocol type in the URI.
For example:

ws://localhost:1883
or
wss://localhost:1883

Signed-off-by: James Sutton <james.sutton@uk.ibm.com>
Change-Id: Iefa994ad5950ea2a66a4733512f62a2755fa0f82
  • Loading branch information
jpwsutton committed Sep 24, 2015
1 parent fa18abe commit d24aaff
Show file tree
Hide file tree
Showing 9 changed files with 956 additions and 0 deletions.
Expand Up @@ -15,7 +15,9 @@
* Ian Craggs - MQTT 3.1.1 support
* Ian Craggs - per subscription message handlers (bug 466579)
* Ian Craggs - ack control (bug 472172)
* James Sutton - Bug 459142 - WebSocket support for the Java client.
*/

package org.eclipse.paho.client.mqttv3;

import java.util.Hashtable;
Expand All @@ -32,6 +34,8 @@
import org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule;
import org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule;
import org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory;
import org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketSecureNetworkModule;
import org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketNetworkModule;
import org.eclipse.paho.client.mqttv3.internal.wire.MqttDisconnect;
import org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish;
import org.eclipse.paho.client.mqttv3.internal.wire.MqttSubscribe;
Expand Down Expand Up @@ -404,6 +408,47 @@ else if ((factory instanceof SSLSocketFactory) == false) {
}
}
break;
case MqttConnectOptions.URI_TYPE_WS:
shortAddress = address.substring(5);
host = getHostName(shortAddress);
port = getPort(shortAddress, 1883);
if (factory == null) {
factory = SocketFactory.getDefault();
}
else if (factory instanceof SSLSocketFactory) {
throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_SOCKET_FACTORY_MISMATCH);
}
netModule = new WebSocketNetworkModule(factory, host, port, clientId);
((WebSocketNetworkModule)netModule).setConnectTimeout(options.getConnectionTimeout());
break;
case MqttConnectOptions.URI_TYPE_WSS:
shortAddress = address.substring(6);
host = getHostName(shortAddress);
port = getPort(shortAddress, 8883);
SSLSocketFactoryFactory wSSFactoryFactory = null;
if (factory == null) {
wSSFactoryFactory = new SSLSocketFactoryFactory();
Properties sslClientProps = options.getSSLProperties();
if (null != sslClientProps)
wSSFactoryFactory.initialize(sslClientProps, null);
factory = wSSFactoryFactory.createSocketFactory(null);

}
else if ((factory instanceof SSLSocketFactory) == false) {
throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_SOCKET_FACTORY_MISMATCH);
}

// Create the network module...
netModule = new WebSocketSecureNetworkModule((SSLSocketFactory) factory, host, port, clientId);
((WebSocketSecureNetworkModule)netModule).setSSLhandshakeTimeout(options.getConnectionTimeout());
// Ciphers suites need to be set, if they are available
if (wSSFactoryFactory != null) {
String[] enabledCiphers = wSSFactoryFactory.getEnabledCipherSuites(null);
if (enabledCiphers != null) {
((SSLNetworkModule) netModule).setEnabledCiphers(enabledCiphers);
}
}
break;
case MqttConnectOptions.URI_TYPE_LOCAL :
netModule = new LocalNetworkModule(address.substring(8));
break;
Expand Down
Expand Up @@ -55,6 +55,8 @@ public class MqttConnectOptions {
protected static final int URI_TYPE_TCP = 0;
protected static final int URI_TYPE_SSL = 1;
protected static final int URI_TYPE_LOCAL = 2;
protected static final int URI_TYPE_WS = 3;
protected static final int URI_TYPE_WSS = 4;

private int keepAliveInterval = KEEP_ALIVE_INTERVAL_DEFAULT;
private int maxInflight = MAX_INFLIGHT_DEFAULT;
Expand Down Expand Up @@ -494,6 +496,12 @@ else if (vURI.getScheme().equals("ssl")) {
else if (vURI.getScheme().equals("local")) {
return URI_TYPE_LOCAL;
}
else if (vURI.getScheme().equals("ws")){
return URI_TYPE_WS;
}
else if (vURI.getScheme().equals("wss")) {
return URI_TYPE_WSS;
}
else {
throw new IllegalArgumentException(srvURI);
}
Expand Down
@@ -0,0 +1,97 @@
/*******************************************************************************
* Copyright (c) 2009, 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* James Sutton - Bug 459142 - WebSocket support for the Java client.
*/
package org.eclipse.paho.client.mqttv3.internal.websocket;

import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;

public class Base64 {

private static final Base64 instance = new Base64();
private static final Base64Encoder encoder = instance.new Base64Encoder();

public static String encode (String s){
encoder.putByteArray("akey", s.getBytes());
String result = encoder.getBase64String();
return result;
}

public static String encodeBytes (byte[] b){
encoder.putByteArray("aKey", b);
String result = encoder.getBase64String();
return result;

}

public class Base64Encoder extends AbstractPreferences {

private String base64String = null;

public Base64Encoder() {
super(null, "");
}


protected void putSpi(String key, String value) {
base64String = value;
}

public String getBase64String() {
return base64String;
}


protected String getSpi(String key) {
return null;
}


protected void removeSpi(String key) {
}


protected void removeNodeSpi() throws BackingStoreException {

}


protected String[] keysSpi() throws BackingStoreException {
return null;
}


protected String[] childrenNamesSpi() throws BackingStoreException {
return null;
}


protected AbstractPreferences childSpi(String name) {
return null;
}


protected void syncSpi() throws BackingStoreException {

}


protected void flushSpi() throws BackingStoreException {

}

}

}
@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2009, 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* James Sutton - Bug 459142 - WebSocket support for the Java client.
*/
package org.eclipse.paho.client.mqttv3.internal.websocket;

public class HandshakeFailedException extends Exception {

private static final long serialVersionUID = 1L;

}

0 comments on commit d24aaff

Please sign in to comment.