I'm trying to connect to the on-line broker https://test.mosquitto.org/ using the code below and the Paho library in Java:
private final String brokerURI = "test.mosquitto.org:1883"; //should be changed to 8883 with SSL
try { //tentativo di creazione del client
client = new MqttClient(brokerURI, idClient); <--NullPointerException here
client.setCallback(new ClientCallback(codaTopic, codaMessaggi, finestra)); //set delle callback
setConnectionOptions(); //set delle opzioni connessione
client.connect(opzioni); //connessione al server
} catch (MqttException e) {
System.err.println(e.getMessage());
System.err.println("Connessione fallita Client, riavviare il sistema.");
}
Connection options are set here:
private void setConnectionOptions() {
opzioni = new MqttConnectOptions();
opzioni.setAutomaticReconnect(true);
opzioni.setCleanSession(false);
opzioni.setConnectionTimeout(30);
opzioni.setKeepAliveInterval(60);
}
but it continues to show a NullPointerException while creating the MqttClient. In particular the console displays:
Exception in thread "Thread-3" java.lang.NullPointerException
at org.eclipse.paho.client.mqttv3.MqttConnectOptions.validateURI(MqttConnectOptions.java:489)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.<init>(MqttAsyncClient.java:291)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.<init>(MqttAsyncClient.java:185)
at org.eclipse.paho.client.mqttv3.MqttClient.<init>(MqttClient.java:226)
at org.eclipse.paho.client.mqttv3.MqttClient.<init>(MqttClient.java:138)
at client.Client.run(Client.java:78)
How can i manage to connect and use SSL?
Surfing the net none of the tutorial or guides were useful, I already downloaded the mosquitto.org.crtfile for SSL connection, but i don't know where to use it and I found no tutorials.
EDIT
Changing the BrokerUri to
private final String brokerURI = "tcp://test.mosquitto.org:1883"; //indirizzo broker
the console shows the error
Client non connesso (32104)
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:31)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.sendNoWait(ClientComms.java:166)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.subscribe(MqttAsyncClient.java:835)
at org.eclipse.paho.client.mqttv3.MqttClient.subscribe(MqttClient.java:322)
at org.eclipse.paho.client.mqttv3.MqttClient.subscribe(MqttClient.java:315)
at client.Client.subscribe(Client.java:214)
at client.Client.run(Client.java:89)
while trying to subscribe to a Topic with the instruction
client.subscribe(topic, 1);
The topic argument is a String that contains the topic name.
Mosquitto's URI needs the protocol. Taking a look at its source code, this is where your exception is being thrown, class MqttConnectOpts.java :
protected static int validateURI(String srvURI) {
try {
URI vURI = new URI(srvURI);
if (!vURI.getPath().equals("")) {
throw new IllegalArgumentException(srvURI);
}
if (vURI.getScheme().equals("tcp")) {
return URI_TYPE_TCP;
}
else if (vURI.getScheme().equals("ssl")) {
return URI_TYPE_SSL;
}
else if (vURI.getScheme().equals("local")) {
return URI_TYPE_LOCAL;
}
else {
throw new IllegalArgumentException(srvURI);
}
} catch (URISyntaxException ex) {
throw new IllegalArgumentException(srvURI);
}
}
So, it accepts 3 types of protocol prefixes: tcp, ssl, local. Regarding your example, you could try it this way:
TCP
private final String brokerURI = "tcp://test.mosquitto.org:1883";
SSL
private final String brokerURI = "ssl://test.mosquitto.org:8883";
Related
I am using netty-socket.io and I implemented the server like the demo.
I receive onConnect event both on server and client, but when I sent a message {message: message} I don't get anything on the server event though I see the message being sent in the network tab.
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
final SocketIOServer server = new SocketIOServer(config);
server.addConnectListener(socketIOClient -> System.out.println("Connection test"));
server.addEventListener("messageevent", MessageEventObject.class, new DataListener<MessageEventObject>() {
#Override
public void onData(SocketIOClient socketIOClient, MessageEventObject messageEventObject, AckRequest ackRequest) throws Exception {
System.out.println("message received!");
}
});
server.start();
My MessageEventObject has String message property, constructor getters and setters, looking the same as client-sided.
And this is my websocket service client-sided:
export class WebsocketService {
private socket;
private subject = new Subject < any > ();
constructor() {
console.log('test!');
}
public connect(host: string, port: number) {
this.socket = io(`http://${host}:${port}`, {
'reconnection': false
});
this.socket.on('connect', this.onConnected);
this.socket.on('connect_error', this.onConnectionFailure);
}
public getConnectionStateUpdate(): Observable < any > {
return this.subject.asObservable();
}
public sendMessage(message: string) {
console.log('test');
this.socket.emit('messageevent', {
message: message
});
}
private onConnected = () => {
this.subject.next({
connected: true
});
}
private onConnectionFailure = () => {
this.subject.next({
connected: false
});
}
}
Is there anything that I did wrong?
I would love to answer my own question after tons of debugging and breaking my head, my laziness to use Engine IO with tomcat or jetty, and just wanting to use that awesome netty package which does not require any servlets, I tried to fix it and figure out.
At first I thought it was the client's protocol version, so I used the exact same client as the demo shows on their github page here but that didn't work so the problem is server-sided.
It appears that your object (MessageEventObject) must have a default empty constructor aswell in addition to your other constructors, probably because netty tries to build an empty object and it fails which causes an exception that you don't see.
I'm creating an app which generates a CSV file and some PDFs. I want my app to send those files to a server via FTPS protocol.
I'm using Apache Commons Net FTP library and it was perfectly working when I had "Require TLS session resumption on data connection when using PORT P" unchecked, but since I enabled it I can't send my files.
An error appeared :
450 TLS session of data connection has not resumed or the session does not match the control connection.
After some researches on this site I have overriden _prepareDataSocket_ in order to overcome this problem but now it just creates empty files on the server.
There is my overriden function :
#Override
protected void _prepareDataSocket_(final Socket socket) throws IOException {
if (socket instanceof SSLSocket) {
// Control socket is SSL
final SSLSession session = ((SSLSocket) _socket_).getSession();
if (session.isValid()) {
final SSLSessionContext context = session.getSessionContext();
try {
final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
sessionHostPortCache.setAccessible(true);
final Object cache = sessionHostPortCache.get(context);
final Method method = cache.getClass().getDeclaredMethod("put", Object.class, Object.class);
method.setAccessible(true);
method.invoke(cache, String
.format("%s:%s", socket.getInetAddress().getHostName(), String.valueOf(socket.getPort()))
.toLowerCase(Locale.ROOT), session);
method.invoke(cache, String
.format("%s:%s", socket.getInetAddress().getHostAddress(), String.valueOf(socket.getPort()))
.toLowerCase(Locale.ROOT), session);
} catch (NoSuchFieldException e) {
throw new IOException(e);
} catch (Exception e) {
throw new IOException(e);
}
} else {
throw new IOException("Invalid SSL Session");
}
}
}
and this is what FileZilla Server displays:
FileZilla Response
will this answer on another forum help?
http://forum.rebex.net/5673/450-error-connecting-to-ftp-requiring-explicit-ftp-over-tls
My question is simple.
I want to know how to fix port client has.
According to Eclipse documents and IBM's, User has to fix broker address(this is absolutely natural). But There are no mentions about way of how to fix client site port.
https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/com.ibm.mq.javadoc.doc/WMQMQxrClasses/com/ibm/micro/client/mqttv3/MqttClient.html
MQTT must be also on TCP Layer, so I think it's possible to fix port.
If you have ideas, let me know.
Thanks
Under normal circumstance you don't set the source port for TCP connections, you just let the OS pick a random free port.
If you fix the source port then you can only ever run 1 instance of the client at a time on a given machine and if you get a connection failure you have to wait for the TCP stack to free that socket up again before you can reconnect.
If for some reason you REALLY NEED to fix the source port then you could probably write a custom javax.net.SocketFactory implementation that you can hard code the source port. Then pass this in as part of the MQTTConnectOptions object, but again I'm really struggling to come up with a reason this is a good idea.
You don't specify the client's port, as it is choosen by the OS, just as with any client to server connection, like you don't need to do that with a HTTP connection either.
You specify the IP address and port of the MQTT broker in the URL you pass in the form of tcp://<address>:<port>, for example tcp://localhost:4922.
The code below shows how I connect a Paho client in an OSGi context, where all connections parameters are retrieved from the bundle context.
private void configureMqtt(BundleContext context) throws IOException, MqttException {
String broker = context.getProperty("mqtt.broker");
if (broker == null) {
throw new ServiceException("Define mqtt.broker");
}
String client = context.getProperty("mqtt.clientname");
if (client == null) {
throw new ServiceException("Define mqtt.clientname");
}
String dir = context.getProperty("mqtt.persistence");
if (dir == null) {
dir = "mqtt";
};
File directory = context.getDataFile(dir);
directory.mkdirs();
logger.config(() -> String.format("MQTT broker: %s, clientname: %s persistence: %s", broker, client, directory.getAbsolutePath()));
connectOptions = new MqttConnectOptions();
connectOptions.setWill(GARAGE + "/door", new byte[0], 0, true);
String ka = context.getProperty("mqtt.keepalive");
if (ka != null) {
connectOptions.setKeepAliveInterval(Integer.valueOf(ka));
}
persistence = new MqttDefaultFilePersistence(directory.getCanonicalPath());
mqttClient = new MqttAsyncClient(broker, client, persistence);
mqttClient.setCallback(this);
connect();
}
private void connect() {
logger.fine("Connecting to MQTT broker");
try {
IMqttToken token = mqttClient.connect(connectOptions);
IMqttActionListener listener = new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
logger.log(Level.INFO, "Connected to MQTT broker");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
logger.log(Level.WARNING, "Could not connect to MQTT broker, retrying in 3 seconds", exception);
service.schedule(this::connect, 3, TimeUnit.SECONDS);
}
};
token.setActionCallback(listener);
} catch (MqttException e) {
logger.log(Level.SEVERE, "Cannot reconnect to MQTT broker, giving up", e);
}
}
I am trying to create a socket connection between a .Net server application and Java Client Application.
I am getting an error from the java client application:
Connection refused: connect
Notes:
Communicating with a .Net Client Application, works fine.
I have disables the windows firewall
Undoubtedly, I am running the server application in the background and then I am running the client application
Following are my server code (C#):
public class Server
{
public Server()
{
CreateListener();
}
public void CreateListener()
{
// Create an instance of the TcpListener class.
TcpListener tcpListener = null;
IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
string output;
try
{
// Set the listener on the local IP address
// and specify the port.
tcpListener = new TcpListener(ipAddress, 13);
tcpListener.Start();
output = "Waiting for a connection...";
}
catch (Exception e)
{
output = "Error: " + e.ToString();
MessageBox.Show(output);
}
}
}
and client application code (Java):
public class smtpClient {
public void Send() {
Socket smtpSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
try {
smtpSocket = new Socket("localhost", 13); // FAILURE
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
It fails at the following line in the Java Client Application:
smtpSocket = new Socket("localhost", 13);
I can't tell what is the issue you are facing, but you need to start with a solid foundation to discover these issues.
As a rule of thumb, you should always write one piece (typically the server) first and verify connectivity (say using telnet) and then write the other piece (typically client) and verify its connectivity.
I always keep a Standard Client and Server handy to test whether its my code or its the environment/configuration.
Below is a sample code that works fine to test connectivity.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class ClientServer {
static void Main() {
new Thread(() => { StartServer("localhost", 5013); }).Start();
Thread.Sleep(100);
Console.WriteLine("\nPress enter to start the client...");
Console.ReadLine();
StartClient("localhost", 5013);
}
public static void StartServer(string serverInterface, int port) {
try {
IPHostEntry hostInfo = Dns.GetHostEntry(serverInterface);
string hostName = hostInfo.HostName;
IPAddress ipAddress = hostInfo.AddressList[0];
var server = new TcpListener(ipAddress, port);
server.Start();
Console.WriteLine($"Waiting for a connection at {server.LocalEndpoint}");
Console.WriteLine("Press ctrl+c to exit server...");
while (true) {
TcpClient client = server.AcceptTcpClient();
Console.WriteLine($"Server says - Client connected: {client.Client.RemoteEndPoint}");
ThreadPool.QueueUserWorkItem((state) => {
using (var _client = (TcpClient)state)
using (NetworkStream stream = _client.GetStream()) {
string msg = stream.ReadAsciiData();
if (msg == "Hello!") {
stream.WriteAsciiData($"Time:{DateTime.Now: yyyy/MM/dd HH:mm zzz}. Server name is {hostName}");
}
}
}, client);
}
} catch (Exception e) {
Console.WriteLine(e);
}
}
public static void StartClient(string serverInterface, int port) {
Console.WriteLine("Client started...");
try {
using (var client = new TcpClient(serverInterface, port))
using (NetworkStream stream = client.GetStream()) {
Console.WriteLine("Client says - Hello!");
stream.Write(Encoding.ASCII.GetBytes("Hello!"));
string msg = stream.ReadAsciiData();
Console.WriteLine($"Client says - Message from server: Server#{client.Client.RemoteEndPoint}: {msg}");
}
} catch (Exception e) {
Console.WriteLine(e);
}
Console.WriteLine("Client exited");
}
}
static class Utils {
public static void WriteAsciiData(this NetworkStream stream, string data) {
stream.Write(Encoding.ASCII.GetBytes(data));
}
public static string ReadAsciiData(this NetworkStream stream) {
var buffer = new byte[1024];
int read = stream.Read(buffer, 0, buffer.Length);
return Encoding.ASCII.GetString(buffer, 0, read);
}
public static void Write(this NetworkStream stream, byte[] data) {
stream.Write(data, 0, data.Length);
}
}
Now to your specific problem,
The choice of port 13, is not ideal for testing. Usually all ports below 1024 are considered privileged. i.e. a firewall or antivirus might block your attempt to listen on that port
Remember that IPV6 addresses plays a role. Your machine might have that enabled or disabled based on your configuration. You want to make sure that if your server is listening on a IPv6 interface, then your client also connects on the same
Which brings us to another related point: Irrespective of you are using IPv6 interface or not, the client needs to connect to the same interface the server is listening on. This might seem obvious, but is often missed. A typical machine
has at-least 2 interfaces: One for localhost (127...* called loopback interface) and another non local (typically 10...* or 192...*, but not restricted to it). It can so happen (especially when you pick the first available interface to bind your server without knowing which one it is) that server might be listening on non loopback interface like say 192.168.1.10 interface and the client might be connecting to 127.0.0.1, and you can see why the client will get "connection refused" errors
The sample code above works and you can test your code with it. You can us telnet for a client or just my sample code. You can play around changing the serverInterface values to some surprising discoveries which are accentuated by
ipAddress = hostInfo.AddressList[0] line
Hope this helps you with your debugging
I want to connect to a web service in a SSL connection. I connect to it and I get Service and Port but when I send Requests, it just returns null.
I searched the web but I could not understand what is the problem. may be because it is SSL, I need to connect it different as an Http connection, is it true?
I used auto code generators, they return null too, WireShark says that SSL Packages transmitted correctly but I cannot read the SOAP from these packages because they are SSL.
I test the web service with some applications and the tools and got correct answers from them.
Question:
is it possible that the null value is because SSL connection?
what mistakes could make this null returning?
How can I see the SOAP messeges I send and I get?
Here is My Java Code:
public class WS_TheServeice
{
private static QName qname;
private static URL url;
private static Service service;
private static ImplementationServicePortType sender;
static
{
qname = new QName("http://wservice.com/", "ImplementationService");
try
{
url = new URL("https://to-service?wsdl");
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
service = Service.create(url, qname);
sender = service.getPort(ImplementationServicePortType.class);
}
public static boolean PayToAcceptor(int AcceptorID, int Kipa) throws Exception
{
getUserInfo req = new getUserInfo();
req.zpID = AcceptorID;
req.kipa = Kipa;
getUserInfoResponse user_info = new getUserInfoResponse();//user_info is not NULL here
user_info = sender.getUserInfo(req);//But web server makes it NULL
if (user_info!=null) //// ---- HERE, IT Always return NULL
{
System.out.println("YouWon");
return true;
}
else
{
System.out.println("YouLoose");
return false;
}
}
public static void main(String Args[]) throws Exception
{
PayToAcceptor(12345, 1);
}
}
thanks.
Did you figure out how to do this? I've had similar problems in the past..
Did you try this: SSL Connection for consuming web services ?