Multiple annotated services for client and server

45 views
Skip to first unread message

Luca Merolla

unread,
Feb 4, 2012, 11:59:44 AM2/4/12
to cometd-users
Hello everyone,

I'm playing with CometD annotation style of the Services and I have a
couple of question about it:

1) How can I have multiple *Service.java classes in the server side to
handle different channels?
The problem here seems that I need to pass this

<init-param>
<param-name>services</param-name>
<param-value>org.test.service.GameService</param-value>
</init-param>

to the AnnotationCometdServlet in the web.xml file, and i don't know
how to pass multiple files.

2) I want to create some Client-Side Annotated Services too. Both for
the Local and Remote Session.
What is the way to make these classes instantiated? On the Local
(Server side) one I probably need to fix the problem #1, but about the
Remote is it possible to use the Annotation in a Remote J2SE client?

Thanks in advance,
LM

Simone Bordet

unread,
Feb 4, 2012, 3:35:55 PM2/4/12
to cometd...@googlegroups.com
Hi,

On Sat, Feb 4, 2012 at 17:59, Luca Merolla <luca.m...@gmail.com> wrote:
> Hello everyone,
>
> I'm playing with CometD annotation style of the Services and I have a
> couple of question about it:
>
> 1) How can I have multiple *Service.java classes in the server side to
> handle different channels?
> The problem here seems that I need to pass this
>
> <init-param>
>        <param-name>services</param-name>
>        <param-value>org.test.service.GameService</param-value>
> </init-param>
>
> to the AnnotationCometdServlet in the web.xml file, and i don't know
> how to pass multiple files.

See http://docs.cometd.org/reference/#java_server_configuration.

You can pass a comma-separated list of classes.

> 2) I want to create some Client-Side Annotated Services too.

Ok.

> Both for the Local and Remote Session.

Mmm, this does not sound right.
You cannot create client-side services for local sessions. Local
sessions live on the server, not on the client.
See http://docs.cometd.org/reference/#concepts

> What is the way to make these classes instantiated? On the Local
> (Server side) one I probably need to fix the problem #1, but about the
> Remote is it possible to use the Annotation in a Remote J2SE client?

See http://docs.cometd.org/reference/#java_server_services_annotated_client-side,
in particular section "Annotation Processing".

J2SE clients instantiate services and use a ClientAnnotationProcessor
to resolve dependencies and process CometD annotations.

Simon
--
http://cometd.org
http://intalio.com
http://bordet.blogspot.com
----
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz

Luca Merolla

unread,
Mar 15, 2012, 5:44:23 PM3/15/12
to cometd...@googlegroups.com
Hi Simone,

sorry for late reply.

On Saturday, 4 February 2012 21:35:55 UTC+1, Simone Bordet wrote:
Hi,

On Sat, Feb 4, 2012 at 17:59, Luca Merolla <luca.me...m> wrote:
> Hello everyone,
>
> I'm playing with CometD annotation style of the Services and I have a
> couple of question about it:
>
> 1) How can I have multiple *Service.java classes in the server side to
> handle different channels?
> The problem here seems that I need to pass this
>
> <init-param>
>        <param-name>services</param-name>
>        <param-value>org.test.service.GameService</param-value>
> </init-param>
>
> to the AnnotationCometdServlet in the web.xml file, and i don't know
> how to pass multiple files.

See http://docs.cometd.org/reference/#java_server_configuration.

You can pass a comma-separated list of classes.

Ok, comma separated list of classes worked.
 

> 2) I want to create some Client-Side Annotated Services too.

Ok.

> Both for the Local and Remote Session.

Mmm, this does not sound right.
You cannot create client-side services for local sessions. Local
sessions live on the server, not on the client.
See http://docs.cometd.org/reference/#concepts

Well, what I want to create is to a have a typical pub-sub architecture with 2 kind of clients:
- 1 Java Client as a Local session in annotated service style which will be allowed to publish
- N Java Clients as a Remote session in annotated service style which will be allowed only to subscribe
 

> What is the way to make these classes instantiated? On the Local
> (Server side) one I probably need to fix the problem #1, but about the
> Remote is it possible to use the Annotation in a Remote J2SE client?

See http://docs.cometd.org/reference/#java_server_services_annotated_client-side,
in particular section "Annotation Processing".

J2SE clients instantiate services and use a ClientAnnotationProcessor
to resolve dependencies and process CometD annotations.

Simon
--
http://cometd.org
http://intalio.com
http://bordet.blogspot.com
----
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


I'm having some problem to understand how the annotated clients works. Here is a little example of an application (Remote J2SE client) which establish a connection and try to interact with a channel.

public class MainCometD {

private static final String CHANNEL = "/testchannel";
private final static MessageListener fooListener = new FooListener();

public static void main(String[] args) throws Exception {
HttpClient httpClient = new HttpClient();
httpClient.setMaxConnectionsPerAddress(2);
httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
httpClient.setRealmResolver(new SimpleRealmResolver(new Realm() {
public String getId() {
return "galaxy";
}

public String getPrincipal() {
return "prova";
}

public String getCredentials() {
return "prova";
}
}));

httpClient.start();

Map<String, Object> options = new HashMap<String, Object>();
ClientTransport websocket = WebSocketTransport.create(options,
new WebSocketClientFactory());
ClientTransport transport = LongPollingTransport.create(options,
httpClient);

BayeuxClient client = new BayeuxClient(

client.handshake();
boolean handshaken = client.waitFor(1000, BayeuxClient.State.CONNECTED);
if (handshaken) {
System.out.println("subscribe test");
client.getChannel(CHANNEL).subscribe(fooListener);
}

System.out.println("publish test");
client.getChannel(CHANNEL).publish(new String("test"));
}

private static class FooListener implements MessageListener {
public void deliver(Client from, Client to, Message message) {
if (CHANNEL.equals(message.getChannel())) {
// Here we received a message on the channel
System.out.println("buu");
}
}
@Override
public void onMessage(ClientSessionChannel channel, Message message) {
System.out.println("got it");
}
}
}

And I can see the logs on the server which is working. However, I have tried to write the same class with annotation and it is not working.
Here it is the code:

@Service
public class CometDService {

@Session
private ClientSession bayeuxClient;

@PostConstruct
private void init() {
System.out.println("Initialized");
}

@PreDestroy
private void destroy() {
System.out.println("Destroy");
}

@Listener(Channel.META_CONNECT)
public void metaConnect(Message connect) {
System.out.println("handle connect");
}

@Listener("/meta/*")
public void handleMetaMessage(Message connect) {
System.out.println("META:" + connect.values().toString());
}

@Subscription("/testchannel")
public void subscribeLobby(Message message) {
System.out.println("handle message");
}
}

And the main method is like this:

public static void main(String[] args) throws Exception {
HttpClient httpClient = new HttpClient();

httpClient.setMaxConnectionsPerAddress(2);

httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
httpClient.setRealmResolver(new SimpleRealmResolver(new Realm() {
public String getId() {
return "galaxy";
}

public String getPrincipal() {
return "prova";
}

public String getCredentials() {
return "prova";
}
}));

httpClient.start();

Map<String, Object> options = new HashMap<String, Object>();
ClientTransport transport = LongPollingTransport.create(options,
httpClient);

BayeuxClient client = new BayeuxClient(COMETD_URL, transport);

ClientAnnotationProcessor processor = new ClientAnnotationProcessor(
client);

CometDService service = new CometDService();

processor.process(service);

client.getChannel(Channel.META_HANDSHAKE).addListener(
new ClientSessionChannel.MessageListener() {
public void onMessage(ClientSessionChannel channel,
Message message) {
if (message.isSuccessful()) {
System.out.println("Here handshake is successful");
}
}
});

System.out.println("handshake...");
client.handshake();

service.subscribeLobby(null);

client.getChannel(CHANNEL).publish(new String("oooo"));

System.out.println("disconnect...");
client.disconnect();
}

The output on the client side is:
Initialized
handshake...
handle message
disconnect...

But on the server side I see no activity on the logs, so I guess nothing happens.

Any idea what am I missing in the annotated version?

Thanks in advance,
LM 

Simone Bordet

unread,
Mar 16, 2012, 7:42:27 AM3/16/12
to cometd...@googlegroups.com
Hi,

On Thu, Mar 15, 2012 at 22:44, Luca Merolla <luca.m...@gmail.com> wrote:
> System.out.println("handshake...");
> client.handshake();
>
> service.subscribeLobby(null);

Subscriptions should be done from /meta/handshake listeners (but
that's not the problem here).

> client.getChannel(CHANNEL).publish(new String("oooo"));
>
> System.out.println("disconnect...");
> client.disconnect();

The problem here is that you publish and immediately after you
disconnect, so the BayeuxClient has no chance to actually send the
message.
Remeber that publish() is asynchronous, so the fact that you publish()
does not mean that when the method returns, the message is actually
published.
It is only queued for publishing, and will be published by a different
thread, so if you disconnect() meanwhile, there is a chance that the
message never hits the network.

Reply all
Reply to author
Forward
0 new messages