Disconnect in Quickfixj - java

I am using quickfixj where I have acceptor from which I am sending fix message using Logout() method "8=FIX.4.29=8235=534=38749=TEST152=20130409-08:01:47.86256=TEST2-1136558=User Is Blocked10=231" to initiator , but I can see heart beat sent from Acceptor itself how do we over come this ? I am using the below code
Logout oLogout = new Logout();
quickfix.field.Text aText = new quickfix.field.Text("User Is Blocked");
oLogout.set(aText);
Session.sendToTarget(oLogout, "TEST2-11365, "TEST1");

You should not manually send a Logout like this. Logout is an admin message; you should trust the engine to send/receive all admin message types.
What is happening is that you are sending this message outside of the engine's control logic. The engine is treating it as any other outgoing application-level message, and not initiating the engine's internal shutdown logic.
If you call Acceptor.stop(), then engine will initiate its shutdown logic and send the Logout for you.

Related

Basic authenticator with Netty

Actually for my server game I'm not using Netty. I've created a socket multithreaded system for send packet object who is serialized into and deserialized from (Int and Out)StreamBuffer.
I've discovered Netty and I think it's better to use it for my network system.
I've actually created a Client and Server handler (both extends ChannelInboundHandlerAdapter) to serialized and deserialized my packet from the ByteBuf, it's work FINE :) !
Now I want migrate my authentication system.
Actually, I've two Handler, the LoginHandler which can receive and process only the Login Packet (defined by an id when I send a buffer packet), and the ServerHandler which can receive and process all others packets.
Actual algorithme
Client side :
User launch a client a new window ask him to enter his username and password When he click on "Login", the client connect to the server, and after send a LoginPacket.
If a AuthServerPacket is sent by the server with the auth flag to true, he continue and open all others features.
If a AuthServerPacket is sent by the server with the auth flag to false, it display a popup with the reason, and re-open the window login.
Server side :
When a user is connecting to the server it's the LoginHandler which is attached to the client.
In this LoginHandler, only LoginPacket is processed, so, when it receive a LoginPacket it check the informations in a database, if these are correct, the client are added to the ServerHandler and deleted from the LoginHandler, and now he can receive and send all others packets.
ServerHandler send a AuthServerPacket with auth flag to true.
My question is, what is the best way to re-create this system with Netty ?
I don't know if I can add the login handler in the pipeline which it will be not check it if a channel is authentified. I don't know how or if the process is stopped if one of the handler reject the channel.
Someone can help me to understand what is the best way to do what I want with Netty ?
Thanks you in advance for your answers.
Programmatically, beaucoralk.
we talked on IRC #netty today :)
My suggestion is:
In your Pipeline Initializer, always add the LoginHandler
Once Login is successful, then the LoginHandler should:
ctx.pipeline.addAfter(this, "gameHandler", new GameLogicHandler());
ctx.pipeline.remove(this);
So basically your LoginHandler removes itself, after a successful authentication. Important: add the new Handler before removing the old Handler. :)
best regards
I've solved my problem with this :
In my Pipeline Initialize always add the LoginHandler (don't add my ServerHandler)
Once Login is successful, then the LoginHandler do :
ctx.pipeline.addLast(new GameLogicServerHandler());
ctx.pipeline.remove(this);
In fact I have not succeeded to use the addAfter like said Franz Bettag, no method was appropriate.
But thanks you to Bettag who help me to understand many things on #netty IRC.

Spring Java WebSockets Messaging between users

This is question about websockets and architecture of messaging between users. What i've done:
Client side:
Send message to server with parameter - conversation uuid. And also i subscribed to topic where new messages must be appeared.
Server side:
When i receive message with conversation uuid, i launch scheduler which sends new messages for conversation to topic.
But there alot of conversation could be, so i my controller class i got field of class "conversationSchedulers" - it is HashMap where key is a username and value is current scheduler which sends new messages for conversation. When user wants to recieve new messages for other conversation, he click on conversation in web application and next code works:
Cliend side:
Send messages with new conversation uuid.
Server side:
Gain previous running scheduler - if it is - cancel it, and run new scheduler with new conversation uuid.
And everything is works... when there are ONE tab with messages. When user open two or more tabs - all architecture gone to the hell. Because i accept only one scheduler for messaging... only one conversation could be opened.
In that moment i got an idea - accept many schedulers to messaging with more than one user at the same time, but i did not do this implementation because on messaging page i have got a button to write a NEW message, when user want to write new message all new messages from other users must stop to sends to client, but i can not stop them because user got a two tabs. Stop all schedulers that means stop messaging on all tabs. And this is a problem. May be i choose wrong architecture? Or websockets it is a bad idea for such task?

How to design push notifications using Atmosphere

I want to use atmosphere to develop a notification System.
I am very new to Atmosphere so apologies if I am wrong somewhere.
What i understood is when a Actor publishes something I save the notification action to the database.
What i don't understand how the receiver will receive those notifications in realtime.
The sender i know will do something like following
event.getBroadcaster().broadcast(
objectMapper.writeValueAsString("Some Message"));
Now i am not able to figure out how the receiver can receive this message.
For example . I want to add a User Object as Friend. So when User1 adds User2 User1 broadcast but than how i push the notification to User2. I have difficulty in understanding this.
Technically i want something similar like facebook or gmail notification where on user activity other users get notifications.
Basically what you need is to implement Publish-subscribe on top of Atmosphere.
Atmosphere consists of two parts: client-side (javascript-based) and server-side(java-based).
First of all you need to configure server-side: Installing Atmosphere
Namely servlet or filter, it is required so that it could add AtmosphereResource to the HttpServletRequest.
AtmosphereResource represents a single client connection on the server-side.
Broadcaster is actually a container for these resources, so that you don't need to handle lookup/iteration/concurrency when you need to send to multiple connections. (Note that multiple connections can be produced by single client).
On the server-side you need to provide clients an endpoint to subscribe for notifications.
For example, if you are using Spring-MVC, it could go like this (omitting validations/authentications, etc.):
#RequestMapping(value = "/user-notifications/{userId}")
#ResponseStatus(HttpStatus.OK)
#ResponseBody
public void watch(#PathVariable("userId") String userId,
HttpServletRequest request) throws Exception {
//Atmosphere framework puts filter/servlet that adds ATMOSPHERE_RESOURCE to all requests
AtmosphereResource resource = (AtmosphereResource)request.getAttribute(ApplicationConfig.ATMOSPHERE_RESOURCE);
//suspending resource to keep connection
resource.suspend();
//find broadcaster, second parameter says to create broadcaster if it doesn't exist
Broadcaster broadcaster = BroadcasterFactory.getDefault().lookup(userId,true);
//saving resource for notifications
broadcaster.addAtmosphereResource(resource);
}
When something happens you can notify clients like this:
public void notify(User user, Event event){
Broadcaster b = BroadcasterFactory.getDefault().lookup(user.getId());
if (b!=null){
b.broadcast(event);
}
}
On the client side you need to send a subscribe request and listen for subsequent events, like this:
var request = new atmosphere.AtmosphereRequest();
request.url = '/user-notifications/'+userId;
request.transport = 'websocket';
request.fallbackTransport = 'streaming';
request.contentType = 'application/json';
request.reconnectInterval = 60000;
request.maxReconnectOnClose = 1000;
request.onMessage = function(response){
console.log(response);
alert('something happend<br>'+response);
};
that.watcherSocket = atmosphere.subscribe(request);
So, to sum it up:
Client sends request "I want to receive this kind of notifications".
Server receives request, suspends and saves connection somewhere (either in your code or in Broadcaster).
When something happens server looks for suspended connection and sends notification in it.
Client receives notification and callback is invoked.
Profit!!!
This wiki has explanations for some concepts behind Atmosphere and links to other documentation.

How to make a JMS Synchronous request

I have an webapp that is expected to fetch and display data from an External App which is accessible only via messaging (JMS).
So, if a user submits a request on a browser, the same HTTP request thread will have to interact with the Messaging system (MQ Series) such that the same request thread can display the data received from the Messaging System.
Is there a pattern I can make use of here? I saw some vague references on the net that use "Correlation ID" in this way:
Msg m = new TextMsg("findDataXYZ");
String cr_id = m.setCorrelationID(id);
sendQueue.send(m).
// now start listening to the Queue for a msg that bears that specific cr_id
Response r = receiverQueue.receive(cr_id);
Is there something better out there? The other patterns I found expect the response to be received asynchronously.. which is not an option for me, since I have to send the response back on the same HTTP request.
The request/reply messaging pattern is useful for your requirement. You typically use a CorrelationId to relate request & reply messages.
While sending request message you set JMSReplyTo destination on the message. Typically a temporary queue is used as JMSReplyTo destination. When creating a consumer to receive response use a selector with JMSCorrelationId, something like
cons = session.createConsumer(tempDestination,"JMSCorrelationId="+requestMsg.JMSMessageId);
At the other end, the application that is processing the request message must use the JMSReplyTo destination to send response. It must also use the MessageId of the request message and set it as CorrelationId of the response message.
First, open the response queue. Then pass that object to the set reply-to method on the message. That way the service responding to your request knows where to send the reply. Typically the service will copy the message ID to the correlation ID field so when you send the message, take the message ID you get back and use that to listen on the reply queue. Of course if you use a dynamic reply-to queue even that isn't neessary - just listen for the next message on the queue.
There's sample code that shows all of this. If you installed to the default location, the sample code lives at "C:\Program Files (x86)\IBM\WebSphere MQ\tools\jms\samples\simple\SimpleRequestor.java" on a Windows box or /var/mqm/toolsjms/samples/simple/SimpleRequestor.java on a *nix box.
And on the off chance you are wondering "install what, exactly?" the WMQ client install is downloadable for free as SupportPac MQC71.

Sending messages to specific Smack domains after initial broadcast message

I'm creating an instant messaging client using Smack 3.1.0 and Java. The problem I'm running in to has to do with sending messages to the user on a specific domain.
For example, I have two users, 1#gmail.com and 2#gmail.com. 1#gmail.com logs in to XMPP through my IM client. 2#gmail.com logs in to GChat through gmail.com AND a second time through pidgin. So now I have one instance of 1#gmail.com and 2 instances of 2#gmail.com.
The way gmail works, if 1#gmail.com sends a message to 2#gmail.com, the gmail and the pidgin client both get the initial message. But then if the gmail instance responds to the message, every message from then on only goes between 1#gmail.com and the gmail instance of 2#gmail.com.
I would like to mimic this behavior with my IM client. I would think the way to do it would be to set up a Chat, send the initial IM to all instances of the recipient. Then I'd set up a MessageListener to listen for a response. When I get the response, I'd have to create a new chat, specifying the 2#gmail.com/resource. But then I'd have to write the MessageListener twice. Any ideas? Here's some sample code that I'm using (the method AddText() simply appends the message to my conversation pane):
recipient = buddy;
setTitle("Instant Message - "+recipient);
chat = com.andreaslekas.pim.PIM.connection.getChatManager().createChat(recipient.getUser(), new MessageListener() {
public void processMessage(Chat chat, Message msg) {
//if(chat.getParticipant().indexOf('/')!=-1)
addText(msg.getBody(), chat.getParticipant(), true);
}
});
UPDATE
I wanted to supplement the answer below with actual code that I used to make this work:
chat = com.andreaslekas.pim.PIM.connection.getChatManager().createChat(recipient.getUser(), new MessageListener() {
public void processMessage(Chat new_chat, Message msg) {
if(msg.getFrom().replaceFirst("/.*", "").equals(recipient.getUser()))
{
if(buddy_resource==null || !msg.getFrom().replaceFirst(".*?/", "").equals(buddy_resource.getResource()))
{
buddy_resource = recipient.getResource(msg.getFrom().replaceFirst(".*?/", ""));
chat = null;
chat = com.andreaslekas.pim.PIM.connection.getChatManager().createChat(recipient.getUser()+"/"+buddy_resource.getResource(), new MessageListener(){
public void processMessage(Chat new_chat2, Message msg) {
addText(msg.getBody(), new_chat2.getParticipant(), true);
}
});
}
addText(msg.getBody(), chat.getParticipant(), true);
}
}
});
To summarize, I send the first message to all resources of the recipient's address and wait for a response. When I get the response, I replace the current Chat object with a new one that specifies the individual resource that responded to the initial message. The code is a little messy with two different MessageListener objects that could probably be combined into a new class. But it works.
So far I understood Message Carbon (XEP - 0280) will solve your problem.
If you enable carbon it will distribute messages to all logged resources of a user. In your case if 1#gmail.com send message to 2#gmail.com it will be distributed to all logged resources of 2#gmail.com.
Here's a code sample using smack,
CarbonManager cm = CarbonManager.getInstanceFor(connection);
cm.enableCarbons();
cm.sendCarbonsEnabled();
First make sure that your server is supported Message Carbon.
Then send message as usual.
In your MessageListener why not always respond to the sender? I think you get it by calling something like msg.getSender() or getFrom() (I'm on mobile right now, cannot check)

Categories