I have set-up MQTT subscription as shown here:
package com.mqttW.demo;
import java.text.SimpleDateFormat;
import java.util.*;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.json.*;
public class WSync implements MqttCallback {
private String BROKER_URL = "";
private String PROTOCOL = "tcp://";
private String PORT = "1883";
private String TOPIC_ROOT_UNCNF = "/P/uncnf/";
private String TOPIC_ROOT_CNF = "/P/cnf/";
private DbOperations dbo = new DbOperations();
public void setBrokerUrl() {
this.BROKER_URL = PROTOCOL + System.getenv("BROKER_DNS") + ":" + PORT;
}
public String getBrokerUrl() {
return this.BROKER_URL;
}
public void publishPayload(String wName, String txnType, String payload) {
String clientId = wName + "-PUB";
String broker = this.getBrokerUrl();
String topic = TOPIC_ROOT_UNCNF + txnType + "/" + wName;
try {
MqttClient w = new MqttClient(broker, clientId);
w.connect();
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(2);
w.publish(topic, message);
w.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
public void processTxns(String wName) {
this.setBrokerUrl();
String broker = this.getBrokerUrl();
String clientId = wName + "-SUB";
String topic = TOPIC_ROOT_CNF + wName + "/CR";
MemoryPersistence persistence = new MemoryPersistence();
try {
MqttConnectOptions c = new MqttConnectOptions();
c.setCleanSession(false);
MqttClient w = new MqttClient(broker, clientId, persistence);
w.connect(c);
w.setCallback(this);
w.subscribe(topic, 2);
System.out.println(w.getServerURI() + " " + w.getClientId() + " " + w.isConnected());
} catch (MqttException e) {
e.printStackTrace();
}
}
#Override
public void connectionLost(Throwable arg0) {
System.out.println("Connection lost at : " + new SimpleDateFormat("yyyy-MM-dd.HH:mm:ss").format(new java.util.Date()));
}
#Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
// TODO Auto-generated method stub
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String s = new String(message.getPayload());
System.out.println(s);
}
}
The class with this method does implement MqttCallback. The System.out.println shows the broker URL, client ID and connected status (true) correctly.
So, what I am not getting is, why does the code terminate? Why is the subscription not set-up to listen for messages?
Related
This question already has answers here:
How do I fix a compilation error for unhandled exception on call to Thread.sleep()?
(2 answers)
Closed 5 years ago.
I'm having difficulty using InetAddress in Java for my Android project. I included the InetAddress library, however it never works.
The code is the follow:
InetAddress giriAddress = InetAddress.getByName("www.girionjava.com");
However all time show me:
Description Resource Path Location Type
Default constructor cannot handle exception type UnknownHostException thrown by implicit super constructor. Must define an explicit constructor LauncherActivity.java /src/my/app/client line 25 Java Problem
I included the library:
import java.net.InetAddress;
What must I do to use InetAddress in my Android Project?
The class of my project is:
public class LauncherActivity extends Activity
{
/** Called when the activity is first created. */
Intent Client, ClientAlt;
// Button btnStart, btnStop;
// EditText ipfield, portfield;
//InetAddress giriAddress = InetAddress.getByName("www.girionjava.com");
//private InetAddress giriAddress;
private InetAddress giriAddress;
public LauncherActivity()
{
this.giriAddress=InetAddress.getByName("www.girionjava.com");
}
private String myIp = "MYIP"; // Put your IP in these quotes.
private int myPort = PORT; // Put your port there, notice that there are no quotes here.
#Override
public void onStart()
{
super.onStart();
onResume();
}
#Override
public void onResume()
{
super.onResume();
Client = new Intent(this, Client.class);
Client.setAction(LauncherActivity.class.getName());
getConfig();
Client.putExtra("IP", myIp);
Client.putExtra("PORT", myPort);
startService(Client);
moveTaskToBack(true);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
Client = new Intent(this, Client.class);
Client.setAction(LauncherActivity.class.getName());
getConfig();
Client.putExtra("IP", myIp);
Client.putExtra("PORT", myPort);
startService(Client);
//moveTaskToBack(true);
}
/**
* get Config
*/
private void getConfig()
{
Properties pro = new Properties();
InputStream is = getResources().openRawResource(R.raw.config);
try
{
pro.load(is);
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
myIp = pro.getProperty("host");
myPort = Integer.valueOf(pro.getProperty("prot"));
System.out.println(myIp);
System.out.println(myPort);
}
}
The error's i get.
Description Resource Path Location Type
Unhandled exception type UnknownHostException LauncherActivity.java /Androrat/src/my/app/client line 31 Java Problem
Picture:
MY VERSION OF JAVA IS JAVA SE 1.6
I propose two alternatives:
If the IP of the given host is mandatory for your application to work properly, you could get it into the constructor and re-throw the exception as a configuration error:
public class MyClass
{
private InetAddress giriAddress;
public MyClass(...)
{
try {
this.giriAddress=InetAddress.getByName("www.girionjava.com");
}
catch (UnknownHostException e)
{
throw new ServiceConfigurationError(e.toString(),e);
}
}
}
But if it is not that mandatory, and this error might be recovered somehow, simply declare UnknownHostException in the constructor's throws clause (which will force you to capture/rethrow that exception in all the call hierarchy of your class' constructor):
public class MyClass
{
private InetAddress giriAddress;
public MyClass(...)
throws UnknownHostException
{
this.giriAddress=InetAddress.getByName("www.girionjava.com");
}
}
This is my simple method using my android application.
private static int timeout = 500;
private static int isIpAddressString(String tstr, byte[] ipbytes)
{
final String str = tstr;
boolean isIpAddress = true;
StringTokenizer st = new StringTokenizer(str, ".");
int idx = 0;
if(st.countTokens() == 4)
{
String tmpStr = null;
byte[] ipBytes = new byte[4];
while(st.hasMoreTokens())
{
tmpStr = st.nextToken();
for (char c: tmpStr.toCharArray()) {
if(Character.isDigit(c)) continue;
else
{
//if(c != '.')
{
isIpAddress = false;
break;
}
}
}
if(!isIpAddress) break;
ipBytes[idx] = (byte)(Integer.valueOf(tmpStr.trim()).intValue());
idx++;
}
System.arraycopy(ipBytes, 0, ipbytes, 0, ipbytes.length);
}
return idx;
}
public static boolean canResolveThisUrlString(final String TAG, String urlStr)
{
String resolveUrl = urlStr;
boolean isResolved = false;
java.net.InetAddress inetaddr = null;
try
{
//java.net.InetAddress addr = java.net.InetAddress.getByName(resolveUrl);
byte[] ipbytes = new byte[4];
if(isIpAddressString(urlStr, ipbytes) == 4)
{
inetaddr = java.net.InetAddress.getByAddress(ipbytes);
}
else
{
String host = null;
if(resolveUrl.startsWith("http") ||resolveUrl.startsWith("https") )
{
URL url = new URL(resolveUrl);
host = url.getHost();
}
else
host = resolveUrl;
inetaddr = java.net.InetAddress.getByName(host);
}
//isResolved = addr.isReachable(SettingVariables.DEFAULT_CONNECTION_TIMEOUT);
isResolved = inetaddr.isReachable(timeout);
//isResolved = true;
}
catch(java.net.UnknownHostException ue)
{
//com.skcc.alopex.v2.blaze.util.BlazeLog.printStackTrace(TAG, ue);
ue.printStackTrace();
isResolved = false;
}
catch(Exception e)
{
//com.skcc.alopex.v2.blaze.util.BlazeLog.printStackTrace(TAG, e);
e.printStackTrace();
isResolved = false;
}
//System.out.println(isResolved + "::::::::" + inetaddr.toString());
return isResolved;
}
You can test it with
public static void main(String[] args)
{
String urlString = "https://www.google.com";
String urlString1 = "www.google.com";
String urlString2 = "https://www.google.co.kr/search?q=InetAddress+create&rlz=1C1NHXL_koKR690KR690&oq=InetAddress+create&aqs=chrome..69i57j0l5.5732j0j8&sourceid=chrome&ie=UTF-8";
String urlString3 = "127.0.0.1";
//URL url = null;
try {
boolean canResolved = canResolveThisUrlString(null, urlString);
System.out.println("resolved " + canResolved + " : url [" + urlString + "]");
canResolved = canResolveThisUrlString(null, urlString1);
System.out.println("resolved " + canResolved + " : url [" + urlString1 + "]");
canResolved = canResolveThisUrlString(null, urlString2);
System.out.println("resolved " + canResolved + " : url [" + urlString2 + "]");
canResolved = canResolveThisUrlString(null, urlString3);
System.out.println("resolved " + canResolved + " : url [" + urlString3 + "]");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
you've got a UnknownHostException from your app when the url you've requested can't be resolved by whatever dns servers.
This case, you can not get any host name with ip address like 'www.girionjava.com' host in the internet world.
I am new in MQTT world. I have written a code to subscribe a topic and get message from topic and store it in database. Now my problem is how to put this code on server so that it will keep receiving message infinitely. I am trying to create a scheduler but in that case i am Getting Persistence Already in Use error from MQTT. I cannot change the clientId every time it connect. It is a fixed one in my case. Is there any way to get the persistence object which is already connected for a particular clientId?
Please help. Thanks and advance.
Please Find the code subscribe topic and messageArrived method of mqqt to get message from topic
public class AppTest {
private MqttHandler handler;
public void doApp() {
// Read properties from the conf file
Properties props = MqttUtil.readProperties("MyData/app.conf");
String org = props.getProperty("org");
String id = props.getProperty("appid");
String authmethod = props.getProperty("key");
String authtoken = props.getProperty("token");
// isSSL property
String sslStr = props.getProperty("isSSL");
boolean isSSL = false;
if (sslStr.equals("T")) {
isSSL = true;
}
// Format: a:<orgid>:<app-id>
String clientId = "a:" + org + ":" + id;
String serverHost = org + MqttUtil.SERVER_SUFFIX;
handler = new AppMqttHandler();
handler.connect(serverHost, clientId, authmethod, authtoken, isSSL);
// Subscribe Device Events
// iot-2/type/<type-id>/id/<device-id>/evt/<event-id>/fmt/<format-id>
handler.subscribe("iot-2/type/" + MqttUtil.DEFAULT_DEVICE_TYPE
+ "/id/+/evt/" + MqttUtil.DEFAULT_EVENT_ID + "/fmt/json", 0);
}
/**
* This class implements as the application MqttHandler
*
*/
private class AppMqttHandler extends MqttHandler {
// Pattern to check whether the events comes from a device for an event
Pattern pattern = Pattern.compile("iot-2/type/"
+ MqttUtil.DEFAULT_DEVICE_TYPE + "/id/(.+)/evt/"
+ MqttUtil.DEFAULT_EVENT_ID + "/fmt/json");
DatabaseHelper dbHelper = new DatabaseHelper();
/**
* Once a subscribed message is received
*/
#Override
public void messageArrived(String topic, MqttMessage mqttMessage)
throws Exception {
super.messageArrived(topic, mqttMessage);
Matcher matcher = pattern.matcher(topic);
if (matcher.matches()) {
String payload = new String(mqttMessage.getPayload());
// Parse the payload in Json Format
JSONObject contObj = new JSONObject(payload);
System.out
.println("jsonObject arrived in AppTest : " + contObj);
// Call method to insert data in database
dbHelper.insertIntoDB(contObj);
}
}
}
Code to connect to client
public void connect(String serverHost, String clientId, String authmethod,
String authtoken, boolean isSSL) {
// check if client is already connected
if (!isMqttConnected()) {
String connectionUri = null;
//tcp://<org-id>.messaging.internetofthings.ibmcloud.com:1883
//ssl://<org-id>.messaging.internetofthings.ibmcloud.com:8883
if (isSSL) {
connectionUri = "ssl://" + serverHost + ":" + DEFAULT_SSL_PORT;
} else {
connectionUri = "tcp://" + serverHost + ":" + DEFAULT_TCP_PORT;
}
if (client != null) {
try {
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
client = null;
}
try {
client = new MqttClient(connectionUri, clientId);
} catch (MqttException e) {
e.printStackTrace();
}
client.setCallback(this);
// create MqttConnectOptions and set the clean session flag
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(false);
options.setUserName(authmethod);
options.setPassword(authtoken.toCharArray());
//If SSL is used, do not forget to use TLSv1.2
if (isSSL) {
java.util.Properties sslClientProps = new java.util.Properties();
sslClientProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
options.setSSLProperties(sslClientProps);
}
try {
// connect
client.connect(options);
System.out.println("Connected to " + connectionUri);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
I've successfully implemented the simple Java Amazon SWF example called hello_sample. I created the ActivityWorker executable that polls SWF for activity tasks to process. I created the WorkflowWorker executable that polls SWF for decision tasks and I have a WorkflowStarter executable that kicks off the workflow execution. It works as advertised. What I don't understand is how do I configure and add a second activity to run after the first activity?
WorkflowWorker:
public class WorkflowWorker {
private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.defaultClient();
public static void main(String[] args) {
PollForDecisionTaskRequest task_request =
new PollForDecisionTaskRequest()
.withDomain(Constants.DOMAIN)
.withTaskList(new TaskList().withName(Constants.TASKLIST));
while (true) {
System.out.println(
"WorkflowWorker is polling for a decision task from the tasklist '" +
Constants.TASKLIST + "' in the domain '" +
Constants.DOMAIN + "'.");
DecisionTask task = swf.pollForDecisionTask(task_request);
String taskToken = task.getTaskToken();
if (taskToken != null) {
try {
executeDecisionTask(taskToken, task.getEvents());
}
catch (Throwable th) {
th.printStackTrace();
}
}
}
}
private static void executeDecisionTask(String taskToken, List<HistoryEvent> events) throws Throwable {
List<Decision> decisions = new ArrayList<Decision>();
String workflow_input = null;
int scheduled_activities = 0;
int open_activities = 0;
boolean activity_completed = false;
String result = null;
System.out.println("WorkflowWorker is executing the decision task for the history events: [");
for (HistoryEvent event : events) {
System.out.println(" " + event);
switch(event.getEventType()) {
case "WorkflowExecutionStarted":
workflow_input = event.getWorkflowExecutionStartedEventAttributes().getInput();
break;
case "ActivityTaskScheduled":
scheduled_activities++;
break;
case "ScheduleActivityTaskFailed":
scheduled_activities--;
break;
case "ActivityTaskStarted":
scheduled_activities--;
open_activities++;
break;
case "ActivityTaskCompleted":
open_activities--;
activity_completed = true;
result = event.getActivityTaskCompletedEventAttributes().getResult();
break;
case "ActivityTaskFailed":
open_activities--;
break;
case "ActivityTaskTimedOut":
open_activities--;
break;
}
}
System.out.println("]");
if (activity_completed) {
decisions.add(
new Decision()
.withDecisionType(DecisionType.CompleteWorkflowExecution)
.withCompleteWorkflowExecutionDecisionAttributes(
new CompleteWorkflowExecutionDecisionAttributes()
.withResult(result)));
}
else {
if (open_activities == 0 && scheduled_activities == 0) {
ScheduleActivityTaskDecisionAttributes attrs =
new ScheduleActivityTaskDecisionAttributes()
.withActivityType(new ActivityType()
.withName(Constants.ACTIVITY)
.withVersion(Constants.ACTIVITY_VERSION))
.withActivityId(UUID.randomUUID().toString())
.withInput(workflow_input);
decisions.add(
new Decision()
.withDecisionType(DecisionType.ScheduleActivityTask)
.withScheduleActivityTaskDecisionAttributes(attrs));
}
else {
// an instance of HelloActivity is already scheduled or running. Do nothing, another
// task will be scheduled once the activity completes, fails or times out
}
}
System.out.println("WorkflowWorker is exiting the decision task with the decisions " + decisions);
swf.respondDecisionTaskCompleted(
new RespondDecisionTaskCompletedRequest()
.withTaskToken(taskToken)
.withDecisions(decisions));
}
}
ActivityWorker:
public class ActivityWorker {
private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.defaultClient();
private static CountDownLatch waitForTermination = new CountDownLatch(1);
private static volatile boolean terminate = false;
private static String executeActivityTask(String g_species) throws Throwable {
String s = " ******** Hello, " + g_species + "!";
System.out.println(s);
String cwd = Paths.get(".").toAbsolutePath().normalize().toString();
String filename = "g_species.txt";
Path filePath = Paths.get(cwd, filename);
String filePathName = filePath.toString();
BufferedWriter output = null;
try {
File file = new File (filePathName);
output = new BufferedWriter(new FileWriter(file));
output.write(g_species);
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (output != null) {
output.close();
}
}
return g_species;
}
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
terminate = true;
System.out.println("ActivityWorker is waiting for the current poll request to return before shutting down.");
waitForTermination.await(60, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
// ignore
System.out.println(e.getMessage());
}
}
});
try {
pollAndExecute();
}
finally {
waitForTermination.countDown();
}
}
public static void pollAndExecute() {
while (!terminate) {
System.out.println("ActivityWorker is polling for an activity task from the tasklist '"
+ Constants.TASKLIST + "' in the domain '" + Constants.DOMAIN + "'.");
ActivityTask task = swf.pollForActivityTask(new PollForActivityTaskRequest()
.withDomain(Constants.DOMAIN)
.withTaskList(new TaskList().withName(Constants.TASKLIST)));
String taskToken = task.getTaskToken();
if (taskToken != null) {
String result = null;
Throwable error = null;
try {
System.out.println("ActivityWorker is executing the activity task with input '" + task.getInput() + "'.");
result = executeActivityTask(task.getInput());
}
catch (Throwable th) {
error = th;
}
if (error == null) {
System.out.println("The activity task succeeded with result '" + result + "'.");
swf.respondActivityTaskCompleted(
new RespondActivityTaskCompletedRequest()
.withTaskToken(taskToken)
.withResult(result));
}
else {
System.out.println("The activity task failed with the error '"
+ error.getClass().getSimpleName() + "'.");
swf.respondActivityTaskFailed(
new RespondActivityTaskFailedRequest()
.withTaskToken(taskToken)
.withReason(error.getClass().getSimpleName())
.withDetails(error.getMessage()));
}
}
}
}
}
WorkflowStarter that kicks it all off:
public class WorkflowStarter {
private static final AmazonSimpleWorkflow swf = AmazonSimpleWorkflowClientBuilder.defaultClient();
public static final String WORKFLOW_EXECUTION = "HelloWorldWorkflowExecution";
public static void main(String[] args) {
String workflow_input = "Amazon SWF";
if (args.length > 0) {
workflow_input = args[0];
}
System.out.println("Starting the workflow execution '" + WORKFLOW_EXECUTION +
"' with input '" + workflow_input + "'.");
WorkflowType wf_type = new WorkflowType()
.withName(Constants.WORKFLOW)
.withVersion(Constants.WORKFLOW_VERSION);
Run run = swf.startWorkflowExecution(new StartWorkflowExecutionRequest()
.withDomain(Constants.DOMAIN)
.withWorkflowType(wf_type)
.withWorkflowId(WORKFLOW_EXECUTION)
.withInput(workflow_input)
.withExecutionStartToCloseTimeout("90"));
System.out.println("Workflow execution started with the run id '" +
run.getRunId() + "'.");
}
}
I would recommend to not reinvent the wheel and use the AWS Flow Framework for Java that is officially supported by Amazon. It already implements all the low level details and allows you to focus on a business logic of your workflow directly.
Here is an example worklow that uses three activities (taken from the developer guide).
Activities interface:
import com.amazonaws.services.simpleworkflow.flow.annotations.Activities;
import com.amazonaws.services.simpleworkflow.flow.annotations.ActivityRegistrationOptions;
#ActivityRegistrationOptions(defaultTaskScheduleToStartTimeoutSeconds = 300,
defaultTaskStartToCloseTimeoutSeconds = 10)
#Activities(version="1.0")
public interface GreeterActivities {
public String getName();
public String getGreeting(String name);
public void say(String what);
}
Activities implementation:
public class GreeterActivitiesImpl implements GreeterActivities {
#Override
public String getName() {
return "World";
}
#Override
public String getGreeting(String name) {
return "Hello " + name;
}
#Override
public void say(String what) {
System.out.println(what);
}
}
Workflow interface:
import com.amazonaws.services.simpleworkflow.flow.annotations.Execute;
import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow;
import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions;
#Workflow
#WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 3600)
public interface GreeterWorkflow {
#Execute(version = "1.0")
public void greet();
}
Workflow implementation:
import com.amazonaws.services.simpleworkflow.flow.core.Promise;
public class GreeterWorkflowImpl implements GreeterWorkflow {
private GreeterActivitiesClient operations = new GreeterActivitiesClientImpl();
public void greet() {
Promise<String> name = operations.getName();
Promise<String> greeting = operations.getGreeting(name);
operations.say(greeting);
}
}
The worker that hosts both of them. Obviously it can be broken into separate activity and workflow workers:
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient;
import com.amazonaws.services.simpleworkflow.flow.ActivityWorker;
import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker;
public class GreeterWorker {
public static void main(String[] args) throws Exception {
ClientConfiguration config = new ClientConfiguration().withSocketTimeout(70*1000);
String swfAccessId = System.getenv("AWS_ACCESS_KEY_ID");
String swfSecretKey = System.getenv("AWS_SECRET_KEY");
AWSCredentials awsCredentials = new BasicAWSCredentials(swfAccessId, swfSecretKey);
AmazonSimpleWorkflow service = new AmazonSimpleWorkflowClient(awsCredentials, config);
service.setEndpoint("https://swf.us-east-1.amazonaws.com");
String domain = "helloWorldWalkthrough";
String taskListToPoll = "HelloWorldList";
ActivityWorker aw = new ActivityWorker(service, domain, taskListToPoll);
aw.addActivitiesImplementation(new GreeterActivitiesImpl());
aw.start();
WorkflowWorker wfw = new WorkflowWorker(service, domain, taskListToPoll);
wfw.addWorkflowImplementationType(GreeterWorkflowImpl.class);
wfw.start();
}
}
The workflow starter:
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient;
public class GreeterMain {
public static void main(String[] args) throws Exception {
ClientConfiguration config = new ClientConfiguration().withSocketTimeout(70*1000);
String swfAccessId = System.getenv("AWS_ACCESS_KEY_ID");
String swfSecretKey = System.getenv("AWS_SECRET_KEY");
AWSCredentials awsCredentials = new BasicAWSCredentials(swfAccessId, swfSecretKey);
AmazonSimpleWorkflow service = new AmazonSimpleWorkflowClient(awsCredentials, config);
service.setEndpoint("https://swf.us-east-1.amazonaws.com");
String domain = "helloWorldWalkthrough";
GreeterWorkflowClientExternalFactory factory = new GreeterWorkflowClientExternalFactoryImpl(service, domain);
GreeterWorkflowClientExternal greeter = factory.getClient("someID");
greeter.greet();
}
}
i have created JmDNS example:
public class Service {
public static void main(String[] args) {
try {
JmDNS mdnsServer = null;
mdnsServer = JmDNS.create("localhost");
// Register a test service.
ServiceInfo testService = ServiceInfo.create("_myTest._tcp.local.", "Test-Service", 3, "test_service");
mdnsServer.registerService(testService);
} catch (IOException e) {
e.printStackTrace();
}
}
}
It runs for few seconds then it exits program, So i am wondering is it blocking or non blocking. I was thinking since it broadcast service over network so we need to exit application manually
Same is true for following ServiceDiscovery
public class ServiceDiscovery {
private static ServiceListenerClass listener;
private static int count = 0;
public static void main(String[] args) throws IOException {
JmDNS jmdns = null;
InetAddress address = null;
String type = "_myTest._tcp.local.";
Enumeration<NetworkInterface> ifc = NetworkInterface.getNetworkInterfaces();
while (ifc.hasMoreElements()) {
NetworkInterface anInterface = ifc.nextElement();
if (anInterface.isUp()) {
Enumeration<InetAddress> addr = anInterface.getInetAddresses();
while (addr.hasMoreElements()) {
if (!(address = addr.nextElement()).isLoopbackAddress())
break;
}
}
}
jmdns = JmDNS.create(address, type);
listener = new ServiceListenerClass();
jmdns.addServiceListener(type, listener);
}
public static class ServiceListenerClass implements ServiceListener {
public void serviceAdded(ServiceEvent event) {
event.getDNS().requestServiceInfo(event.getInfo().getServer(), event.getName(), true);
}
public void serviceRemoved(ServiceEvent event) {
System.out.println((count--) + " " + event.getInfo().getName());
}
public void serviceResolved(ServiceEvent event) {
System.out.println((count++) + " :Res: " + event.getInfo().getName() + " " + event.getInfo().getPort() + " " + event.getInfo().getApplication()
+ " " + event.getInfo().getDomain() + " " + event.getInfo().getKey());
for (InetAddress address : event.getInfo().getInetAddresses())
System.out.println(address.getHostAddress());
}
}
}
Without guarantee: JmDNS.create is non-blocking, the one which is blocking is the jmdns.registerService() method.
I am using org.fusesource.mqtt (mqtt-client-1.0-20120208.162159-18-uber) and wrote a listener in Java based on the non-blocking example.
I use my listener class in the following way:
Listener mqList = new Listener("tcp://localhost:1883", "mytopic/#", "c:/test.log", true);
new Thread(mqList).start( );
This work perfectly.
If I create two instances/threads then conflicts seem to arise and I get connect/disconnect messages flowing over me.
Here is the usage that fails:
Listener mqList = new Listener("tcp://localhost:1883", "mytopic/#", "c:/test.log", true);
new Thread(mqList).start( );
Listener mqList1 = new Listener("tcp://localhost:1883", "mytopic1/#", "c:/test1.log", true);
new Thread(mqList1).start( );
My Listener class is quite simple and I am puzzled why this does not work in multiple threads. Any ideas/hints?
Here is my class definition:
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.UTF8Buffer;
import org.fusesource.mqtt.client.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.logging.*;
import java.io.*;
import java.net.URISyntaxException;
public class Listener implements Runnable{
private static final long DEFAULT_SLEEP_BEFORE_RE_ATTEMPT_IN_SECONDS = 5000;
private static final long DEFAULT_MAX_RE_ATTEMPT_DURATION_IN_SECONDS = 3600 * 3;
private long listenerSleepBeforeReAttemptInSeconds;
private long listenerMaxReAttemptDurationInSeconds;
private MQTT mqtt;
private ArrayList<Topic> topics;
private boolean listenerDebug;
private String listenerHostURI;
private String listenerTopic;
private String listenerLogFile;
private long listenerLastSuccessfulSubscription;
private Logger fLogger;
private String NEW_LINE = System.getProperty("line.separator");
public Listener(String listenerHostURI, String listenerTopic, String logFile, boolean debug) {
this(listenerHostURI, listenerTopic, logFile, DEFAULT_SLEEP_BEFORE_RE_ATTEMPT_IN_SECONDS, DEFAULT_MAX_RE_ATTEMPT_DURATION_IN_SECONDS, debug);
}
public Listener(String listenerHostURI, String listenerTopic, String logFile, long listenerSleepBeforeReAttemptInSeconds, long listenerMaxReAttemptDurationInSeconds, boolean debug) {
init(listenerHostURI, listenerTopic, logFile, listenerSleepBeforeReAttemptInSeconds, listenerMaxReAttemptDurationInSeconds, debug);
}
private void init(String listenerHostURI, String listenerTopic, String logFile, long listenerSleepBeforeReAttemptInSeconds, long listenerMaxReAttemptDurationInSeconds, boolean debug) {
this.listenerHostURI = listenerHostURI;
this.listenerTopic = listenerTopic;
this.listenerLogFile = logFile;
this.listenerSleepBeforeReAttemptInSeconds = listenerSleepBeforeReAttemptInSeconds;
this.listenerMaxReAttemptDurationInSeconds = listenerMaxReAttemptDurationInSeconds;
this.listenerDebug = debug;
initMQTT();
}
private void initMQTT() {
mqtt = new MQTT();
listenerLastSuccessfulSubscription = System.currentTimeMillis();
try {
fLogger = Logger.getLogger("eTactica.mqtt.listener");
FileHandler handler = new FileHandler(listenerLogFile);
fLogger.addHandler(handler);
} catch (IOException e) {
System.out.println("Logger - Failed");
}
try {
mqtt.setHost(listenerHostURI);
} catch (URISyntaxException e) {
stderr("setHost failed: " + e);
stderr(e);
}
QoS qos = QoS.AT_MOST_ONCE;
topics = new ArrayList<Topic>();
topics.add(new Topic(listenerTopic, qos));
}
private void stdout(String x) {
if (listenerDebug) {
fLogger.log(Level.INFO, x + NEW_LINE);
}
}
private void stderr(String x) {
if (listenerDebug) {
fLogger.log(Level.SEVERE, x + NEW_LINE);
}
}
private void stderr(Throwable e) {
if (listenerDebug) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
fLogger.log(Level.SEVERE, sw.toString() + NEW_LINE);
}
}
private void subscriptionSuccessful() {
listenerLastSuccessfulSubscription = System.currentTimeMillis();
}
private boolean tryToListen() {
return ((System.currentTimeMillis() - listenerLastSuccessfulSubscription) < listenerMaxReAttemptDurationInSeconds * 1000);
}
private void sleepBeforeReAttempt() throws InterruptedException {
stdout(String.format(("Listener stopped, re-attempt in %s seconds."), listenerSleepBeforeReAttemptInSeconds));
Thread.sleep(listenerSleepBeforeReAttemptInSeconds);
}
private void listenerReAttemptsOver() {
stdout(String.format(("Listener stopped since reattempts have failed for %s seconds."), listenerMaxReAttemptDurationInSeconds));
}
private void listen() {
final CallbackConnection connection = mqtt.callbackConnection();
final CountDownLatch done = new CountDownLatch(1);
/* Runtime.getRuntime().addShutdownHook(new Thread(){
#Override
public void run() {
setName("MQTT client shutdown");
stderr("Disconnecting the client.");
connection.getDispatchQueue().execute(new Runnable() {
public void run() {
connection.disconnect(new Callback<Void>() {
public void onSuccess(Void value) {
stdout("Disconnecting onSuccess.");
done.countDown();
}
public void onFailure(Throwable value) {
stderr("Disconnecting onFailure: " + value);
stderr(value);
done.countDown();
}
});
}
});
}
});
*/
connection.listener(new org.fusesource.mqtt.client.Listener() {
public void onConnected() {
stdout("Listener onConnected");
}
public void onDisconnected() {
stdout("Listener onDisconnected");
}
public void onPublish(UTF8Buffer topic, Buffer body, Runnable ack) {
stdout(topic + " --> " + body.toString());
ack.run();
}
public void onFailure(Throwable value) {
stdout("Listener onFailure: " + value);
stderr(value);
done.countDown();
}
});
connection.resume();
connection.connect(new Callback<Void>() {
public void onFailure(Throwable value) {
stderr("Connect onFailure...: " + value);
stderr(value);
done.countDown();
}
public void onSuccess(Void value) {
final Topic[] ta = topics.toArray(new Topic[topics.size()]);
connection.subscribe(ta, new Callback<byte[]>() {
public void onSuccess(byte[] value) {
for (int i = 0; i < value.length; i++) {
stdout("Subscribed to Topic: " + ta[i].name() + " with QoS: " + QoS.values()[value[i]]);
}
subscriptionSuccessful();
}
public void onFailure(Throwable value) {
stderr("Subscribe failed: " + value);
stderr(value);
done.countDown();
}
});
}
});
try {
done.await();
} catch (Exception e) {
stderr(e);
}
}
#Override
public void run() {
while (tryToListen()) {
initMQTT();
listen();
try {
sleepBeforeReAttempt();
} catch (InterruptedException e) {
stderr("Sleep failed:" + e);
stderr(e);
}
}
listenerReAttemptsOver();
}
}
A TCP port can have only one listener. That number in "tcp://localhost:1883" has to be unique for each listener. Someplace, presumably (I'm not familiar with this specific API) you're probably starting a client with a port number too; the numbers must match between the client and server.