Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gameRoom.sendBroadcast(networkEvent) duplicates the message #12

Open
nikolaykuz opened this issue Sep 7, 2012 · 10 comments
Open

gameRoom.sendBroadcast(networkEvent) duplicates the message #12

nikolaykuz opened this issue Sep 7, 2012 · 10 comments
Assignees

Comments

@nikolaykuz
Copy link

At server side I create a new GameRoomSession, add existing session there

NettyMessageBuffer outBuf = new NettyMessageBuffer();
outBuf.writeBytes(outHeader.toByteArray());
NetworkEvent networkEvent = Events.networkEvent(outBuf);
gameRoom.sendBroadcast(networkEvent);

executed at server only once. gameRoom has only 1 session.

At client:
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
ChannelBuffer buffer = (ChannelBuffer) event.getSource();
System.out.println("NETWORK_MESSAGE received!");

appears twice and content is identical.
NETWORK_MESSAGE received!
MESSAGE_TYPE Fri Sep 07 17:29:14 KST 2012

Any idea?

@ghost ghost assigned menacher Sep 7, 2012
@menacher
Copy link
Owner

menacher commented Sep 7, 2012

Could you check for the event type at client side? This could be some other event say "START" sent by server, not the network event. Also instead of sending one network event send same network event say 5 times to see result. I do not see a check in your code to see if the event is actually "NETWORK_EVENT". Finally, any reason why you are not using the jetclient library at client side? That will provide you with a onDataIn just like server side.

@nikolaykuz
Copy link
Author

  1. If change it to 5 times then 10 messages are received at client side.

  2. playerSession.getTcpSender().sendMessage(networkEvent);
    //gameRoom.sendBroadcast(networkEvent);
    works okay (gameRoom has one session)

  3. else if (Events.NETWORK_MESSAGE == event.getType())
    {
    ChannelBuffer buffer = (ChannelBuffer) event.getSource();
    System.out.println("NETWORK_MESSAGE received!");

there is check for NETWORK_MESSAGE type

  1. I am following Zombie example there was DefenderHandler at client side

@menacher
Copy link
Owner

Looks like a bug, let me check it out.

@nikolaykuz
Copy link
Author

if i can put some debugging code for you, let me know

@menacher
Copy link
Owner

I did an initial test case and could not reproduce it. This is what I did

  1. Created a new game room in spring config (ZombieSpringConfig), named it Zombie_ROOM_2 and add it to the lookupservice hashmap with ref key as Zombie_ROOM_1_REF_KEY_2.
  2. Modified ZombieJetclient to create only one session. I also commented out the scheduled tasks so that client does not send any data to server.
  3. Modified GameServer to load this new room instead of the old one. GameRoom room = (GameRoom) ctx.getBean("room2");
  4. The world monitor task which is already coded will wake up every 5 seconds and broadcast the number of people alive to the game room, I left this code untouched.
    Result: For every broadcast I only got one message at client side. -> Remaining Human Population: 2000000000.

Here is the code for the new room I added.

public class BroadcastZombieRoom extends ZombieRoom {
    public BroadcastZombieRoom(GameRoomSessionBuilder sessionBuilder){
        super(sessionBuilder);
    }
    
    @Override
    public void onLogin(final PlayerSession playerSession) {
        playerSession.addHandler(new DefaultSessionEventHandler(playerSession) {
            
            
        });
    }
    
}

Did you by any chance add 2 session event handlers to the playersession or gameroom?

@nikolaykuz
Copy link
Author

Did you by any chance add 2 session event handlers to the playersession or gameroom?
This is very probable and maybe related to the topic 8 discussed before.
#8

How I add print number of added handlers by mine? I have tried but it produce null pointer exception.

Before adding another handler to the PlayerSession request I do like this
request.getEventDispatcher().removeHandlersForEvent(Events.CONNECT);
request.getEventDispatcher().removeHandlersForEvent(Events.SESSION_MESSAGE);
but it produces same result

@menacher
Copy link
Owner

The default handler which handles any event is added using Events.ANY. So you could also try to do request.getEventDispatcher().removeHandlersForEvent(Events.ANY);
If you want to see all handlers associated with an event dispatcher it will be better to downcast EventDispatcher to the JetlangEventDispatcher class. Then you can call getListenersByEventType() method which will return the underlying map used to store all event handler, getting count etc is then quite easy.
I can add such methods to the interface, but I feel it is "leaky abstraction" hence not adding. If you feel that is not the case let me know.

@nikolaykuz
Copy link
Author

request.getEventDispatcher().removeHandlersForEvent(Events.ANY);
You are right. Now only one message is received at every client.

Overall as beginner of netty and your java server I can say that handlers and eventType mapping is confusing. As you have said before there are internal netty handlers, I think those should be accessed directly. But for handlers programmed and added by programmer there should be more convenient way to manage it.

@menacher
Copy link
Owner

Thanks for the feedback! Let me see what can be done, either through document or code wise to have neater control on event handlers.

@menacher
Copy link
Owner

I have added a "clear" method, which you can use to remove all event handlers associated with a dispatcher. Binaries not updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants