Here is the full solution for Android Client + Socket IO Server (Lot of code but works). There seems to be lack of support for Android and IOS when it comes to socket io which is a tragedy of sorts.
Basically creating a room name by joining user unique id from mysql or mongo then sorting it (done in Android Client and sent to server). So each pair has a unique but common amongst the pair room name. Then just go about chatting in that room.
For quick refernce how room is created in Android
// Build The Chat Room
if (Integer.parseInt(mySqlUserId) < Integer.parseInt(toMySqlUserId)) {
room = "ic" + mySqlUserId + toMySqlUserId;
} else {
room = "ic" + toMySqlUserId + mySqlUserId;
}
The Full Works
Package Json
"dependencies": {
"express": "^4.17.1",
"socket.io": "^2.3.0"
},
"devDependencies": {
"nodemon": "^2.0.6"
}
Socket IO Server
app = require('express')()
http = require('http').createServer(app)
io = require('socket.io')(http)
app.get('/', (req, res) => {
res.send('Chat server is running on port 5000')
})
io.on('connection', (socket) => {
// console.log('one user connected ' + socket.id);
// Join Chat Room
socket.on('join', function(data) {
console.log('======Joined Room========== ');
console.log(data);
// Json Parse String To Access Child Elements
var messageJson = JSON.parse(data);
const room = messageJson.room;
console.log(room);
socket.join(room);
});
// On Receiving Individual Chat Message (ic_message)
socket.on('ic_message', function(data) {
console.log('======IC Message========== ');
console.log(data);
// Json Parse String To Access Child Elements
var messageJson = JSON.parse(data);
const room = messageJson.room;
const message = messageJson.message;
console.log(room);
console.log(message);
// Sending to all clients in room except sender
socket.broadcast.to(room).emit('new_msg', {
msg: message
});
});
socket.on('disconnect', function() {
console.log('one user disconnected ' + socket.id);
});
});
http.listen(5000, () => {
console.log('Node app is running on port 5000')
})
Android Socket IO Class
public class SocketIOClient {
public Socket mSocket;
{
try {
mSocket = IO.socket("http://192.168.1.5:5000");
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
public Socket getSocket() {
return mSocket;
}
}
Android Activity
public class IndividualChatSocketIOActivity extends AppCompatActivity {
// Activity Number For Bottom Navigation Menu
private final Context mContext = IndividualChatSocketIOActivity.this;
// Strings
private String mySqlUserId;
private String toMySqlUserId;
// Widgets
private EditText etTextMessage;
private ImageView ivSendMessage;
// Socket IO
SocketIOClient socketIOClient = new SocketIOClient();
private String room;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
// Widgets
etTextMessage = findViewById(R.id.a_chat_et_text_message);
ivSendMessage = findViewById(R.id.a_chat_iv_send_message);
// Get The MySql UserId from Shared Preference
mySqlUserId = StartupMethods.getFromSharedPreferences("shared",
"id",
mContext);
// Variables From Individual List Adapter
Intent intent = getIntent();
if (intent.hasExtra("to_id")) {
toMySqlUserId = Objects.requireNonNull(Objects.requireNonNull(getIntent().getExtras())
.get("to_id"))
.toString();
}
// Build The Chat Room
if (Integer.parseInt(mySqlUserId) < Integer.parseInt(toMySqlUserId)) {
room = "ic" + mySqlUserId + toMySqlUserId;
} else {
room = "ic" + toMySqlUserId + mySqlUserId;
}
connectToSocketIO();
joinChat();
leaveChat();
getChatMessages();
sendChatMessages();
}
@Override
protected void onPause() {
super.onPause();
}
private void connectToSocketIO() {
socketIOClient.mSocket = socketIOClient.getSocket();
socketIOClient.mSocket.on(Socket.EVENT_CONNECT_ERROR,
onConnectError);
socketIOClient.mSocket.on(Socket.EVENT_CONNECT_TIMEOUT,
onConnectError);
socketIOClient.mSocket.on(Socket.EVENT_CONNECT,
onConnect);
socketIOClient.mSocket.on(Socket.EVENT_DISCONNECT,
onDisconnect);
socketIOClient.mSocket.connect();
}
private void joinChat() {
// Prepare To Send Data Through WebSockets
JSONObject jsonObject = new JSONObject();
// Header Fields
try {
jsonObject.put("room",
room);
socketIOClient.mSocket.emit("join",
String.valueOf(jsonObject));
} catch (JSONException e) {
e.printStackTrace();
}
}
private void leaveChat() {
}
private void getChatMessages() {
socketIOClient.mSocket.on("new_msg",
new Emitter.Listener() {
@Override
public void call(Object... args) {
try {
JSONObject messageJson = new JSONObject(args[0].toString());
String message = String.valueOf(messageJson);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(IndividualChatSocketIOActivity.this,
message,
Toast.LENGTH_SHORT)
.show();
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
private void sendChatMessages() {
ivSendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String message = etTextMessage.getText()
.toString()
.trim();
// Prepare To Send Data Thru WebSockets
JSONObject jsonObject = new JSONObject();
// Header Fields
try {
jsonObject.put("room",
room);
jsonObject.put("message",
message);
socketIOClient.mSocket.emit("ic_message",
String.valueOf(jsonObject));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
public Emitter.Listener onConnect = new Emitter.Listener() {
@Override
public void call(Object... args) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(IndividualChatSocketIOActivity.this,
"Connected To Socket Server",
Toast.LENGTH_SHORT)
.show();
}
});
Log.d("TAG",
"Socket Connected!");
}
};
private Emitter.Listener onConnectError = new Emitter.Listener() {
@Override
public void call(Object... args) {
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
};
private Emitter.Listener onDisconnect = new Emitter.Listener() {
@Override
public void call(Object... args) {
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
};
}
Android Gradle
// SocketIO
implementation ('io.socket:socket.io-client:1.0.0') {
// excluding org.json which is provided by Android
exclude group: 'org.json', module: 'json'
}