Reputation: 194
I'm trying to connect an Android app using Native Socket.IO to an Express server. The server has a very simple job (currently) of taking incoming traffic on 4200 and sending it back out to other clients so they can display it - although right now I'm just debugging the server and this Android implementation, hoping for the beautiful text "client connected"
This is the server API
// Socket handling
io.on( 'connection', (socket) => {
console.log('Client Connected');
socket.on('temperature', (data) => {
console.log('Engine Data:' + data);
// For now, just spit data back to all other connected clients
socket.broadcast.emit('temperature', {num: data});
});
socket.on('disconnect', ()=> {
console.log('Client disconnected');
});
});
Currently this works with a basic Node.JS client sending random numbers, so I know the server works:
<script>
var socket = io('http://localhost:4200');
socket.on('connection', (socket) => {
console.log('Connection Success');
});
let temperature = 0;
//Send stuff every 100ms
setInterval(() => {
let lastTemp = temperature < 90 ? temperature : 0;
temperature = Math.floor(Math.random() * 5) + lastTemp;
socket.emit('temperature', temperature);
}, 50);
</script>
However my Android app is having issues - the server doesn't log a connection like it does the browser client, and while it isn't throwing an exception on connection, the socket ID is just NULL and the state is "not connected" when debugging. I've been following different tutorials and trying solutions posted on StackOverflow, so I currently have a main activity utilizing a seek bar for dummy values that looks like this:
//! SocketIO stuff
import com.github.nkzawa.socketio.client.IO
import com.github.nkzawa.socketio.client.Socket
class MainActivity : AppCompatActivity() {
//! Instantiate socket for other functions that will utilize it - this will likely be part of its own class
lateinit var mSocket: Socket
//! Main Activity creation
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
//! SeekBar for setting dummy input by user
val seek: SeekBar = findViewById<SeekBar>(R.id.seekBar)
seek.max = 100
seek.progress = 50
//! CurrentVal is our current dummy sensor value
var currentVal: Int;
//! Connect to web server
try {
//! Configure library options
val options = IO.Options()
options.reconnection = true
options.forceNew = true
//This address is the way you can connect to localhost with AVD(Android Virtual Device)
mSocket = IO.socket("http://10.0.2.2:4200/", options) // emulator loopback address
} catch (e: Exception) {
e.printStackTrace()
Log.d("Failure", "Failed to connect to server")
}
Log.d("Connected", "socket ID:${mSocket.id()}")
mSocket.connect()
seek.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
...
override fun onStopTrackingTouch(seek: SeekBar) {
//Progress stopped
//get value from seek bar
currentVal = seek.progress
//Send the value via our socket
mSocket.emit("temperature", currentVal)
}
})
}
My Manifest includes the following based on feedback from other StackOverflow suggestions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
...
android:usesCleartextTraffic="true"
...
However the server doesn't reflect that a client is connected. When I look at Wireshark, I see that there is indeed a port 55735 that's trying to connect to the server running on 4200, however the server is responding with "400 Bad Request" and the JSON string value is "Unsupported protocol version"
2899 23.395504 127.0.0.1 127.0.0.1 HTTP/JSON 287 HTTP/1.1 400 Bad Request , JavaScript Object Notation (application/json)
This leads me to believe that there's some compatibility issue with the Socket.IO library I'm using and Socket.IO on the server. The tutorial I'm using is on the Socket.IO website... but it's also from 2015. Should I be following a different way to use Socket.IO on Android?
Upvotes: 1
Views: 2164
Reputation: 194
I seem to have figured out the issue - the socket.io
library for Android was not compatible with the latest 3.1.1 in NPM
This was mainly shown by watching the data in Wireshark - I had communication between the ports, however the response - mainly the JSON in the response - indicated an incorrect protocol version
In short the dependency in my build.gradle file for the app, shown in the original tutorial from Socket.IO from 2015 is WAY out of date
implementation 'com.github.nkzawa:socket.io-client:0.6.0'
//OUT OF DATE
This implementation from Joyce Hong was closer...
implementation ('io.socket:socket.io-client:1.0.0') {
exclude group: 'org.json', module: 'json'
}
//Still nope, but that was a clue
However, the implementation that's compatible with my 3.1.1 Socket.IO library in NPM is
implementation ('io.socket:socket.io-client:2.0.0') {
exclude group: 'org.json', module: 'json'
}
//YES
If anyone else is running into this issue where there's traffic between ports, but neither is registering a connection, check your versions
Upvotes: 3