-
1. Re: SessionContext and LocalContext within RPC
csa Feb 7, 2012 1:42 PM (in response to fvitorc)I assume your use case for this is to get access to the HTTP session? I have created a JIRA for this a while back: https://issues.jboss.org/browse/ERRAI-157
If it's for the session object, you could add a servlet filter and store the object in a ThreadLocal, given you use the SimpleDispatcher.
-
2. Re: SessionContext and LocalContext within RPC
fvitorc Feb 7, 2012 2:19 PM (in response to csa)Not actually. I wanted acess to the queue id of the client invoking the RPC. I guess that information is in LocalContext right?
I just put SessionContext in this discussion because those are the contexts provided by errai, so that would be a helpful information.
Anyway, does errai have acess to the Message object just before invoking the RPC?
I assume it does, and so, it would be possible to store the Message object in a ThreadLocal.
Then from the RPC we can grab it, and access LocalContext and SessionContext.
Regards,
Vitor.
-
3. Re: SessionContext and LocalContext within RPC
csa Feb 7, 2012 3:41 PM (in response to fvitorc)There's currently no API you could use to get access to the message from within an RPC endpoint. Can you elaborate on the feature you want to implement? Maybe we can come up with an alternative.
-
4. Re: SessionContext and LocalContext within RPC
fvitorc Feb 7, 2012 11:17 PM (in response to csa)Ok, so the first thing that comes into my mind in this situation is to use a ThreadLocal. Let me try to show a simple and ugly way to do this.
As I've seen from the source code, RPCs are initiated from class ConversationalEndpointCallback, correct?
Let's add ThreadLocal to it:
private static ThreadLocal<Message> currentMessage = new ThreadLocal<Message>();
public static Message getCurrentMessage() {
return currentMessage.get();
}
and right before the createConversation(message) statement, in the beginning of the try block, place this statement:
try {
currentMessage.set(message);
createConversation(message)
....
and create a finally block to the above try block like this:
...
finally {
currentMessage.remove();
}
Now, in our RPC service, we access the current message object using ConversationEndpointCallback.getCurrentMessage();
It's ugly but it works. So let's make it look nice. We can use resource injection for that.
First, let's make getCurrentMessage() protected, so that only classes in the same package can access it.
protected static Message getCurrentMessage() {
return currentMessage.get();
}
Now, create an extension component in the same package as ConversationalEndpointCallback that will add bindings to a resource provider:
@ExtensionComponent
public class MessageAccessorExtension implements ErraiConfigExtension {
@Override
public void configure(ErraiConfig config) {
config.addBinding(Message.class, new ResourceProvider<Message>() {
@Override
public Message get() {
return ConversationalEndpointCallback.getCurrentMessage();
}
});
}
}
That's it. Now we add a provider to our RPC service and access the Message object through this provider:
@Service
public class MyServiceImpl implements MyService {
@Inject
private Provider<Message> message;
@Override
public void doYourWork() {
Message m = message.get();
}
}
It would also be possible to add more bindings to simplify access of commonly used objects in RPC services, like:
@Override
public LocalContext get() {
Message m = ConversationalEndpointCallback.getCurrentMessage();
return LocalContext.get(m);
}
@Override
public SessionContext get() {
Message m = ConversationalEndpointCallback.getCurrentMessage();
return SessionContext.get(m);
}
What do you think of this solution?
Regards,
Vitor.
-
5. Re: SessionContext and LocalContext within RPC
csa Feb 8, 2012 11:35 AM (in response to fvitorc)Nice! I think your solution would work. However, it seems there's an opportunity for us to provide a higher level abstraction for what you are trying to do. What is your exact use case for this? To identify the client? I am thinking we could make a provider for the context itself which could then be injected.
-
6. Re: SessionContext and LocalContext within RPC
fvitorc Feb 8, 2012 12:21 PM (in response to csa)Yes, I need to identify the client. What I need is a list of all users currently logged in, along with their respective queue id. There's no specific need for the Message object. But I know that with it I can get the LocalContext of the currently running RPC.
Think of it as chat application (it's a little more complex than a chat application, but it serves as an example). When a user logs in, I register that user as logged in along with his queue id in a application scoped variable. So, if user A wants to send a private message to user B, I get the user B from the application scoped variable along with his queue id. With his queue id, it's now possible to send a message directly to user B.
I can use my hack for the moment, but I am looking forward to see this feature in future releases.
I've recently opened up another discussion about detecting user presence, because I need to know when a queue has been started or finished. But I still have no response for that.
Regards,
Vitor.