I'm trying to implement both the WebSocket Client and the WebSocket Server on the same Android device. Basically I have two Android apps that need to communicate. I've implemented a couple of test apps using LocalSockets successfully, but the target Client side app is a web browser app so it can only use WebSockets.
I've tried the https://github.com/TooTallNate/Java-WebSocket implementation. I have the Client app running in the foreground and the Server app running in an Android Service in the background. Essentially, I've taken my LocalSocket implementations that works and replaced the LocalSockets with TooTallNate's WebSockets. It appears that the WebSocket Server is failing to start. The obvious symptom is that the Client side throws a NotYetConnectedException every time it tries to send something.
Another symptom is if I try to use WebSocketServer.run() instead of WebSocketServer.start() I get an IOException from ServerSocketChannel.open().
Any ideas are certainly welcome at this point. Thanks!
A basic implementation is this:
public class ChatServer extends WebSocketServer
{
private final String TAG = LogHelper.makeLogTag(ChatServer.class);
private Map<String, WebSocket> clients = new ConcurrentHashMap<>();
public ChatServer(int port)
{
super(new InetSocketAddress(port));
}
public ChatServer(InetSocketAddress address)
{
super(address);
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
String uniqueID = UUID.randomUUID().toString();
clients.put(uniqueID, conn);
conn.send(WrapHelper.regToJson(uniqueID));
conn.send(WrapHelper.resToJson("Welcome to the server!"));
broadcast((WrapHelper.resToJson("new connection: " + handshake.getResourceDescriptor()))); //This method sends a message to all clients connected
LogHelper.e(TAG, conn.getRemoteSocketAddress().getAddress().getHostAddress() + " entered the room!");
}
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
broadcast(WrapHelper.resToJson(conn + " has left the room!"));
LogHelper.e(TAG, conn + " has left the room!");
}
@Override
public void onMessage(WebSocket conn, String message) {
Gson gson = new Gson();
final Frame frame = gson.fromJson(message, Frame.class);
if (frame != null) {
LogHelper.e(TAG, "frame: " + frame);
switch (frame.getCmd()) {
case CMD_MSG:
broadcast(message);
break;
case CMD_REG_USER:
break;
}
}
LogHelper.e(TAG, conn + ": " + message);
}
@Override
public void onMessage(WebSocket conn, ByteBuffer message) {
broadcast(message.array());
LogHelper.e(TAG, conn + ": " + message);
}
@Override
public void onError(WebSocket conn, Exception ex)
{
ex.printStackTrace();
if (conn != null) {
// some errors like port binding failed may not be assignable to a specific websocket
}
}
@Override
public void onStart()
{
LogHelper.e(TAG, "Server started!");
setConnectionLostTimeout(0);
setConnectionLostTimeout(100);
}
}
In this example you can see that we are overriding the abstract methods of the WebSocketServer
class. You can create an interface to update your UI.
Then in your main activity you can use it like this:
@Override
protected void onCreate(Bundle savedInstanceState)
{
...
ChatServer server = new ChatServer(DEFAULT_CHAT_PORT);
server.start();
...
}
I have a full implementation of a chat sample here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With