最近,一些Android应用程序无法连接到socket.io Golang服务器的问题引起了广泛关注。php小编新一在此为大家解答。在使用socket.io Golang服务器时,有一些常见的连接问题可能导致Android应用程序无法连接。首先,确保你的Android应用程序和服务器在相同的网络环境下,并且能够互相访问。另外,检查你的代码中是否正确设置了服务器的地址和端口。如果问题仍然存在,可以尝试使用其他网络调试工具来检查连接问题,如Wireshark等。希望这些解答能帮助到你解决问题!
问题内容
我不知道我是否遗漏了一些东西,因为我的 kotlin
代码没有找到 golang
套接字服务器。我做了一个 netstat -ano
并且端口 8000 已经用于 tcp,所以我认为套接字服务器运行良好。但我的安卓还是找不到。服务器和模拟器都在同一网络上。这是我的代码:
//服务器(golang)
import (
"fmt"
"net/http"
socketio "github.com/googollee/go-socket.io"
"github.com/googollee/go-socket.io/engineio"
"github.com/googollee/go-socket.io/engineio/transport"
"github.com/googollee/go-socket.io/engineio/transport/polling"
"github.com/googollee/go-socket.io/engineio/transport/websocket"
)
server := socketio.newserver(&engineio.options{
transports: []transport.transport{
&polling.transport{
checkorigin: alloworiginfunc,
},
&websocket.transport{
checkorigin: alloworiginfunc,
},
},
})
server.onconnect("/", func(s socketio.conn) error {
s.setcontext("")
fmt.println("connected:", s.id())
return nil
})
server.onevent("/", "notice", func(s socketio.conn, msg string) {
fmt.println("notice:", msg)
s.emit("reply", "have "+msg)
})
server.onerror("/", func(s socketio.conn, e error) {
fmt.println("meet error:", e)
})
server.ondisconnect("/", func(s socketio.conn, reason string) {
fmt.println("closed", reason)
})
go server.serve()
defer server.close()
http.handle("/socket.io/", server)
http.handle("/", http.fileserver(http.dir("./asset")))
fmt.println("scktsrv serving at localhost:8000...")
fmt.print(http.listenandserve(":8000", nil))
//android(kotlin)
implementation ('io.socket:socket.io-client:2.0.0') {
exclude group: 'org.json', module: 'json'
}
try {
msocket = io.socket("http://localhost:8000/skt")
log.d(tag, "success: ${msocket.id()}")
} catch (e: exception) {
e.localizedmessage?.let { log.e(tag, it) }
}
msocket.connect()
msocket.on(socket.event_connect, onconnect)
msocket.on("reply", onreply)
private var onconnect = emitter.listener {
log.i(tag, "onconnect")
msocket.emit("notice", "{\"relay_num\": 4, \"to_status\": 1}")
}
private var onreply = emitter.listener {
log.i(tag, "replymsg: ${it[0]}")
}
更新:
在@dev.bmax的回答之前,我已经发现了一些关于启用cleartexttraffic的信息,并且已经在我的androidmanifest.xml
上添加了 android:usescleartexttraffic="true"
,但该应用程序仍然无法连接到服务器。 socket.connected()
现在返回 false。
另外,您应该如何实际连接到服务器?我只需要 http://10.0.2.2:8000
而不需要任何路径吗?
更新:
我刚刚注意到我不断收到如下所示的日志:
tagsocket(6) with statstag=0xffffffff, statsuid=-1
它不断在 logcat 上弹出
更新:
我四处寻找其他代码,并找到了一个可以工作的代码。幸运或不幸的是,这很简单。这是我找到的代码:
//go语言
listener, _ := net.listen("tcp", ":8000")
for {
conn, _ := listener.accept()
fmt.printf("%s --- %s\n", conn.localaddr(), conn.remoteaddr())
io.writestring(conn, "welcome to socket")
}
//android kotlin
val host = "192.168.100.250"
val port = 8000
executors.newsinglethreadexecutor().execute {
try {
val socket = java.net.socket(host, port)
receivemove(socket)
} catch (e: connectexception) {
log.e(tag, "socket connexc: ${e.localizedmessage}")
runonuithread {
toast.maketext(this, "connection failed", toast.length_short).show()
}
}catch (e: exception) {
log.e(tag, "socket connexc: ${e.localizedmessage}")
}
}
现在我想知道,为什么准系统代码可以工作,而 googollee 库提供的代码却不能?我认为我没有错过双方的任何设置。
更新:
取得了一些进展。发现 android
代码可以工作,但由于某种原因正在执行一些意外的问题。以下是我在 android 端所做的更改的详细信息:
// 应用程序 build.gradle
implementation('io.socket:socket.io-client:0.8.3') {
exclude group: 'org.json', module: 'json'
}
//mainactivity.kt
import io.socket.client.io
import io.socket.client.socket
init {
try {
msocket = io.socket("http://:8000/socket.io/")
}catch (e: connectexception) {
log.e(tag, "socket connexc: ${e.localizedmessage}")
}catch (e: urisyntaxexception) {
log.e(tag, "socket urisynexc: ${e.localizedmessage}")
}catch (e: exception){
log.e(tag, "socket exc: ${e.localizedmessage}")
}
}
// androidmanifest.xml
android:usesCleartextTraffic="true"
//I used to have android:networkSecurityConfig="@xml/network_security_config" here as well
完成这些更改后,应用程序现在可以连接到服务器。但连接后,应用程序似乎立即断开连接。然后它再次连接到服务器,然后再次断开连接,然后连接到服务器,这个循环似乎没有停止。我在断开连接时收到 lated 客户端命名空间disconnect
。
解决方法
我终于找到了使这项工作发挥作用的部分。我认为最大的问题是在android方面。更换要使用的库似乎已经解决了所有问题,然后只需进行一个小的更改即可解决立即断开连接的问题。以下是双方的最终代码和其他详细信息:
//go语言
package main
import (
"fmt"
"net/http"
socketio "github.com/googollee/go-socket.io"
"github.com/googollee/go-socket.io/engineio"
"github.com/googollee/go-socket.io/engineio/transport"
"github.com/googollee/go-socket.io/engineio/transport/polling"
"github.com/googollee/go-socket.io/engineio/transport/websocket"
)
var alloworiginfunc = func(r *http.request) bool {
return true
}
func main() {
server := socketio.newserver(&engineio.options{
transports: []transport.transport{
&polling.transport{
checkorigin: alloworiginfunc,
},
&websocket.transport{
checkorigin: alloworiginfunc,
},
},
})
server.onconnect("/", func(s socketio.conn) error {
s.setcontext("")
fmt.println("connected:", s.id())
return nil
})
server.onevent("/", "notice", func(s socketio.conn, msg string) {
fmt.println("notice:", msg)
s.emit("reply", "have "+msg)
})
server.onerror("/", func(s socketio.conn, e error) {
fmt.println("error:", e)
})
server.ondisconnect("/", func(s socketio.conn, reason string) {
fmt.println("closed", reason)
})
go server.serve()
defer server.close()
http.handle("/socket.io/", server)
http.handle("/", http.fileserver(http.dir("./asset")))
fmt.println("socket server serving at localhost:8000...")
fmt.print(http.listenandserve(":8000", nil))
}
// 安卓 kotlin
androidmanifest.xml
应用程序构建.gradle
implementation('io.socket:socket.io-client:0.8.3') {
exclude group: 'org.json', module: 'json'
}
// mainactivity.kt 或任何您想放置此内容的地方
import io.socket.client.IO
import io.socket.client.Socket
class MainActivity : AppCompatActivity() {
private lateinit var mSocket: Socket
...
init {
try {
mSocket = IO.socket("http://:8000/")
}catch (e: ConnectException) {
Log.e(TAG, "Socket ConnExc: ${e.localizedMessage}")
}catch (e: URISyntaxException) {
Log.e(TAG, "Socket URISynExc: ${e.localizedMessage}")
}catch (e: Exception){
Log.e(TAG, "Socket Exc: ${e.localizedMessage}")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
...
mSocket.connect()
binding.btnSend.setOnClickListener {
Log.i(TAG, "isConnected: ${mSocket.connected()}")
mSocket.emit("notice", "from_app_msg")
}
}
override fun onDestroy() {
super.onDestroy()
mSocket.off()
mSocket.disconnect()
}
}
关于立即断开,看起来你在android端尝试连接时并不需要添加/socket.io
。删除它解决了断开连接的问题。而且您的项目中不需要 asset
文件夹。伙计,这个 socket.io
东西很奇怪。
以上就是Android应用程序无法连接到socket.io Golang服务器的详细内容,更多请关注编程网其它相关文章!