mqtt client has same client id。
how to closing old connection?
just like this.
New connection from 192.168.3.57 on port 1883.
1479826181: Client paho166768969170988 already connected, closing old connection.
1479826181: Client paho166768969170988 disconnected.
1479826181: New client connected from 192.168.3.57 as paho166768969170988 (c1, k60, u'admin').
EDIT:
String clientId ="**public_cloud**";
try {
MqttClient sampleClient = new MqttClient(config.getBroker(), clientId);
sampleClient.setCallback(new PushCallback());
MqttTopic mtopic = sampleClient.getTopic(config.getTopic());
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setConnectionTimeout(100);
connOpts.setKeepAliveInterval(200);
connOpts.setUserName(config.getUsername());
connOpts.setPassword(config.getPassword().toCharArray());
connOpts.setWill(mtopic, "close".getBytes(), 0, true);
sampleClient.connect(connOpts);
} catch (MqttException e) {
e.printStackTrace();
}
}
if the clientid is same,has error.
ConnectionLost,cause:(32109) - java.io.EOFException
Every connection to the broker MUST have a unique client id. This is part of the MQTT specification. How the broker handles a new connection with an existing client id, but most will disconnect the oldest connection.
The usual fix in the situation you are seeing is to use a randomly generated client id or the current timestamp
long time = new Date().getTime();
String clientId ="public_cloud" + time;
try {
MqttClient sampleClient = new MqttClient(config.getBroker(), clientId);
sampleClient.setCallback(new PushCallback());
MqttTopic mtopic = sampleClient.getTopic(config.getTopic());
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setConnectionTimeout(100);
connOpts.setKeepAliveInterval(200);
connOpts.setUserName(config.getUsername());
connOpts.setPassword(config.getPassword().toCharArray());
connOpts.setWill(mtopic, "close".getBytes(), 0, true);
sampleClient.connect(connOpts);
} catch (MqttException e) {
e.printStackTrace();
}
}
String clientId ="**public_cloud**";
try {
MqttClient sampleClient = new MqttClient(config.getBroker(), clientId);
sampleClient.setCallback(new PushCallback());
MqttTopic mtopic = sampleClient.getTopic(config.getTopic());
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setConnectionTimeout(100);
connOpts.setKeepAliveInterval(200);
connOpts.setUserName(config.getUsername());
connOpts.setPassword(config.getPassword().toCharArray());
connOpts.setWill(mtopic, "close".getBytes(), 0, true);
sampleClient.connect(connOpts);
} catch (MqttException e) {
e.printStackTrace();
}
}
If the clientId is the same, it has the error:
ConnectionLost,cause:(32109) - java.io.EOFException
Related
How can I publish to an MQTT topic using a URL.
i.e. "http://127.0.0.1/cmnd/power/on" will send "on" to "power" topic.
Ps: I am using HiveMQ
MQTT normally uses TCP as the underlaying protocol, (HTTP only in websocket context).
An Java-Example for connecting an mqtt client with the usage of the paho mqtt client lib:
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
...
final MqttClient mqttClient = new MqttClient("tcp://localhost:1883",
MqttClient.generateClientId(),
new MemoryPersistence());
opt.setUserName("User");
...
mqttClient.connect(opt);
...
//subscribe to all topics
mqttClient.subscribe("#");
//publish your status ON with a QoS 1 message that is retained
mqttClient.publish("cmnd/power, ("on").getBytes(), 1, true);
First you need make mqtt Connection and once the connection is successful you could send any payload to desired topic.
This is how you need to initiate connection.
String clientId = MqttClient.generateClientId();
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName("USERNAME");
options.setPassword("PASSWORD".toCharArray());
MqttAndroidClient client =
new MqttAndroidClient(this.getApplicationContext(), "tcp://broker.hivemq.com:1883",
clientId);
try {
IMqttToken token = client.connect(options);
token.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
// We are connected
Log.d(TAG, "onSuccess");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
// Something went wrong e.g. connection timeout or firewall problems
Log.d(TAG, "onFailure");
}
});
} catch (MqttException e) {
e.printStackTrace();
}
You can publish message to topic power
String topic = "power";
String payload = "ON";
byte[] encodedPayload = new byte[0];
try {
encodedPayload = payload.getBytes("UTF-8");
MqttMessage message = new MqttMessage(encodedPayload);
client.publish(topic, message);
} catch (UnsupportedEncodingException | MqttException e) {
e.printStackTrace();
}
This is the code and I am recieving the error 401: Authentication Error
public class Server {
// initialize socket and input stream
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream in = null;
public void tweet() throws TwitterException {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDaemonEnabled(true).setOAuthConsumerKey("......")
.setOAuthConsumerSecret("......")
.setOAuthAccessToken("......")
.setOAuthAccessTokenSecret(".....");
TwitterFactory tf = new TwitterFactory();
twitter4j.Twitter twitter = tf.getInstance();
List status = twitter.getHomeTimeline();
for (Status st : status) {
System.out.println(st.getUser().getName() + "---- Tweets----" + st.getText());
}
}
// constructor with port
public Server(int port) throws TwitterException {
// starts server and waits for a connection
try {
server = new ServerSocket(port);
System.out.println("Server started");
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted");
// takes input from the client socket
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
String line = "";
// reads message from client until "Over" is sent
while (!line.equals("Over")) {
try {
line = in.readUTF();
System.out.println(line);
if (line.equalsIgnoreCase("Data")) {
tweet();
}
} catch (IOException i) {
System.out.println(i);
}
}
System.out.println("Closing connection");
// close connection
socket.close();
in.close();
} catch (IOException i) {
System.out.println(i);
}
}
public static void main(String args[]) throws TwitterException {
Server server = new Server(5000);
}
}
Please make sure that the tokens are valid.
Then, you could try enabling system proxies like so:
System.setProperty("java.net.useSystemProxies", "true");
I am using the below code for push notification.
public void PushNotificationIOS(string message, string registrationKey)
{
string deviceID = registrationKey;
int port = 2195;
String hostname = System.Configuration.ConfigurationManager.AppSettings["HostName"];//"gateway.sandbox.push.apple.com";
string certPath = string.Empty;
certPath = System.Configuration.ConfigurationManager.AppSettings["CertificatePath"] + System.Configuration.ConfigurationManager.AppSettings["Cer
String certificatePath = System.Web.HttpContext.Current.Server.MapPath(certPath);
string certPassword = System.Configuration.ConfigurationManager.AppSettings["CertificatePassword"];
TcpClient client = new TcpClient(hostname, port);
try
{
X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), certPassword);
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)32);
writer.Write(StringToByteArray(deviceID.ToUpper()));
String payload = "{\"aps\":{\"alert\":\"" + message + "\",\"badge\":0,\"sound\":\"default\"}}";
writer.Write((byte)0);
writer.Write((byte)payload.Length);
byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(b1);
writer.Flush();
byte[] array = memoryStream.ToArray();
sslStream.Write(array);
sslStream.Flush();
client.Close();
}
catch (System.Security.Authentication.AuthenticationException ex)
{
client.Close();
}
}
I am getting the following error
Authentication failed because the remote party has closed the transport stream.
On Trace, I am getting the below
System.Net.Security.SslState.CheckThrow(Boolean authSucessCheck)
at System.Net.Security.SslState.get_SecureStream()
at System.Net.Security.SslStream.Write(Byte[] buffer)
I tried all the things mentioned in various post but am not able to solve the issue.
Make sure certificate is valid & is not corrupted. You can regenerate certificate to be dead sure.
Try providing all the options for SecurityProtocolType like :
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls, false);
SecurityProtocolType.Tls12 can negotiate Transport layer security 1.1 or downwards too but try all options to be sure.
For more details on SecurityProtocolType refer :
https://msdn.microsoft.com/en-us/library/system.net.securityprotocoltype(v=vs.110).aspx
I am sending push notification for Iphone from an asp.net application Like this-
String msg5 = "{\"aps\":{\"NewsId\":3156,\"NewCat\":\"Agra\",\"Date1\":\"11Apr2015\",\"content-available\":1,\"alert\":\"HelloWorld\",\"sound\":\"default\",\"badge\":2}}";
and it is received by the client side perfectly. But When I place some Hindi Data in place of "HelloWorld" on alert key, Notification is not received by client side. Please Explain me what is the issue. My code to send Notification is -
public static void pushMessage(string deviceID)
{
int port = 2195;
String hostname = "gateway.sandbox.push.apple.com";
String certificatePath = System.Web.Hosting.HostingEnvironment.MapPath("~/Certificates.p12");
//X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "");//password
X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
TcpClient client = new TcpClient(hostname, port);
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)32);
writer.Write(HexStringToByteArray(deviceID.ToUpper()));
String msg4 = "{\"aps\":{\"NewsId\":3156,\"NewCat\":\"Agra\",\"Date1\":\"11Apr2015\",\"content-available\":1,\"alert\":\"मुख्यमंत्री ने जर्मनी के उद्यमियों को राज्य में निवेश के लिए आमंत्रित किया\",\"sound\":\"default\",\"badge\":2}}";
String msg5 = "{\"aps\":{\"NewsId\":3156,\"NewCat\":\"Agra\",\"Date1\":\"11Apr2015\",\"content-available\":1,\"alert\":\"HelloWorld\",\"sound\":\"default\",\"badge\":2}}";
writer.Write((byte)0);
writer.Write((byte)msg5.Length);
byte[] b1 = System.Text.Encoding.UTF8.GetBytes(msg5);
writer.Write(b1);
writer.Flush();
byte[] array = memoryStream.ToArray();
sslStream.Write(array);
sslStream.Flush();
client.Close();
}
catch (System.Security.Authentication.AuthenticationException ex)
{
client.Close();
}
catch (Exception e)
{
client.Close();
}
But In place of UTF8 I use default encoding Like this
byte[] b1 = Encoding.UTF8.GetBytes(msg5)
Hindi text is received as ?????
Try this code, working fine for me..
Changes done
write b1.length instead of msg5.length(as in hindi length vary from original text).
public static void pushMessage(string deviceID, string text)
{
int port = 2195;
String hostname = "gateway.sandbox.push.apple.com";
String certificatePath = System.Web.Hosting.HostingEnvironment.MapPath("~/cert.p12");
X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
TcpClient client = new TcpClient(hostname, port);
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)32);
writer.Write(HexStringToByteArray(deviceID.ToUpper()));
String msg5 = "{\"aps\":{\"NewsId\":3156, \"alert\":\"" + text + "\",\"content-available\":\"1\"}}";
writer.Write((byte)0);
byte[] b1 = Encoding.UTF8.GetBytes(msg5);
writer.Write((byte)b1.Length);
writer.Write(b1);
writer.Flush();
byte[] array = memoryStream.ToArray();
sslStream.Write(array);
sslStream.Flush();
client.Close();
}
catch (System.Security.Authentication.AuthenticationException ex)
{
client.Close();
}
catch (Exception e)
{
client.Close();
}
}
I wrote the below code to send location coordinates to server:
setTitle("version 5.0");
Criteria criteria = new Criteria();
criteria.setHorizontalAccuracy(Criteria.NO_REQUIREMENT);
criteria.setVerticalAccuracy(Criteria.NO_REQUIREMENT);
criteria.setCostAllowed(true);
criteria.setPreferredPowerConsumption(Criteria.POWER_USAGE_LOW);
// bc.setFailoverMode(GPSInfo.GPS_MODE_ssCDMA_MS_ASSIST, 2, 100);
try {
LocationProvider lp=LocationProvider.getInstance(criteria);
if(lp !=null)
{
Location loc=null;
// while(loc==null)
// {
loc=lp.getLocation(-1);
// }
if(loc!=null){
add(new EditField(loc.getQualifiedCoordinates().getLatitude()+"\n"+loc.getQualifiedCoordinates().getLongitude(),""));
}
else
add(new EditField("unable to find the location provider", ""));
}
else
{
add(new EditField("unable to find the location provider", ""));
}
} catch (LocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ButtonField b = new ButtonField("Send");
add(b);
b.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
// TODO Auto-generated method stub
try{
String url="http://56.91.532.72:8084/SFTS/updateLocation.jsp?empid=12304&lat=16.9477&lon=82.23970;deviceside=true";
Dialog.alert(url);
ConnectionFactory factory = new ConnectionFactory();
// use the factory to get a connection
ConnectionDescriptor conDescriptor = factory.getConnection(url, TransportInfo.TRANSPORT_TCP_CELLULAR,null);
if ( conDescriptor != null ) {
HttpConnection conn = (HttpConnection) conDescriptor.getConnection();
Dialog.alert("http");
//conn.setRequestMethod(HttpConnection.GET);
Dialog.alert("conn.setre");
int responseCode = conn.getResponseCode();
Dialog.alert(Integer.toString(responseCode));
if(responseCode == HttpConnection.HTTP_OK)
{
Dialog.alert("OK");
InputStream data = conn.openInputStream();
StringBuffer raw = new StringBuffer();
byte[] buf = new byte[4096];
int nRead = data.read(buf);
while(nRead > 0)
{
raw.append(new String(buf, 0, nRead));
nRead = data.read(buf);
}
}
}
}catch(Exception e){
Dialog.alert(e.getMessage());
}
}
});
I am getting an exception Critical tunnel failure. But i am able to retrieve the location coordinates correctly. I am using blackberry 8520 with airtel sim which is enabled with data services. Actually this app worked well in the mobile with version 5.0. But it's not working in the mobile which i've upgraded from 4.6.1.3 to 5.0.0 what might be the problem? Please provide me a solution. thank you
I also tried the below url's:
http://56.91.532.72:8084/SFTS/updateLocation.jsp?empid=12304&lat=16.9477&lon=82.23970;deviceside=true;apn=null
http://56.91.532.72:8084/SFTS/updateLocation.jsp?empid=12304&lat=16.9477&lon=82.23970;deviceside=true;apn=airtelgprs.com
I also enabled apn settings in my mobile
It is because you haven't set up the apn correctly. As you are using direct tcp, the apn has to be set in order to connect to the network.
Also , network connections should be done on a separate thread.