I am trying to implement a CoAP client based on Californium. I make this client observing to a resource:
public static class CoapCl{
double val = 0;
CoapClient client = new CoapClient("coap://localhost/Ultrasonic");
CoapObserveRelation relation = client.observe(new CoapHandler() {
#Override public void onLoad(CoapResponse response)
{
val = Double.parseDouble(response.getResponseText());
}
#Override
public void onError() {
System.out.println("Failed");
}
});
}
I want to access the value "val" from another class. How can I do it ? I tried to call a reference from the CoapCl class like this and print the value out:
CoapCl client = new CoapCl();
while(true)
{
System.out.println("Testing: " + client.val);
}
This will print all the value I get from the CoAP client, both changed and unchanged value. What should I do if I only want to get the changed value ?
Well, the issue itself isn't related to Californium and CoAP.
Except that CoapHandler is async but this is rather a strench.
Nevertheless, I'd recommend to end up with some kind of callback:
public class CoapCl {
private final Consumer<Double> valueChangedAction;
private final CoapClient client = new CoapClient("coap://localhost/Ultrasonic");
public CoapCl(Consumer<Double> valueChangedAction) {
this.valueChangedAction = valueChangedAction;
}
public void run() {
client.observe(new CoapHandler() {
#Override
public void onLoad(CoapResponse response) {
valueChangedAction.accept(
Double.parseDouble(
response.getResponseText()
)
);
}
#Override
public void onError() {
System.out.println("Failed");
}
});
}
}
new CoapCl(val -> System.out.println("Testing: " + val)).run();
Please keep in mind you have to block the main thread someway to keep the program from immediate exit.
Before, you had blocked it with your infinite loop.
Now you'll have to use System.in.read() or Thread.sleep or something else if you have no such stuff yet in your program.
Related
I have a daemon thread running which calls a function (prepareOrder) whenever the cook is not busy and there are orders to be delivered. The prepareOrder calls the orderComplete function after a certain interval of time depending upon the time required to complete the order. Now the problem i am facing is only the last call to the prepareOrder gets displayed on sout.
The daemon
package ui;
import Model.takeOrderModel;
public class daemonThread extends Thread{
//call this method in the main method of driving fucntion
private takeOrderModel orderModel;
daemonThread(takeOrderModel orderModel){
this.orderModel = orderModel;
}
public void assignCook(){
while(true){
int toComplete = orderModel.toCompleteOrders.size();
if ( !orderModel.cookBusy && toComplete>0 ) orderModel.prepareOrder();
}
}
}
The prepare order function.
public void prepareOrder(){
// pick the last element from list
if (toCompleteOrders.size() > 0){
String nextPrepare = toCompleteOrders.get(toCompleteOrders.size()-1);
order orderToComplete = allOrdersPlaced.get(nextPrepare);
completeOrder(orderToComplete);
toCompleteOrders.remove(nextPrepare);
}
}
//Helper function to prepareOrder moves an order from toComplete to prepared order
private void completeOrder(order orderToComplete){
changeCookState();
new java.util.Timer().schedule(
new java.util.TimerTask(){
#Override
public void run() {
changeCookState();
preparedOrders.add(orderToComplete.id);
deliverOrder(orderToComplete.id);
}
}, (long) (orderToComplete.timeToComplete*60)
);
}
public void changeCookState(){
this.cookBusy = !cookBusy;
}
// MODIFIES removes a order from the prepared list and puts it in delivered list
public String deliverOrder(String completedOrder){
preparedOrders.remove(completedOrder);
deliveredOrders.add(completedOrder);
System.out.println(String.format("The order of %s is here", allOrdersPlaced.get(completedOrder).customerName));
return String.format("The order of %s is here", allOrdersPlaced.get(completedOrder).customerName);
}
The main function driving code.
orderMachine.takeNewOrder(fullMeal, "Tom");
orderMachine.takeNewOrder(halfMeal, "Bob");
daemonThread backThread = new daemonThread(orderMachine);
backThread.setDaemon(true);
backThread.assignCook();
Now for me only the last placed order("Bob") gets printed on sout. How can all calls created by Timer.schedule stay in stack.
Edits
The take new order function.
public boolean takeNewOrder(List<item> itemsInOrder, String customerName){
try {
order newOrder = new order(itemsInOrder, customerName);
allOrdersPlaced.put(newOrder.id, newOrder);
toCompleteOrders.add(newOrder.id);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Edit 2
here is the public repo containing the complete code
https://github.com/oreanroy/Share_code_samples/tree/master/takeOrder
The problem in this code is a concurrency bug - the cookBusy variable is being written to from two different threads. To fix this, use an AtomicBoolean instead of a boolean, as this is thread safe.
AtomicBoolean cookBusy = new AtomicBoolean(false);
Use compareAndSet to ensure the shared variable is set to a known value before updating it.
public void changeCookState(boolean busy){
if (!this.cookBusy.compareAndSet(!busy, busy))
{
throw new RuntimeException("shared variable set to unexpected value");
}
}
I am trying to implement the guaranteed message processing but the ack or fail methods on the Spout are not being called.
I am passing the a message ID object with the spout.
I am passing the tuple with each bolt and calling collector.ack(tuple) in each bolt.
Question
The ack or fail is not being called and I cannot work out why?
Here is a shortened code sample.
Spout Code using BaseRichSpout
public void nextTuple() {
for( String usage : usageData ) {
.... further code ....
String msgID = UUID.randomUUID().toString()
+ System.currentTimeMillis();
Values value = new Values(splitUsage[0], splitUsage[1],
splitUsage[2], msgID);
outputCollector.emit(value, msgID);
}
}
#Override
public void ack(Object msgId) {
this.pendingTuples.remove(msgId);
LOG.info("Ack " + msgId);
}
#Override
public void fail(Object msgId) {
// Re-emit the tuple
LOG.info("Fail " + msgId);
this.outputCollector.emit(this.pendingTuples.get(msgId), msgId);
}
Bolt Code using BaseRichBolt
#Override
public void execute(Tuple inputTuple) {
this.outputCollector.emit(inputTuple, new Values(serverData, msgId));
this.outputCollector.ack(inputTuple);
}
Final Bolt
#Override
public void execute(Tuple inputTuple) {
..... Simply reports does not emit .....
this.outputCollector.ack(inputTuple);
}
The reason the ack did not work was the use of the for loop in the spout. Changed this to a counter loop version below the emit and it works.
Example
index++;
if (index >= dataset.size()) {
index = 0;
}
Further to this thanks to the mailing list info.
Its because the Spout runs on a single thread and will block in a for loop, as next tuple will not return therefore it will never be able to call ACK method.
I'm working on a project that has hosts and clients, and where hosts can send commands to clients (via sockets).
I'm determined that using JSON to communicate works the best.
For example:
{
"method" : "toasty",
"params" : ["hello world", true]
}
In this example, when this JSON string is sent to the client, it will be processed and a suitable method within the client will be run as such:
public abstract class ClientProcessor {
public abstract void toasty(String s, boolean bool);
public abstract void shutdown(int timer);
private Method[] methods = getClass().getDeclaredMethods();
public void process(String data) {
try {
JSONObject json = new JSONObject(data);
String methodName = (String) json.get("method");
if (methodName.equals("process"))
return;
for (int i = 0; i < methods.length; i++)
if (methods[i].getName().equals(methodName)) {
JSONArray arr = json.getJSONArray("params");
int length = arr.length();
Object[] args = new Object[length];
for (int i2 = 0; i2 < length; i2++)
args[i2] = arr.get(i2);
methods[i].invoke(this, args);
return;
}
} catch (Exception e) {}
}
}
And using the ClientProcessor:
public class Client extends ClientProcessor {
#Override
public void toasty(String s, boolean bool) {
//make toast here
}
#Override
public void shutdown(int timer) {
//shutdown system within timer
}
public void processJSON(String json) {
process(json);
}
}
The JSON is sent by the server to the client, but the server could be modified to send different JSONs.
My questions are:
Is this a safe way of running methods by processing JSON?
Is there a better way to do this? I'm thinking that using reflection is terribly slow.
There's a 100 and 1 ways you can process a JSON message so that some processing occurs, but they'll all boil down to:
parse message
map message to method
invoke method
send response
While you could use a reflective call (performance-wise it would be fine for most cases) to invoke a method, that, imho, would be a little too open - a malicious client could for example crash your system by issuing wait calls.
Reflection also opens you up to having to correctly map the parameters, which is more complicated than the code you've shown in your question.
So don't use Reflection.
Would you could do is define a simple interface, implementations of which would understand how to process the parameters and have your processor (more commonly referred to as a Controller) invoke that, something like this:
public interface ServiceCall
{
public JsonObject invoke(JsonArray params) throws ServiceCallException;
}
public class ServiceProcessor
{
private static final Map<String, ServiceCall> SERVICE_CALLS = new HashMap<>();
static
{
SERVICE_CALLS.put("toasty", new ToastCall());
}
public String process(String messageStr)
{
try
{
JsonObject message = Json.createReader(new StringReader(messageStr)).readObject();
if (message.containsKey("method"))
{
String method = message.getString("method");
ServiceCall serviceCall = SERVICE_CALLS.get(method);
if (serviceCall != null)
{
return serviceCall.invoke(message.getJsonArray("params")).toString();
}
else
{
return fail("Unknown method: " + method);
}
}
else
{
return fail("Invalid message: no method specified");
}
}
catch (Exception e)
{
return fail(e.message);
}
}
private String fail(String message)
{
return Json.createObjectBuilder()
.add("status", "failed")
.add("message", message)
.build()
.toString();
}
private static class ToastCall implements ServiceCall
{
public JsonObject invoke(JsonArray params) throws ServiceCallException
{
//make toast here
}
}
}
Map method names to int constants and just switch(case) on these constants to invoke appropriate method.
"toasty" : 1
"shutdown": 2
switch()
case 1: toasty()
case 2: shutdown()
I believe you are trying to convert JSON string to Java object and vice versa... if that is the requirement then this would not be the right approach...
Try any open source API like Gson...
it is the API by Google for conversin of Java to JSON and vice versa.
Please check ...
https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/Gson.html
Let me know if you have any further questions...
I've implemented Gdxpay into my libgdx game but when I call requestPurchase(), nothing happens. I followed this tutorial https://github.com/libgdx/gdx-pay/wiki/Integration-example-with-resolvers but I'm not sure where I'm going wrong.
Here is the main game class where the purchase observer is:
public MyGame extends Application adapter {
public MyGame(IActivityRequestHandler handler) {
// TODO Auto-generated constructor stub
super();
myRequestHandler = handler;
// ---- IAP: define products ---------------------
purchaseManagerConfig = new PurchaseManagerConfig();
purchaseManagerConfig.addOffer(new Offer().setType(OfferType.ENTITLEMENT).setIdentifier(SKU_REMOVE_ADS));
}
public PurchaseObserver purchaseObserver = new PurchaseObserver() {
#Override
public void handleRestore (Transaction[] transactions) {
for (int i = 0; i < transactions.length; i++) {
if (checkTransaction(transactions[i].getIdentifier()) == true) break;
}
// to make a purchase (results are reported to the observer)
PurchaseSystem.purchase(SKU_REMOVE_ADS);
}
#Override
public void handleRestoreError (Throwable e) {
// getPlatformResolver().showToast("PurchaseObserver: handleRestoreError!");
Gdx.app.log("ERROR", "PurchaseObserver: handleRestoreError!: " + e.getMessage());
throw new GdxRuntimeException(e);
}
#Override
public void handleInstall () {
// getPlatformResolver().showToast("PurchaseObserver: installed successfully...");
Gdx.app.log("handleInstall: ", "successfully..");
}
#Override
public void handleInstallError (Throwable e) {
//getPlatformResolver().showToast("PurchaseObserver: handleInstallError!");
Gdx.app.log("ERROR", "PurchaseObserver: handleInstallError!: " + e.getMessage());
throw new GdxRuntimeException(e);
}
#Override
public void handlePurchase (Transaction transaction) {
checkTransaction(transaction.getIdentifier());
}
#Override
public void handlePurchaseError (Throwable e) {
if (e.getMessage().equals("There has been a Problem with your Internet connection. Please try again later")) {
// this check is needed because user-cancel is a handlePurchaseError too)
// getPlatformResolver().showToast("handlePurchaseError: " + e.getMessage());
}
throw new GdxRuntimeException(e);
}
#Override
public void handlePurchaseCanceled () {
}
};
protected boolean checkTransaction (String ID) {
boolean returnbool = false;
if (SKU_REMOVE_ADS.equals(ID)) {
myRequestHandler.showAds(false);
returnbool = true;
}
return returnbool;
}
public void create() {
...
Here is where requestPurchase is called:
public class MainMenu extends Screen {
#Override
public void update() {
...
if (removeBounds.contains(touchPoint.x, touchPoint.y)) {
MyGame.getPlatformResolver().requestPurchase(MyGame.SKU_REMOVE_ADS);
}
}
...
}
Many thanks.
Edit: Ok logcat says the following error when I request a purchase:
5188-5220/com.comp.myGame.android I/ERRORīš gdx-pay: requestPurchase(): purchaseManager == null
So that means pruchaseManager is null, but according to the tutorial in this instance it should cause the correct purchaseManager to be called so I'm still confused...
I had exactly the same issue. I followed the tutorial as well, but changed the distributed resolver system to a more local defined system where all app store keys are set in the main game class.
This didn't work (with the same error you got). I then re-engineered the code to follow exactly the tutorial - with all the resolver bells and whistles. Next, I got a "no suitable app store found" error while creating the purchaseManager (at this point, I celebrated because it at least TRIED to create it).
I think that it worked the second try has something to do with the sequence flow:
In the android/AndroidLauncher.java, onCreate:
MyGame myGame = new MyGame(this);
initialize(myGame, config);
// init IAP
myGame.setPlatformResolver(new AndroidResolver(myGame, this));
In core/MyGame.java, declarations:
public PurchaseObserver purchaseObserver = new BrainsPurchaseObserver();
public PurchaseManagerConfig purchaseManagerConfig;
In core/MyGame.java, constructor:
purchaseManagerConfig = new PurchaseManagerConfig();
Offer iap15Tipps = new Offer();
iap15Tipps.setIdentifier(Product.brains_hints_15.name());
iap15Tipps.setType(OfferType.CONSUMABLE);
purchaseManagerConfig.addOffer(iap15Tipps);
PlatformResolver.java and AndroidResolver.java as described in the tutorial. This worked to the point of the above error "no app store found".
Then I switched from gdx-pay 0.3.0 to 0.4.0 (by just incrementing the version in the gradle settings, it is already available in the repository), AND IT WORKED!
I suggest you check the sequence of IAP initializing you execute and switch to 0.4.0 if you are not already using it.
-- Michael
I want to know what is the difference between the
scraper.exitExecution() and
scraper.stopExecution() and
scraper.finishExecutingProcessor()
I have tried looking in to the java doc, I could not find anything over there. There seems to be no proper documentation for this. Please help.
I need a method to stop the execution of the scraper after some timeout, How can I do this?
Why not just download sourses of the library and look inside it?
Source code analyze shows, that the difference is only in statuses which these functions are set.
STATUS_STOPPED is interpreted as that configuration was aborted by user.
STATUS_EXIT is interpreted as configuration was just exited.
I.e. they are almost equal.
Let's do it together:
One:
public void exitExecution(String message) {
setStatus(STATUS_EXIT);
this.message = message;
}
Two:
public void stopExecution() {
setStatus(STATUS_STOPPED);
}
Next, going to BaseProcessor class, this is one of the two places where STATUS_EXIT or STATUS_STOPPED statuses are used:
public Variable run(Scraper scraper, ScraperContext context) {
int scraperStatus = scraper.getStatus();
if (scraperStatus == Scraper.STATUS_STOPPED || scraperStatus == Scraper.STATUS_EXIT) {
return EmptyVariable.INSTANCE;
}
...
}
Another one in class ConfigPanel:
public void onExecutionEnd(Scraper scraper) {
...
} else if (status == Scraper.STATUS_STOPPED) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GuiUtils.showWarningMessage("Configuration \"" + configDocument.getName() + "\" aborted by user!");
ide.setTabIcon(ConfigPanel.this, ResourceManager.SMALL_FINISHED_ICON);
}
});
} else if ( status == Scraper.STATUS_EXIT && message != null && !"".equals(message.trim()) ) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GuiUtils.showWarningMessage("Configuration exited: " + message);
ide.setTabIcon(ConfigPanel.this, ResourceManager.SMALL_FINISHED_ICON);
}
});
}
...
}