I am using vertx in my project and I have problems with eventBus. If I understood right, it ables several languages to communicate using one string representing a server route. I have this code in my Server.java:
vertx.eventBus().registerHandler("getTree", new Handler<Message<String>>() {
public void handle(Message<String> e) {
// e.reply(call of function returning a json string);
}
});
In a javascript file, I need to get that json string just to print it for the moment. I have:
var eventBus = require('vertx/event_bus');
eventBus.send('getTree', '', function(reply) {
console.log('I received a reply ' + reply);
});
}
But nothing happens. Does anyone know why ?
I assume that you would like to see something like I received a reply in your console.
In order to be able to receive anything back to your JavaScript reply handler, you will need to change your Java message handler and call reply method on the incoming message e.g.
vertx.eventBus().registerHandler("getTree", new Handler<Message<String>>() {
public void handle(Message<String> msg) {
msg.reply("message from Java handler");
}
});
Without calling a reply method, nothing will happen in your JavaScript sender / reply receiver code.
After adding the mentioned change to your Java code you should be able to see following logs in console:
I received a reply message from Java handler
Note that even though you use different languages with Vert.x, entire logic is executed by JVM (JavaScript by Rhino open-source implementation).
Related
I have a scenario where i need to get data from Soap Service API call for each company.
For each industry i have thousands companies.
To call API , i need to set/pass few parameters apart from companyid. These parameters like user name , password , url , port etc... more of configuration or property files ..
These wont change for each call i.e. each Actor.
I am trying to implement the same using Akka Actor system for company retrieval i.e. calling Soap Service API .
Me new to Akka , any help how to do this ?
Thanks and Regards.
Tried :
CompanyActor -- which expects a companyId so created a CompanyInput as below
CompanyInput{
String companyId,
DataAPIConnection conn;
}
I am preparing CompanyInput where I get connection object "conn" by passing all valid userName and pwd , url to Soap Service API call.
I set companyId also.
Then create CompanyActor . where
#Override
public void onReceive(Object msg) throws Throwable {
if(msg instanceof CompanyInput) {
CompanyInput input = (CompanyInput) msg;
logger.info("onRecive msg companyId : " + input.getCompanyId());
}
}
Hope the above works fine. Please suggest if any corrections needed.
But from this I need to return CompanyInfo object i.e. reading the fields from SoapAPI call and populating CompanyInfo VO.
How to return an object from an Actor call ? onReceive() returning void so I return a Future ?
In Akka, messages go in one direction and the receive function does not return a value. Instead, you can send a reply message back to the original sender:
https://doc.akka.io/docs/akka/current/actors.html#reply-to-messages
You can use the "ask pattern" to simplify sending a message that expects a reply. Calling ask returns a CompletionStage in Java (or a Future in Scala) that completes when the receiving actor replies to its sender:
https://doc.akka.io/docs/akka/current/actors.html#ask-send-and-receive-future
I am using the StreamObserver class found in the grpc-java project to set up some bidirectional streaming.
When I run my program, I make an undetermined number of requests to the server, and I only want to call onCompleted() on the requestObserver once I have finished making all of the requests.
Currently, to solve this, I am using a variable "inFlight" to keep track of the requests that have been issued, and when a response comes back, I decrement "inFlight". So, something like this.
// issuing requests
while (haveRequests) {
MessageRequest request = mkRequest();
this.requestObserver.onNext(request);
this.inFlight++;
}
// response observer
StreamObserver<Message> responseObserver = new StreamObserver<Message> {
#Override
public void onNext(Message response) {
if (--this.onFlight == 0) {
this.requestObserver.onCompleted();
}
// work on message
}
// other methods
}
A bit pseudo-codey, but this logic works. However, I would like to get rid of the "inFlight" variable if possible. Is there anything within the StreamObserver class that allows this sort of functionality, without the need of an additional variable to track state? Something that would tell the number of requests issued and when they completed.
I've tried inspecting the object within the intellij IDE debugger, but nothing is popping out to me.
To answer your direct question, you can simply call onComplete from the while loop. All the messages passed to onNext. Under the hood, gRPC will send what is called a "half close", indicating that it won't send any more messages, but it is willing to receive them. Specifically:
// issuing requests
while (haveRequests) {
MessageRequest request = mkRequest();
this.requestObserver.onNext(request);
this.inFlight++;
}
requestObserver.onCompleted();
This ensures that all responses are sent, and in the order that you sent them. On the server side, when it sees the corresponding onCompleted callback, it can half-close its side of the connection by calling onComplete on its observer. (There are two observers on the server side one for receiving info from the client, one for sending info).
Back on the client side, you just need to wait for the server to half close to know that all messages were received and processed. Note that if there were any errors, you would get an onError callback instead.
If you don't know how many requests you are going to make on the client side, you might consider using an AtomicInteger, and call decrementAndGet when you get back a response. If the return value is 0, you'll know all the requests have completed.
I read many topics, but I couldn't find good answer. I'm working on Android application that uses Bluetooth to send and receive data from Microcontroller. I have already finished sending part and it works fine, but I have problem with receiving data on Android.
I'm using this library: https://android-arsenal.com/details/1/690#!description It doesn't have properly tutorial (or at least I don't see it), it just says about receiving data on android this:
//Listener for data receiving
bt.setOnDataReceivedListener(new OnDataReceivedListener() {
public void onDataReceived(byte[] data, String message) {
// Do something when data incoming
}
});
Does anybody have any idea how to use it? I have tried to write whole Bluetooth part by myself, but it was too hard, so I decided to use this library. I need to listen for incoming datas all the time, but also I can't do it in loop, because it will block the UI thread.
This is basically an callback function and as you can see in the parameter it is giving you 2 things data of type byte[] and message of type String. Now you can just log the 2 and see what values are being given to you like below
Log.d("Data value : " + data.toString() + "Message : " + message);
And then you can do whatever that you intend to do with it like update a view, etc. like below
TextView messageView = findViewById(R.id.message);
messageView.setText(message);
I'm writing Android application that has Java and native part. Java part sends messages to native part and receives answers back. Native part does all work on separate thread and when it returns answer I want to handle answers on main thread. Here is part of my extended Application class:
#Override
public void OnMessage(final Message msg, final long answerTo) {
Log.i(TAG, msg.ToStr()); // OK
handler.post(new Runnable() {
#Override
public void run() {
Log.i(TAG, msg.ToStr()); // Fatal signal 11 (SIGSEGV)
// at 0x74616862 (code=1), thread 13255
}
});
}
Native code calls OnMessage method on it's thread and trying to pass it to UI thread through Handler. And when I try to use any method of msg inside UI thread my program fails with SEGSEGV.
Significant fact is that Message class is the wrapper for C++ Message class. Wrapper was generated by SWIG.
I tried to debug it in GDB, and GDB even shows me stack trace, which ends in native Message.toStr method. But gdb refuses to print variables, saying "No symbol "*" in current context".
Please, help me to resolve this issue.
I don't think you are using Handler properly for what you are trying to do (copy object across threads). Check out the blog post here:
http://techtej.blogspot.com/2011/02/android-passing-data-between-main.html
Specifically the sending of messages to handlers like this:
Message msg = Message.obtain();
msg.obj = // Some Arbitrary object
mHandler.sendMessage(msg);
I don't think the way you are doing this performs the Handler magic of data copy between threads because it's just running a Runnable.
EDIT: I am curious to see if this was the issue, so even if it wasn't could you respond in a comment and let me know the outcome?
EDIT 2: So it looks like your object is probably being stored as a local ref in the JNI Layer. Unfortunately, that's not good enough for your purposes, you may need to make it a global ref. Just be wary of the fact that if you do make it a global ref, you have to delete it yourself in native code when you are done with it.
http://developer.android.com/training/articles/perf-jni.html#local_and_global_references
Finally I solved problem by myself. The problem was, that when we make call from C++ to Java, SWIG proxy method passed pointer to it's argument to Java side. Something like:
void SwigDirector_NativeLayerDelegate::OnMessage(Message msg, Long answer_to) {
...
*((Message **)&jmsg) = &msg;
...
jenv->CallStaticVoidMethod(..., jmsg, ...);
...
}
On Java side another proxy method recieved pointer, wrapped it with Java representation of Message class and passed it to Java method OnMessage:
public static void SwigDirector_NativeLayerDelegate_OnMessage(
NativeLayerDelegate self, long msg, long answer_to) {
self.OnMessage(new Message(msg, false), answer_to);
// false parameter means that Message object isn't owner of 'msg' pointer, so it
// shouldn't free it on finalize.
}
After OnMessage finished, native Message object was destructed in SwigDirector_NativeLayerDelegate::OnMessage and Java Message object kept pointer to destructed native object.
Solution
I've wrote custom typemaps for my Message object:
%typemap(directorin,descriptor="L$packagepath/$javaclassname;") Message
%{*((Message**)&$input) = new Message($1);%}
%typemap(javadirectorin,descriptor="L$packagepath/$javaclassname;") Message
%{new Message($1, true)%}
Now SwigDirector_NativeLayerDelegate::OnMessage creates copy of msg and Java object owns it:
// Native
void SwigDirector_NativeLayerDelegate::OnMessage(Message msg, Long answer_to) {
...
*((Message**)&jmsg) = new Message(msg);
...
jenv->CallStaticVoidMethod(..., jmsg, ...);
...
}
// Java
public static void SwigDirector_NativeLayerDelegate_OnMessage(
NativeLayerDelegate self, long msg, long answer_to) {
self.OnMessage(new Message(msg, true), answer_to);
}
Regarding Java NIO2.
Suppose we have the following to listen to client requests...
asyncServerSocketChannel.accept(null, new CompletionHandler <AsynchronousSocketChannel, Object>() {
#Override
public void completed(final AsynchronousSocketChannel asyncSocketChannel, Object attachment) {
// Put the execution of the Completeion handler on another thread so that
// we don't block another channel being accepted.
executer.submit(new Runnable() {
public void run() {
handle(asyncSocketChannel);
}
});
// call another.
asyncServerSocketChannel.accept(null, this);
}
#Override
public void failed(Throwable exc, Object attachment) {
// TODO Auto-generated method stub
}
});
This code will accept a client connection process it and then accept another.
To communicate with the server the client opens up an AsyncSocketChannel and fires the message.
The Completion handler completed() method is then invoked.
However, this means if the client wants to send another message on the same AsyncSocket instance it can't.
It has to create another AsycnSocket instance - which I believe means another TCP connection - which is performance hit.
Any ideas how to get around this?
Or to put the question another way, any ideas how to make the same asyncSocketChannel receive multipe CompleteionHandler completed() events?
edit:
My handling code is like this...
public void handle(AsynchronousSocketChannel asyncSocketChannel) {
ByteBuffer readBuffer = ByteBuffer.allocate(100);
try {
// read a message from the client, timeout after 10 seconds
Future<Integer> futureReadResult = asyncSocketChannel.read(readBuffer);
futureReadResult.get(10, TimeUnit.SECONDS);
String receivedMessage = new String(readBuffer.array());
// some logic based on the message here...
// after the logic is a return message to client
ByteBuffer returnMessage = ByteBuffer.wrap((RESPONSE_FINISHED_REQUEST + " " + client
+ ", " + RESPONSE_COUNTER_EQUALS + value).getBytes());
Future<Integer> futureWriteResult = asyncSocketChannel.write(returnMessage);
futureWriteResult.get(10, TimeUnit.SECONDS);
} ...
So that's it my server reads a message from the async channe and returns an answer.
The client blocks until it gets the answer. But this is ok. I don't care if client blocks.
Whent this is finished, client tries to send another message on same async channel and it doesn't work.
There are 2 phases of connection and 2 different kind of completion handlers.
First phase is to handle a connection request, this is what you have programmed (BTW as Jonas said, no need to use another executor). Second phase (which can be repeated multiple times) is to issue an I/O request and to handle request completion. For this, you have to supply a memory buffer holding data to read or write, and you did not show any code for this. When you do the second phase, you'll see that there is no such problem as you wrote: "if the client wants to send another message on the same AsyncSocket instance it can't".
One problem with NIO2 is that on one hand, programmer have to avoid multiple async operations of the same kind (accept, read, or write) on the same channel (or else an error occur), and on the other hand, programmer have to avoid blocking wait in handlers. This problem is solved in df4j-nio2 subproject of the df4j actor framework, where both AsyncServerSocketChannel and AsyncSocketChannel are represented as actors. (df4j is developed by me.)
First, you should not use an executer like you have in the completed-method. The completed-method is already handled in a new worker-thread.
In your completed-method for .accept(...), you should call asychSocketChannel.read(...) to read the data. The client can just send another message on the same socket. This message will be handled with a new call to the completed-method, perhaps by another worker-thread on your server.