Page 1 of 1

Sending UDP NullPointerException [v1.0.5]

Posted: 07 Dec 2012, 22:41
by janheuninck
Hi,

When I launch multiple clients at the same time (> 20), some of them fail to send messages over UDP. This is the null pointer exception thrown by the SmartFox framework:

Code: Select all

java.lang.NullPointerException
   at sfs2x.client.core.sockets.UDPSocketLayer.write(UDPSocketLayer.java:143)
   at sfs2x.client.bitswarm.UDPManager.send(UDPManager.java:104)
   at sfs2x.client.core.SFSIOHandler.writeUDP(SFSIOHandler.java:409)
   at sfs2x.client.core.SFSIOHandler.onDataWrite(SFSIOHandler.java:392)
   at sfs2x.client.core.SFSProtocolCodec.onPacketWrite(SFSProtocolCodec.java:79)
   at sfs2x.client.bitswarm.BitSwarmClient.send(BitSwarmClient.java:223)
   at sfs2x.client.SmartFox.send(SmartFox.java:893)


Cheers
Jan

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 11 Dec 2012, 16:53
by janheuninck
Anyone else having the same problem?

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 12 Dec 2012, 09:52
by Lapo
Are you leaving a bit of pause between each client generation?
Maybe it's a timing issue

Thanks

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 13 Dec 2012, 19:32
by janheuninck
Same issue occurs when I launch the clients one by one. When +- 20 clients are sending messages, some of them start failing to send UDP messages...

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 14 Dec 2012, 08:53
by Lapo
I am not able to reproduce this problem. I am running a test with 100+ users each firing 10 packets/sec over UDP and everything works smoothly.
Are you sure you are handling the UDP Init failure event, just in case?
Can you provide more context as regards your test?

thanks

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 14 Dec 2012, 18:34
by janheuninck
Yes I'm handling the event when the initialization of the UDP socket fails. This is a slimmed down version of the relevant code handling the SmartFox connection of a test client:

Code: Select all

public class SmartFoxProxy implements IEventListener
{
    public SmartFoxProxy()
    {
        // Create smartfox object
        _smartFox = new SmartFox(false);

        // Add event listeners
        _smartFox.addEventListener(SFSEvent.CONNECTION, this);
        _smartFox.addEventListener(SFSEvent.CONNECTION_LOST, this);
        _smartFox.addEventListener(SFSEvent.LOGIN, this);
        _smartFox.addEventListener(SFSEvent.LOGIN_ERROR, this);
        _smartFox.addEventListener(SFSEvent.ROOM_JOIN, this);
        _smartFox.addEventListener(SFSEvent.ROOM_JOIN_ERROR, this);
        _smartFox.addEventListener(SFSEvent.UDP_INIT, this);
        _smartFox.addEventListener(SFSEvent.EXTENSION_RESPONSE, this);

        // Disable bluebox
        _smartFox.setUseBlueBox(false);
    }

    public void connect()
    {
        if (!_smartFox.isConnecting())
        {
            // Connect
            _smartFox.connect(_ip, _port);
        }
    }

    private void onConnection()
    {
        // Login
        _smartFox.send(new LoginRequest(_username, _password, _zone, params));
    }

    private void onLogin()
    {
        // Init UDP
        if (_smartFox.isUdpAvailable())
        {
            if (!_smartFox.isUdpInited())
            {
                _smartFox.initUdp(_ip, _port);
            }
        }
    }

    private void onUDPSocketConnect(BaseEvent event)
    {
        // Get the state
        boolean success = Boolean.valueOf(event.getArguments().get("success").toString());

        if (success)
        {
            if (!_initialized)
            {
                // Join the room
                _smartFox.send(new JoinRoomRequest(_room));
            }
            else
            {
                // Log
                Logger.getLogger(SmartFoxProxy.class).info("[" + _username + "] UDP socket connected, but client is already initialized");
            }
        }
        else
        {
            // Log
            Logger.getLogger(SmartFoxProxy.class).error("[" + _username + "] UDP socket initialization failed");
        }
    }

    private void onRoomJoin()
    {
        _initialized = true;
    }

    public void send(HashMap<String, Object> params, boolean useUDP)
    {
        // Send the message to the server
        if (useUDP && (!_smartFox.isUdpAvailable() || !_smartFox.isUdpInited() || !_smartFox.getSocketEngine().getUdpManager().isInited()))
        {
            // Log
            Logger.getLogger(SmartFoxProxy.class).error("UDP is not set up properly!");
        }

        // Send the message
        _smartFox.send(new ExtensionRequest("s", data, _smartFox.getLastJoinedRoom(), useUDP));
    }

    @Override
    public void dispatch(BaseEvent event) throws SFSException
    {
        // Get the type of the event
        String type = event.getType();

        if (type.equals(SFSEvent.CONNECTION))
        {
            onConnection();
        }
        else if (type.equals(SFSEvent.CONNECTION_LOST))
        {
            onConnectionLost();
        }
        else if (type.equals(SFSEvent.LOGIN))
        {
            onLogin();
        }
        else if (type.equals(SFSEvent.LOGIN_ERROR))
        {
            onLoginError(event);
        }
        else if (type.equals(SFSEvent.ROOM_JOIN))
        {
            onRoomJoin();
        }
        else if (type.equals(SFSEvent.ROOM_JOIN_ERROR))
        {
            onRoomJoinError();
        }
        else if (type.equals(SFSEvent.UDP_INIT))
        {
            onUDPSocketConnect(event);
        }
        else if (type.equals(SFSEvent.EXTENSION_RESPONSE))
        {
            // Get the command
            String command = event.getArguments().get("cmd").toString();

            // Get the data
            ISFSObject params = (ISFSObject) event.getArguments().get("params");

            // Call the event handler
            onExtensionResponse(command, params);
        }
        else
        {
            // Log
            Logger.getLogger(SmartFoxProxy.class).debug("Event dispatched: " + event.getType() + " - " + event);
        }
    }
}


UDP is always initialized successful, and the if statement before I'm sending the messages to the server is always false (=> UDP should be setup properly).

This morning I also got a new exception:

Code: Select all

Dec 14, 2012 10:00:51 AM org.jboss.netty.channel.DefaultChannelPipeline
WARNING: An exception was thrown by a user handler while handling an exception event ([id: 0x2c59d953, /0.0.0.0:59410] EXCEPTION: java.nio.channels.ClosedChannelException)
java.lang.NullPointerException
   at sfs2x.client.core.sockets.UDPSocketLayer$UDPClientHandler.exceptionCaught(UDPSocketLayer.java:170)
   at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:432)
   at org.jboss.netty.channel.socket.nio.NioDatagramWorker.cleanUpWriteBuffer(NioDatagramWorker.java:745)
   at org.jboss.netty.channel.socket.nio.NioDatagramWorker.writeFromUserCode(NioDatagramWorker.java:444)
   at org.jboss.netty.channel.socket.nio.NioDatagramPipelineSink.eventSunk(NioDatagramPipelineSink.java:112)
   at org.jboss.netty.channel.Channels.write(Channels.java:611)
   at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:263)
   at org.jboss.netty.channel.socket.nio.NioDatagramChannel.write(NioDatagramChannel.java:236)
   at sfs2x.client.core.sockets.UDPSocketLayer.write(UDPSocketLayer.java:143)
   at sfs2x.client.bitswarm.UDPManager.send(UDPManager.java:104)
   at sfs2x.client.core.SFSIOHandler.writeUDP(SFSIOHandler.java:409)
   at sfs2x.client.core.SFSIOHandler.onDataWrite(SFSIOHandler.java:392)
   at sfs2x.client.core.SFSProtocolCodec.onPacketWrite(SFSProtocolCodec.java:79)
   at sfs2x.client.bitswarm.BitSwarmClient.send(BitSwarmClient.java:223)
   at sfs2x.client.SmartFox.send(SmartFox.java:893)
   ...


I'm using API version v1.0.5, which contains the netty-3.2.2.Final.jar library.


Cheers
Jan

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 17 Dec 2012, 11:17
by Lapo
Not being able to reproduce the issue locally all I can say is that I find strange this part of the code:

public void send(HashMap<String, Object> params, boolean useUDP)
{
// Send the message to the server
if (useUDP && (!_smartFox.isUdpAvailable() || !_smartFox.isUdpInited() || !_smartFox.getSocketEngine().getUdpManager().isInited()))
{
// Log
Logger.getLogger(SmartFoxProxy.class).error("UDP is not set up properly!");
}

// Send the message
_smartFox.send(new ExtensionRequest("s", data, _smartFox.getLastJoinedRoom(), useUDP));
}


1) I don't understand the convoluted IF expression... why do you need to check all those flags? All you have to do is send the UDPInit request ONCE and then wait for the server's response. Until then you don't want to send any UDP request.

2) The IF expression does not prevent the _smartFox.send(...) call to run, so you end up calling it even when you shouldn't

Thanks

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 17 Dec 2012, 16:14
by janheuninck
The if statement in the send() function was only added to do some more testing after I received those exceptions. It doesn't prevent the code from sending a UDP packet, but verifies if UDP is initialized (double checked after the UDP init event). The client doesn't start sending messages until it receives confirmation of the server that it's UDP channel has been initialized, but nonetheless I receive the above NullPointerExceptions...

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 18 Dec 2012, 16:22
by Lapo
Just to double check can you verify with this jar file?

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 18 Dec 2012, 17:10
by janheuninck
Lapo wrote:Just to double check can you verify with this jar file?


Still the same issue...

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 18 Dec 2012, 17:53
by Lapo
We would then need to put our hands on an actual working code that causes this issue, as we haven't found a way to cause the problem you describe.
The fastest way for us is if you send us an example.

thanks

Re: Sending UDP NullPointerException [v1.0.5]

Posted: 19 Dec 2012, 20:12
by janheuninck
Lapo wrote:We would then need to put our hands on an actual working code that causes this issue, as we haven't found a way to cause the problem you describe.
The fastest way for us is if you send us an example.

thanks


I'll get back to you next week with an example. Thanks!