I wonder if someone used RealTime sockets with Google Multiplayer (rather than messages).
I have a code that works OK with streams derived from "native"(IP) socket, so I expected it to work with RealTime socket streams too. Unfortunately this is not the case.
The following code works fine with RealTime sockets
Sending end:
int s1, s2;
os.write(new byte[] {(byte)s1, (byte)s2};
os.flush(); // May be redundant, according to Google docs
Receiving end:
byte[] buffer = new byte[2];
is.read(buffer);
int r1=buffer[0] & 0xff;
int r2=buffer[1] & 0xff;
However, since the length of chuck is unknown in advance, I prefer to spit the chunk into two pieces: length and the data, read one after another. Consider therefore a different code:
Sending end:
byte s1, s2;
os.write(s1);
os.write(s2);
os.flush();
Receiving end:
int r1=is.read();
int r2=is.read();
In this case, only first byte is read, while the second byte never comes!
Since Android docs don't recommend flush, I tried to make a wrapper for caching several writes into one on flush:
public class OutputStreamWrapper extends OutputStream {
private OutputStream innerOs;
private ByteArrayOutputStream baos;
public OutputStreamWrapper(OutputStream innerOs) {
this.innerOs = innerOs;
baos = new ByteArrayOutputStream();
}
@Override
public void write(int oneByte) throws IOException {
baos.write(oneByte);
}
@Override
public void flush() throws IOException {
if (baos.size() > 0)
innerOs.write(baos.toByteArray());
baos.reset();
}
@Override
public void write(byte[] buffer, int offset, int count)
throws IOException {
baos.write(buffer, offset, count);
}
@Override
public void close() throws IOException {
flush();
innerOs.close();
baos.close();
}
}
The problem persists!
Am I doing something wrong?
If I can't find the solution, I will have to write custom streams as wrappers for Real-Time Messages, but it is really a shame to avoid "ready to use" streams.
No answer for two months... Have to answer it somehow :)
I tried several approaches, but couldn't get it working. Either the implementation of RealTime sockets is broken (BTW, I haven't come across any example of using those), or I still misunderstand something.
As a result, I found nothing better than making my own RealTime sockets by sending messages (reliable or unreliable, depending on request) under the hood.
The code is so weird that I am ashamed to publish it. But this is the idea:
outputStream has a BiteArrayOuputStream of size equals to max allowed size of RealTimeMessage. It fires a message either on flush() or when the array is full. There is an indicator of a split packet.
I keep a queue of received messages. The input streams polls the queue and after the whole packet has been collected it returns the bytes.
Works great for me!