-
Notifications
You must be signed in to change notification settings - Fork 426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reflection-based roles #356
Conversation
Hi @oberstet, Usage sample: declare the following classes import java.util.Arrays;
public class MyClass {
public int counter;
public int[] foo;
@Override
public String toString() {
return String.format("{counter: %d, foo:%s}", counter, Arrays.toString(foo));
}
} import io.crossbar.autobahn.wamp.reflectionRoles.WampTopic;
public class ComplexSubscriber {
@WampTopic("com.myapp.topic2")
public void OnTopic2(int number1, int number2, String c, MyClass d){
System.out.printf("Got event: number1:%d, number2:%d, c:%s, d: %s%n", number1, number2, c, d);
}
} Then call session.registerSubscriber: import io.crossbar.autobahn.wamp.Client;
import io.crossbar.autobahn.wamp.Session;
import io.crossbar.autobahn.wamp.interfaces.IInvocationHandler;
import io.crossbar.autobahn.wamp.reflectionRoles.ReflectionServices;
import io.crossbar.autobahn.wamp.reflectionRoles.WampProcedure;
import io.crossbar.autobahn.wamp.serializers.JSONSerializer;
import io.crossbar.autobahn.wamp.types.ExitInfo;
import io.crossbar.autobahn.wamp.types.InvocationDetails;
import io.crossbar.autobahn.wamp.types.InvocationResult;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();
Session mySession = new Session();
mySession.addOnJoinListener((session, sessionDetails) -> {
System.out.println("Connected!");
ReflectionServices reflectionServices = mySession.getReflectionServices();
// Subscribe to "com.myapp.topic2"
reflectionServices.registerSubscriber(new ComplexSubscriber());
});
Client client = new Client(mySession, "ws://127.0.0.1:8080/ws", "realm1", executor);
CompletableFuture<ExitInfo> exitInfoCompletableFuture = client.connect();
}
} This sample works with this code. In order to have the parameters c and d filled (and not null), make sure to compile with the "-parameters" flag, otherwise Java won't emit the names of the parameters, and the code will fail to attach them to the corresponding parameters. Elad. |
@darkl Hi Elad! Awesome. Really cool. This allows for a style that is definitely even more expressive for app code, which is good. Also, thanks a lot for outlining rationale, usage examples, todos and all. @om26er maybe you also have a look over the code as it is quite extensive and see if you have comments from you side (you are much more familiar with the details I guess by now). also you could also check over all what Elad wrote (in particular the todos) and file issues as you see fit. I think this is really worth following up on, and of course then also putting it on the frontpage etc |
I have been looking into this, the change is mostly isolated, so doesn't really change the existing code (which is a good thing). One big problem however is that the new code won't work on Android, except for Android 8.0+ aka API level 26[1]. We currently support API level 24 as minimum. I have spent quite some time trying to figure out if there is a way to get that working on older versions through a third party library, so far no luck. I came across these libraries that could help though. https://github.com/maxxedev/javapan @oberstet For now what we can do is to only land that feature for Netty (need to make some changes in gradle config for that). Your call. [1] https://developer.android.com/reference/java/lang/reflect/Parameter.html |
|
||
for (int i = 0; i < parameters.length; i++) { | ||
Parameter parameter = parameters[i]; | ||
String parameterName = parameter.getName(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Android, the main issue is this API(level 26 only) and of course its use is central to what we are trying to achieve here.
Is there any option for conditional compilation? (#ifdef in C#)
If this option exists, you can support parameter name mapping only for
netty. Also note my remark that parameter name mapping works only if the
user adds the "-parameters" flag, so you guys might just decide to ditch it
(IMO this feature is pretty neat, unfortunately Java makes life harder
about using it).
|
@om26er Ok, making it work on Netty only first is cool! We can figure out Android later. So I am going to merge this now - could you pls create a follow up PR with the gradle changes you mentioned? ah, and pls file follow up issues for the remaining todos mentioned by Elad |
@darkl awesome! thanks for coming around here and contributing=) |
Hi @oberstet,
This pull request contains a sketch for reflection based caller/callee roles. This is pretty cool.
Usage:
Callee proxy:
Declare an interface:
Use ReflectionServices property of session in order to obtain a proxy, and then call the desired method:
Callee
Declare a class
Use ReflectionServices property of service to register all procedures of an instance of this class:
TODOs
I really hope that this kind of feature will be integrated in AutobahnJava.
Feel free to ask me any question about this.
Elad