Message to server not getting echoed

I’m having a strange problem and I hope that I’m not trying to do anything stupid here.

What I am trying to do is just send a String to the SGS and then echo the ByteBuffer back out on a channel to all the connected clients (just one at the moment).

What I am finding is if once the data is recieved at the server, I get all the bytes out of the ByteBuffer and then send the ByteBuffer on, the information is sent back to the client correctly. If I just send the ByteBuffer on, the information dosen’t get sent correctly to the clients (the ByteBuffer that is recieved dosn’t contain any data, capacity = 0).

To send the data I am doing this:


ByteBuffer buffer = ByteBuffer.allocate(message.length());
buffer.put(message.getBytes());
toServer.sendData(buffer);

toServer.sendData does this:


public void sendData(ByteBuffer bytes) {
        mgr.sendToServer(bytes, true);
}

at the recieving end I am doing this:



public void dataArrived(byte[] from, ByteBuffer data, boolean reliable) {
       
        int remaining = data.remaining();
        System.out.println("remaining: " + remaining + " capacity: " + data.capacity());
        
        byte [] message = new byte[remaining];
        data.get(message);
        
        System.out.println("raw message is: " + new String(message));        
}

and in the server I am doing this:


public void userDataReceived(UserID from, ByteBuffer data) {
        
        SimTask task = SimTask.getCurrent();
        byte[] dummy = new byte[data.remaining()];  //comment out these two lines and it dosn't work!!
        data.get(dummy);                                            //comment out these two lines and it dosn't work!!
        for(UserID id : users)
        {
            task.sendData(gameChannel, id, data, true);
        }
}

If I don’t have the two lines mentioned in the commentsthere I get a capacity 0 ByteBuffer at the client. I did try just doing a data.get(); and then sending the buffer on but that way I only got the first charceter of my message.

users is a list that I add clients too as they connect


public void userJoined(UserID uid, Subject subject) {
        Set<Principal> principals = subject.getPrincipals();
        Principal principal = principals.iterator().next();
        
        System.err.println("User Joined server (P): " + uid + " (" + principal.getName() + ")");
        
        users.add(uid);
        SimTask.getCurrent().addUserDataListener(uid, thisobj);
}

Is there something really obvious that I’m missing here?

Thanks in advance,
Dan.

You might need to do something with the buffer, like rewind it or something (not sure).

The other option is that SGS reuses the buffer under the covers, so you might have to copy the data into another buffer to send on. Not sure on either counts, but they seem to be the two options to look at.

HTH

Endolf

I did try sticking a rewind() in before sending it on, as I saw it in one of the examples, but it didn’t seem to do any good :frowning:

I wondered about trying to copy it but couldn’t see why waht I was doing would have that effect as I’m still sending the original buffer on afetr getting the bytes out of it.

I was wonderig if it was somthign to do with how I was trying to use the sgs (my boot object is the sole listener for data) but then why does it work in one case and not the other?

Incidently any one know that the difference between buffer.array() and buffer.get(byteArray) is? does array return the raw array and get copy in to the array you pass in?

Dan.

Oh I will try copying the ByteBuffer and then sending it on when I get chance.

hmmm just looked that te Javadoc for ByteBuffer it seems a strange beast.

does duplicate actually copy the underlying memory? or does it effectivle just give you a diferent view on the same memory?

if so how do you actually get a new copy of the data? get() the underlying array and then wrap it?

Dan.

sounds like you need to flip the buffer.

I’ll give flipping it ago, thanks. I think my overall simple server is a bit too simple too. So I’m going to do a little rejgging.

Duplicate just gives youa enw ehader to the same data, yes.

Create a new buffer of the same size, make sure your original buffer is rewound, and do newbuffer.put(oldbuffer)

Cheers thanks, I’ll give that a go.

So should I be copying the data for each user I want to sent to?

What I am aiming towards is amodel where a clinet sends the data to teh server and the server timestaps it and sends it out to all teh clients to be acted upon (basically the modified lock step that Kev did in his ASD code, eventually).

Cheers,
Dan.

Whelp depends on how you organize it.

What Id personally do is to send it once from the server as a broadcast to the channel.

If you are going to try to send the same buffer multiple tiems then id recoomend yo udo whT I do internally for such multi-plexing and rather then doing a send(… ,buff, … ) do a send(… ,buff.duplicate(), … )

This ensures that you are isolated from any side-effect state changes to the buffer’s internal pointing information.