Unable to cast up to one connection using Atmosphere

I am using Atmosphere runtime 0.6 Snapshot. Tomcat 7 correctly logs that I am using the Http11 Nio connector and there is no warning that BlockingIO will be used.

I am trying to send messages to three types of channels.

  • Global Broadcaster - broadcasts to all suspended resources. (Everything)
  • Broadcast to a specific resource (say, partner)
  • Broadcast to the current resource (Self)

When the login action occurs, what do I need to save in the session to achieve this kind of broadcast?

Some details of my code are as follows:

  • My Handler implements AtmosphereHandler
  • In the constructor, I create an instance of globalBroadcaster as follows:

    globalBroadcaster = new DefaultBroadcaster();

  • When logging in,

    resource.getAtmosphereConfig().getServletContext().setAttribute(name, selfBroadcaster); where name is the username from the query parameter, and selfBroadcaster is the new instance of DefaultBroadcaster.

  • Here is the code for sendMessageToPartner,

private synchronized void sendMessageToPartner(Broadcaster selfBroadcaster, AtmosphereResource<HttpServletRequest, HttpServletResponse> resource,String name, String message) {
// this gives the partner name
String partner= (String) resource.getAtmosphereConfig().getServletContext().getAttribute(name + PARTNER_NAME_TOKEN);
// get partner broadcaster
Broadcaster outsiderBroadcaster = (Broadcaster) resource
.getAtmosphereConfig().getServletContext()
.getAttribute(partner);
if (outsiderBroadcaster == null) {
sendMessage(selfBroadcaster, "Invalid user " + partner);
return;
}
// broadcast to partner
outsiderBroadcaster.broadcast(" **" + message);

I hope I have provided all the necessary information. If necessary, I can provide additional information.

The problem is that the global message is being sent. When a message is sent to a partner, sometimes it is blocked, the message is not accepted at all by the client. This happens sequentially after 3-4 messages.

Is there a problem with threads? What am I doing wrong?

I hope someone helps me with this.

+4
source share
1 answer

Well, I figured out how this can be achieved using the Atmosphere environment. Firstly, I upgraded SNAPSHOT to 0.7, but I think the same logic will work with 0.6.

So, to create a broadcaster for one user:

In GET request

  // Use one Broadcaster per AtmosphereResource try { atmoResource.setBroadcaster(BroadcasterFactory.getDefault().get()); } catch (Throwable t) { throw new IOException(t); } // Create a Broadcaster based on this session id. selfBroadcaster = atmoResource.getBroadcaster(); // add to the selfBroadcaster selfBroadcaster.addAtmosphereResource(atmoResource); atmoResource.suspend(); 

When the login action is called,

 //Get this broadcaster from session and add it to BroadcasterFactory. Broadcaster selfBroadcaster = (Broadcaster) session.getAttribute(sessionId); BroadcasterFactory.getDefault().add(selfBroadcaster, name); Now the global broadcaster. The logic here is, you create a broadcaster from the first resource and then add each resource as they log in. Broadcaster globalBroadcaster; globalBroadcaster = BroadcasterFactory.getDefault().lookup(DefaultBroadcaster.class, GLOBAL_TOKEN, false); if (globalBroadcaster == null) { globalBroadcaster = selfBroadcaster; } else { BroadcasterFactory.getDefault().remove( globalBroadcaster, GLOBAL_TOKEN); AtmosphereResource r = (AtmosphereResource) session .getAttribute("atmoResource"); globalBroadcaster.addAtmosphereResource(r); } BroadcasterFactory.getDefault().add(globalBroadcaster, GLOBAL_TOKEN); 

Finally, you can stream to one connection or globally to all connections as follows:

 // Single Connection/Session Broadcaster singleBroadcaster= BroadcasterFactory.getDefault().lookup( DefaultBroadcaster.class, name); singleBroadcaster.broadcast("Only for you"); // Global Broadcaster globalBroadcaster = BroadcasterFactory.getDefault().lookup(DefaultBroadcaster.class,GLOBAL_TOKEN, false); globalBroadcaster.broadcast("Global message to all"); 

To send a message to a partner, simply find the transmitter for the partner and do the same as above for one connection.

Hope this helps someone who is trying to achieve the same. There may be better ways to do this. I think I will have to use this approach until someone offers a better solution.

+6
source

Source: https://habr.com/ru/post/1333540/


All Articles