最近,一些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)
<uses-permission android:name="android.permission.internet" /> 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://<local_ip>: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
<uses-permission android:name="android.permission.internet" /> <application ... android:usescleartexttraffic="true">
应用程序构建.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://<host>: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
东西很奇怪。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!