blazeds push message to all clients - push

I have a bootstrapper that handles sessionDestroyed, sessionCreated, ClientCreated, ClientDestroyed, MessageClientDestroyed, MessageClientCreated events.
My aim is to send a disconnect message to all clients or all subscribed destinations.
So i need a push mechanism inside the service. I have tried to get messageService and MessageBroker but i got exception.
I have tried messageBroker.routeMessageToService(msg,null);
and messageService.pushMessageToClients(msg,true); both is unsuccessful because i could not get messageService and messageBroker.
How can i get MessageBroker or MessageService in service clientDestroyed event.

String clientId = UUIDUtils.createUUID();
MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
JOptionPane.showMessageDialog(null, msgBroker);
AsyncMessage msg = new AsyncMessage();
msg.setDestination(dest.destinationList.get(i));
msg.setClientId(clientId);
msg.setMessageId(UUIDUtils.createUUID());
msg.setHeader("disconnected",0);
msg.setBody(client.getId());
msgBroker.routeMessageToService(msg, null);
this is my working code hope it helps to somebody.

Related

VertX multiple Worker Instances processing same message

I have a simple Vertx worker vertical with 4 instances for scaling as defined below. When multiple requests come, I was expecting that each worker instances will process individual request concurrently (4 requests at a time).
Vertx vertx = Vertx.vertx();
DeploymentOptions deploymentOptions = new DeploymentOptions()
.setWorker(true)
.setInstances(4);
vertx.deployVerticle(MailVertical.class.getName(), deploymentOptions);
some code to plumb incoming mail message to publishing method.
// This is executed once per incoming message
this.vertx.eventBus().publish("anAddress", messageString);
Vertical Consumer code to log incoming mail message
public class MailVertical extends AbstractVerticle {
private static final Logger logger = LoggerFactory.getLogger(MailVertical.class);
#Override
public void start(Promise<Void> future) {
logger.info("Welcome to Vertx: MailVertical.");
vertx.eventBus().consumer("anAddress", message -> {
String msg = message.body().toString();
for(int i=0;i<50;i++){
logger.info(msg);
}
try {
updateStatusInDB(msg);
} catch (SQLException e) {
e.printStackTrace();
}
});
}
However, I am observing that each request is processed by all 4 instances somewhat concurrently i.e. if 1 request come in, total 4 processing events occur = 200 log messages.
...
...
[vert.x-worker-thread-7] INFO com.vertx.mailproject.MailVertical - {"msg":"sample message for app-2123x mail notification","appname":"app-1","msgid":"64fd684b-45a8-48c7-9526-4606d6adc311"}
[vert.x-worker-thread-6] INFO com.vertx.mailproject.MailVertical - Msg: sample message for app-2123x mail notification updated to SENT in DB.
[vert.x-worker-thread-7] INFO com.vertx.mailproject.MailVertical - Msg: sample message for app-2123x mail notification updated to SENT in DB.
[vert.x-worker-thread-4] INFO com.vertx.mailproject.MailVertical - Msg: sample message for app-2123x mail notification updated to SENT in DB.
[vert.x-worker-thread-5] INFO com.vertx.mailproject.MailVertical - Msg: sample message for app-2123x mail notification updated to SENT in DB.
Any suggestion what am I doing wrong here? Or is this expected.
vertx-core = 4.2.3
Yes this is indeed a correct behavior. You are starting 4 worker threads and then registering all of them against the same address "anAddress".
Publish Subscribe pattern is being used here. With the method publish() all the registered consumer/handler will receive this event. see Publish / subscribe messaging
If you want only one of worker to receive this event, then use Point-to-point and Request-Response messaging. Basically replace publish() with send()
But looking at your code, I would suggest instead of using worker verticle use executeBlocking in standard verticle

Akka remoting: Remote subscribed event listener custom serialising a Watch message

I have the following remote actor set up.
actorSystem.actorSelection(remoteConfig.getString("/myEventListener")).resolveOne().map{ar =>
actorSystem.eventStream.subscribe(ar, classOf[MyEvent])
}
I also have my own custom serialization. The issue is that this gets sent a Watch message which has the following signature:
private[akka] final case class Watch(watchee: InternalActorRef, watcher: InternalActorRef) extends SystemMessage
Which is not so straight forward to serialize. Any suggestions on how to proceed on this one? Sending a remote message with references to InternalActorRef seems a bit of an odd one.
And to note I use other remote actors directly (not as event listeners), these dont get sent the Watch message:
val emailService = actorSystem.actorSelection(remoteConfig.getString("/emailCommandHandler"))

How to access the Session Object Inside event bus in Vertx?

My Request handler
router.route("/clientController/*").handler(sockJSHandler);
and my event bus is
eb.consumer("chat.to.server",message->{
System.out.println("Getting Request in Client Controller Event Bus");
JsonObject data = (JsonObject) message.body();
String classifier = data.getString("classifier");
if(classifier.equals("loginUri")) {
System.out.println("Request for Login URI");
vertx.executeBlocking(future -> {
future.complete(OAuth.getOAuthParam());
}, res -> {
eb.publish("chat.to.client", res.result());
});
}
is it possible to access the session object inside event bus as we do the normal routing handler as routingContext.getSession()
Short answer, you can't. Routing context session is not related to the eventbus. The eventbus can be deployed without having a HTTP server while routing context is a very web specific thing.
If you need to have state on your eventbus then I'd say you need to pass the session id in your message headers, and only if the session is clustered then you might be able to retrieve it from the cluster store by id. By doing so you might also introduce inconsistency so i'd advice not to do it.
Alternative just put all your required session data in your message payload.

How to keep chat history locally on android?

I am using openfire and aSmack for my chat application.
I am able to send and receive messages using aSmack library.
Can anyone tell me how to keep these messages in local(android) storage, so that whenever user opens application next time, he can see his previous chat history ? Is there any api provided by aSmack/Smack ?
Simply register a packet listener and interceptor and log the messages to the backing store of your choice.
use packetListener as:
PacketFilter gc_filter = new MessageTypeFilter(Message.Type.groupchat);
XMPPconnection.addPacketListener(new PacketListener()
{
public void processPacket(Packet packet)
{
final Message message = (Message) packet;
String body = message.getBody();
String from_jid = message.getFrom();
// save it in data base
}
)};

Smack service discovery without login gives bad-request(400)

I am trying to discover items that a pubsub service provides. When I log into the target server, I can get the response successfully. But when I connect bu do not login, it gives a bad request error.
This is the code:
ConnectionConfiguration config = new ConnectionConfiguration(serverAddress, 5222);
config.setServiceName(serviceName);
connection = new XMPPConnection(config);
connection.connect();
connection.login(userName, password); //!!!when I remove this line, bad request error is received
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection);
DiscoverItems items;
try {
items = discoManager.discoverItems("pubsubservice." + serverName);
} catch (XMPPException e) {
e.printStackTrace();
}
Is there a way to discover items when the user is not logged in, but the connection is established?
No, you must authenticate to send stanzas to any JID in XMPP (otherwise they would not be able to reply to you, since they wouldn't know your address).
Perhaps one option for you is anonymous authentication. Most servers support it, and it creates a temporary account on the server for you, with a temporary JID. You don't need a password, and login time is quick.
#MattJ is correct and you could try using anon login. That will get you part way there.
Your current request will only get you the nodes though, after which you will have to get the items for each node. It would be simpler to use PubsubManager to get the information you want since it provides convenience methods for accessing/using all things pubsub.
Try the documentation here, the getAffiliations() method is what you are looking for.
BTW, I believe the typical default service name for pubsub is pubsub not pubsubservice. At least this is the case for Openfire.