我正在尝试将使用本地Socket.IO的安卓应用程序连接到Express服务器。服务器有一个非常简单的工作(目前)是接收4200上的传入流量,并将其发送回其他客户端,以便它们可以显示它-尽管现在我只是在调试服务器和这个Android实现,希望看到漂亮的文本"client connected“。
这是服务器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');
});
});目前,这与发送随机数的基本Node.JS客户端一起工作,所以我知道服务器是工作的:
<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>然而,我的Android应用程序有问题-服务器不像浏览器客户端那样记录连接,虽然它没有在连接时抛出异常,但套接字ID仅为空,并且在调试时状态为“未连接”。我一直在关注不同的tutorials并尝试发布在StackOverflow上的解决方案,所以我目前有一个主要活动,利用了一个用于虚拟值的搜索栏,如下所示:
//! 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)
}
})
}根据来自其他StackOverflow建议的反馈,我的清单包括以下内容
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
...
android:usesCleartextTraffic="true"
...但是,服务器不会反映出客户端已连接。当我查看Wireshark时,我看到确实有一个端口55735正在尝试连接到运行在4200上的服务器,但是服务器的响应是“400Bad Request”,而JSON字符串值是"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)这让我相信,我正在使用的Socket.IO库和服务器上的Socket.IO存在一些兼容性问题。我正在使用的教程在Socket.IO网站上...但它也是2015年的。我应该遵循一种不同的方式在安卓上使用Socket.IO吗?
发布于 2021-02-23 03:20:29
我似乎已经解决了这个问题--用于安卓系统的socket.io库与NPM最新的3.1.1版本不兼容
这主要是通过观察Wireshark -I中的数据在端口之间进行通信来显示的,但是响应-主要是响应中的JSON -指示不正确的协议版本
简而言之,在2015年Socket.IO的原始教程中显示的应用程序的build.gradle文件中的依赖项已远远过时
implementation 'com.github.nkzawa:socket.io-client:0.6.0'
//OUT OF DATEJoyce Hong的这个实现更接近...
implementation ('io.socket:socket.io-client:1.0.0') {
exclude group: 'org.json', module: 'json'
}
//Still nope, but that was a clue但是,在NPM中与我的3.1.1 Socket.IO库兼容的实现是
implementation ('io.socket:socket.io-client:2.0.0') {
exclude group: 'org.json', module: 'json'
}
//YES如果其他任何人遇到这个问题,在端口之间有通信,但都没有注册连接,请检查您的版本
https://stackoverflow.com/questions/66320114
复制相似问题