Open GoogleCodeExporter opened 8 years ago
Hi,
Issue25 describes a similar problem
(http://code.google.com/p/gwteventservice/issues/detail?id=25) and I think the
first step to solve it is to get rid of the "hard" module-base mapping which is
described in Issue22
(http://code.google.com/p/gwteventservice/issues/detail?id=22). That means
Issue22 has to be solved at first.
The code snippet of Issue22 shows the client side mapping to access the
RemoteService (GWT.getModuleBaseURL() is used). Could you please tell me how
you access the RemoteService in your application? I think you won't use
GWT.getModuleBaseURL().
Thanks in advance.
Sven S.
Original comment by sven.strohschein@googlemail.com
on 19 Sep 2010 at 2:01
Hi Sven,
Thanks for your response.
You are correct we are not looking to use GWT.getModuleBaseURL().
As i explained earlier we are using GWTRPC-Spring
(http://code.google.com/p/gwtrpc-spring/) to inject our GWT service
implementation classes as Spring beans for our POJOS.
So that means your services don't have to inherit RemoteServiceServlet just
implement your RemoteService interface. That means any Spring POJO can become a
Gwt RPC Service.
1) Can we make the gwteventservice mapping URL to be mapped to any URL such as
/apps/test/myservice.rpc instead of hard coding to
/<gwtmodulepath>/gwteventservice in web.xml?
2) Also in all the gwteventservice demos it looks like you have to create a
package name de.novanic.eventservice.service in your project to create the
EventServiceImpl class as a RemoteServiceServlet for registering the domains.
Is there a way instead of hardcoding the package name
(de.novanic.eventservice.service ) in your project it can be any package name
for the implementation of the EventServiceImpl class.
Original comment by leogem0...@gmail.com
on 21 Sep 2010 at 1:38
Hi Sven,
Please ignore my 2) suggestion as I am able to create my own package and
implement my own MyEventServiceImpl.
Currently the only limitation of the gwteventservice is /gwteventservice
mapping URL in web.xml and secondly the EventServiceImpl uses the GWT
RemoteServiceServlet instead of integrated with GWTRPC-Spring to implement
RemoteService interface and use the dependency injection to be invoked instead
of declaring as servlet in web.xml
Original comment by leogem0...@gmail.com
on 21 Sep 2010 at 8:17
Hi,
to implement the RemoteService interface isn't a problem, but I still haven't
found a mapping which works for both worlds (till yet). To use
GWT#getModuleBase() seems to be the common way, but isn't compatible with
GWT-RPC-Spring. I will set up a GWT-RPC-Spring project in the next days to find
a working solution.
Original comment by sven.strohschein@googlemail.com
on 22 Sep 2010 at 6:00
Hi Sven,
Thanks for your response.
It will be really great if we can find a solution of calling GWTEventService
with GWTRPC-Spring.
As for now due to the hardcoded /gwteventservice URL mapping in the web.xml for
the EventServiceImpl class I cannot find any way to call the GWTEventService
with our current GWTRPC-Spring RemoteService implementation. I alsi tried to
create a Spring Controller with @Controller annotation to inject dependency
injection for EventServiceImpl class so that I do not have to create the
mapping in web.xml for EventServiceImpl but when i gave the @RequestMapping for
the Spring controller to be /test/gwteventservice.do it did not worked and gave
me exception as Error in registering the client code.
We definately need the solution with GWTRPC-Spring to create a RemoteService
for EventServiceImpl class so that we do not have to define the
EventServiceImpl class in the web.xml with /gwteventservice as the hardcoded
URL.
Below is the implementation i was looking for calling EventServiceImpl as a
GWTRPC_Spring service instead of defining it in web.xml.
1) Setting for web.xml
<servlet>
<servlet-name>gwtDispatcher</servlet-name>
<servlet-class>org.gwtrpcspring.RemoteServiceDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gwtDispatcher</servlet-name>
<url-pattern>*.rpc</url-pattern>
</servlet-mapping>
2) EventServiceRemoteService
@RemoteServiceRelativePath("/apps/test/gwteventservice.rpc")
public interface EventServiceRemoteService extends RemoteService,EventService {
/**
* Utility/Convenience class.
* Use EventServiceRemoteService.App.getInstance() to access static instance of EventServiceRemoteServiceAsync
*/
public static class App {
private static final EventServiceRemoteServiceAsync ourInstance;
static {
ourInstance = (EventServiceRemoteServiceAsync) GWT.create(EventServiceRemoteService.class);
}
public static EventServiceRemoteServiceAsync getInstance() {
return ourInstance;
}
}
public void initEventService();
}
3) EventServiceRemoteServiceAsync
public interface EventServiceAppRemoteServiceAsync extends EventServiceAsync {
void initEventService(AsyncCallback<Void> async);
}
4) EventServiceRemoteServiceImpl implementation class as Spring Service
@Service
public class EventServiceRemoteServiceImpl implements EventServiceRemoteService
{
private static final ServerLogger LOG = ServerLoggerFactory.getServerLogger(EventServiceRemoteServiceImpl.class.getName());
private EventRegistry myEventRegistry;
/**
* Initializes the {@link de.novanic.eventservice.client.event.service.EventService}.
*/
public void initEventService() {
myEventRegistry = initEventRegistry();
final String theClientId = getClientId(true);
LOG.debug("Client \"" + theClientId + "\" initialized.");
}
/**
* Register listen for a domain.
*
* @param aDomain domain to listen to
*/
public void register(Domain aDomain) {
register(aDomain, null);
}
/**
* Register listen for a domain.
*
* @param aDomain domain to listen to
* @param anEventFilter EventFilter to filter events
*/
public void register(Domain aDomain, EventFilter anEventFilter) {
final String theClientId = getClientId();
myEventRegistry.registerUser(aDomain, theClientId, anEventFilter);
}
/**
* Register listen for a domain.
*
* @param aDomains domains to listen to
*/
public void register(Set<Domain> aDomains) {
for (Domain aDomain : aDomains) {
register(aDomain);
}
}
/**
* Register listen for domains.
*
* @param aDomains domains to listen to
* @param anEventFilter EventFilter to filter events (applied to all domains)
*/
public void register(Set<Domain> aDomains, EventFilter anEventFilter) {
for (Domain aDomain : aDomains) {
register(aDomain, anEventFilter);
}
}
/**
* Registers an {@link de.novanic.eventservice.client.event.listener.unlisten.UnlistenEvent} which is triggered on a
* timeout or when a user/client leaves a {@link de.novanic.eventservice.client.event.domain.Domain}. An
* {@link de.novanic.eventservice.client.event.listener.unlisten.UnlistenEvent} is hold at the server side and can
* contain custom data. Other users/clients can use the custom data when the event is for example triggered by a timeout.
*
* @param anUnlistenScope scope of the unlisten events to receive
* @param anUnlistenEvent {@link de.novanic.eventservice.client.event.listener.unlisten.UnlistenEvent} which should
* be transferred to other users/clients when a timeout occurs or a domain is leaved.
*/
public void registerUnlistenEvent(UnlistenEventListener.Scope anUnlistenScope, UnlistenEvent anUnlistenEvent) {
final String theClientId = getClientId();
myEventRegistry.registerUnlistenEvent(theClientId, anUnlistenScope, anUnlistenEvent);
}
/**
* Registers an {@link EventFilter} for the domain.
*
* @param aDomain domain to register the EventFilter to
* @param anEventFilter EventFilter to filter events for the domain
*/
public void registerEventFilter(Domain aDomain, EventFilter anEventFilter) {
final String theClientId = getClientId();
myEventRegistry.setEventFilter(aDomain, theClientId, anEventFilter);
}
/**
* Deregisters the {@link EventFilter} of the domain.
*
* @param aDomain domain to drop the EventFilters from
*/
public void deregisterEventFilter(Domain aDomain) {
final String theClientId = getClientId();
myEventRegistry.removeEventFilter(aDomain, theClientId);
}
/**
* Returns the EventFilter for the user domain combination.
*
* @param aDomain domain
* @return EventFilter for the domain
*/
public EventFilter getEventFilter(Domain aDomain) {
final String theClientId = getClientId();
return myEventRegistry.getEventFilter(aDomain, theClientId);
}
/**
* The listen method returns all events for the user (events for all domains where the user is registered and user
* specific events). If no events are available, the method waits a defined time before the events are returned.
* The client side calls the method with a defined interval to receive all events. If the client don't call the
* method in the interval, the user will be removed from the EventRegistry. The timeout time and the waiting time
* can be configured with {@link de.novanic.eventservice.config.EventServiceConfiguration}.
*
* @return list of events
*/
public List<DomainEvent> listen() {
final String theClientId = getClientId();
LOG.debug("Listen (client id \"" + theClientId + "\").");
return myEventRegistry.listen(theClientId);
}
/**
* Unlisten for events (for the current user) in all domains (deregisters the user from all domains).
*/
public void unlisten() {
final String theClientId = getClientId();
LOG.debug("Unlisten (client id \"" + theClientId + "\").");
myEventRegistry.unlisten(theClientId);
LOG.debug("Unlisten finished (client id \"" + theClientId + "\").");
}
/**
* Unlisten for events (for the current user) in the domain and deregisters the user from the domain.
*
* @param aDomain domain to unlisten
*/
public void unlisten(Domain aDomain) {
final String theClientId = getClientId();
LOG.debug("Unlisten (client id \"" + theClientId + "\").");
myEventRegistry.unlisten(aDomain, theClientId);
LOG.debug("Unlisten finished (client id \"" + theClientId + "\").");
}
/**
* Unlisten for events (for the current user) in the domains and deregisters the user from the domains.
*
* @param aDomains set of domains to unlisten
*/
public void unlisten(Set<Domain> aDomains) {
for (Domain theDomain : aDomains) {
unlisten(theDomain);
}
}
/**
* Checks if the user is registered for event listening.
*
* @param aDomain domain to check
* @return true when the user is registered for listening, otherwise false
*/
public boolean isUserRegistered(Domain aDomain) {
final String theClientId = getClientId();
return myEventRegistry.isUserRegistered(aDomain, theClientId);
}
/**
* Adds an event for all users in the domain.
*
* @param aDomain domain to add the event
* @param anEvent event to add
*/
public void addEvent(Domain aDomain, Event anEvent) {
myEventRegistry.addEvent(aDomain, anEvent);
}
/**
* Adds an event only for the current user.
*
* @param anEvent event to add to the user
*/
public void addEventUserSpecific(Event anEvent) {
final String theClientId = getClientId();
myEventRegistry.addEventUserSpecific(theClientId, anEvent);
}
/**
* Returns the domain names, where the user is listening to
*
* @return collection of domain names
*/
public Set<Domain> getActiveListenDomains() {
final String theClientId = getClientId();
return myEventRegistry.getListenDomains(theClientId);
}
/**
* Registers the {@link de.novanic.eventservice.config.loader.WebDescriptorConfigurationLoader},
* loads the first available configuration (with {@link de.novanic.eventservice.config.EventServiceConfigurationFactory})
* and initializes the {@link de.novanic.eventservice.service.registry.EventRegistry}.
*
* @param aConfig servlet configuration
* @return initialized {@link de.novanic.eventservice.service.registry.EventRegistry}
*/
private EventRegistry initEventRegistry(ServletConfig aConfig) {
final WebDescriptorConfigurationLoader theWebDescriptorConfigurationLoader = new WebDescriptorConfigurationLoader(aConfig);
final EventServiceConfigurationFactory theEventServiceConfigurationFactory = EventServiceConfigurationFactory.getInstance();
theEventServiceConfigurationFactory.addConfigurationLoader(ConfigLevelFactory.DEFAULT, theWebDescriptorConfigurationLoader);
final EventRegistryFactory theEventRegistryFactory = EventRegistryFactory.getInstance();
EventRegistry theEventRegistry = theEventRegistryFactory.getEventRegistry();
if (theWebDescriptorConfigurationLoader.isAvailable()) {
theEventServiceConfigurationFactory.loadEventServiceConfiguration();
}
return theEventRegistry;
}
private EventRegistry initEventRegistry() {
//final WebDescriptorConfigurationLoader theWebDescriptorConfigurationLoader = new WebDescriptorConfigurationLoader(aConfig);
final EventServiceConfigurationFactory theEventServiceConfigurationFactory = EventServiceConfigurationFactory.getInstance();
//theEventServiceConfigurationFactory.addConfigurationLoader(ConfigLevelFactory.DEFAULT, theWebDescriptorConfigurationLoader);
final EventRegistryFactory theEventRegistryFactory = EventRegistryFactory.getInstance();
EventRegistry theEventRegistry = theEventRegistryFactory.getEventRegistry();
//if (theWebDescriptorConfigurationLoader.isAvailable()) {
// theEventServiceConfigurationFactory.loadEventServiceConfiguration();
//}
return theEventRegistry;
}
/**
* Returns the client id.
*
* @return client id
*/
private String getClientId() {
return getClientId(false);
}
/**
* Returns the client id.
*
* @param isInitSession initializes the session (if not already initialized).
* @return client id
*/
protected String getClientId(boolean isInitSession) {
return RemoteServiceUtil.getThreadLocalRequest().getSession(isInitSession).getId();
}
5) Client side calling the EventServiceRemoteService service
EventServiceRemoteService.App.getInstance().initEventService(new
VoidAsyncCallback());
Original comment by leogem0...@gmail.com
on 23 Sep 2010 at 3:27
Hi Sven,
Did you get a chance to look into integration of GWTEventService with
GWTRPC-Spring for making GWTEventService to use Spring dependency injection?
Thanks
Original comment by leogem0...@gmail.com
on 28 Sep 2010 at 6:42
Hi,
I had no time to setup a GWT-RPC-Spring project to test if it works, but I have
removed GWT#getModuleBaseURL() and replaced it with the
RemoteServiceRelativePath annotation. It is already in the trunk version (since
today). The RemoteService interface is implemented via the EventService
interface.
Could you please try if it helps to setup the mapping for your Spring project?
Thanks in advance.
Regards,
Sven S.
Original comment by sven.strohschein@googlemail.com
on 28 Sep 2010 at 8:48
Hi Sven,
Does it help to provide our own implementation of the EventServiceImpl class
and provide the servlet mapping as /myservice.rpc which could understood by
gwtdispatcher for GWTRPC-Spring integration?
How from the client side we can invoke our own implementation of the
EventServiceImpl when someone adds the event on the server side with
GWTEventService?
Can we igonore the current deployment of providing EventServiceImpl mapping in
the web.xml and provide our own implementation?
Thanks.
Original comment by leogem0...@gmail.com
on 28 Sep 2010 at 9:19
Hi,
have you tried it with my last trunk commits which I have described above
(Comment 7)?
Your suggestion should also work. We could extract the EventService
creation/instantiation as a factory (that is definitely a good idea) and you
can overwrite the instantiation with your own implementation of EventService.
Your implementation should easily be able to work like in the following code
snippets. After that you can map and create/access it without any limitations.
public class EventServiceSpringImpl extends EventServiceImpl implements
EventServiceSpring {}
public interface EventServiceSpring extends EventService {}
public interface EventServiceSpringAsync { ... }
Regards
Sven S.
Original comment by sven.strohschein@googlemail.com
on 3 Oct 2010 at 8:03
Oh, I forget to say that the handling of your service would work automatically
in GWTEventService when your service interface is castable to the EventService
interface (should work with the code snippets above). You can use the
GWTEventService-API as common and don't have to access your service manually.
All you have to do is to provide your service interfaces (code snippet above)
and to implement your factory method like
public EventService createEventService() {
return GWT.create(EventServiceSpringImpl.class);
}.
I will start to implement the factory next week.
Regards,
Sven S.
Original comment by sven.strohschein@googlemail.com
on 3 Oct 2010 at 8:16
Hi Sven,
Thanks for your response.
Exactly i am looking for something similar where GWTEventService can be mapped
and creation/access as our own implementation. It would be really great if you
can provide the GWTEventService as a factory.
I would appreciate if you could also provide a sample code snippet as How to
map and create/ and how to instantiate our own implementation of
GWTEventService with an example as it can save a lot of time to test the same.
When does we have to call the factory method from the client side.
As i want to know once the GWTEventService is available as Factory then How to
invoke our own EventServiceImpl class on the server side. Do i need to call my
implementation of EventService from the client side similar like i am calling
my other services which will be a Http POST request to my service mapping URL
/apps/test/gwteventservice.rpc by using
@RemoteServiceRelativePath("/apps/test/gwteventservice.rpc")annotation mapping
on my implementation of the EventService interface.
For example as i have sent earlier the code snippet.
Client side calling the EventServiceRemoteService service
EventServiceRemoteService.App.getInstance().initGWTEventService(new
VoidAsyncCallback());
Thanks.
Original comment by leogem0...@gmail.com
on 5 Oct 2010 at 3:36
Hi,
I have now committed all changes to create individual mappings and
instantiations of EventService. All you have to do is to write a
EventServiceCreator (new interface). The EventServiceCreator is called from
GWTEventService to create an instance of EventService. Here you can write your
logic to create an instance of EventService with GWT-RPC-Spring. You can take a
look at DefaultEventServiceCreator to see working implementation.
To let GWTEventService use your written EventServiceCreator, you have to get
the RemoteEventService with
RemoteEventServiceFactory#getInstance()#getRemoteEventService(<your-EventService
Creator>);.
Here are some code-snippets for a possible implementation.
public class EventServiceSpringImpl extends EventServiceImpl implements
EventServiceSpring {}
public interface EventServiceSpring extends EventService {}
public interface EventServiceSpringAsync { /*...*/ }
public class EventServiceSpringCreator implements EventServiceCreator {
public EventServiceAsync createEventService() {
return MagicGWTRPCSpringCreator.get(EventServiceSpring.class); // ;-)
}
}
With this solution you can define EventService like every other GWT-RPC-Spring
service. Please let me know if you need support regarding this solution and
whether it fulfills your expectations.
Regards,
Sven S.
Original comment by sven.strohschein@googlemail.com
on 19 Oct 2010 at 10:06
Hi Sven,
Thank you for the update.
I will look into the DefaultEventServiceCreator implementation provided by you
and will test to create my own GWTRPC-Spring Event Service mapping and
instantiation.
Could you please provide a client side sample code as How to invoke this new
mapping instantiation?
Thanks.
Original comment by leogem0...@gmail.com
on 20 Oct 2010 at 3:57
Hi Sven,
Just wanted to add to my previous response.
If you can provide a client side Demo example code as when to invoke this new
EventServiceImpl instantiation. Similar like you provided a Demo application as
pushing the "Hello Message" from the server side.
I just need to know as on the client side when we have to invoke our new
EventServiceCreator.
RemoteEventServiceFactory#getInstance()#getRemoteEventService(<your-EventService
Creator>);.
Thanks.
Original comment by leogem0...@gmail.com
on 20 Oct 2010 at 4:03
Original issue reported on code.google.com by
leogem0...@gmail.com
on 19 Sep 2010 at 1:12