In letzter Zeit hat das Problem, dass einige Android-Anwendungen keine Verbindung zum socket.io Golang-Server herstellen können, große Aufmerksamkeit erregt. Der PHP-Editor Xinyi ist hier, um die Frage für alle zu beantworten. Bei der Verwendung des socket.io Golang-Servers gibt es einige häufige Verbindungsprobleme, die dazu führen können, dass Android-Anwendungen keine Verbindung herstellen können. Stellen Sie zunächst sicher, dass sich Ihre Android-Anwendung und Ihr Server in derselben Netzwerkumgebung befinden und aufeinander zugreifen können. Überprüfen Sie außerdem, ob die Adresse und der Port des Servers in Ihrem Code korrekt festgelegt sind. Wenn das Problem weiterhin besteht, können Sie versuchen, andere Netzwerk-Debugging-Tools zu verwenden, um nach Verbindungsproblemen zu suchen, z. B. Wireshark usw. Ich hoffe, diese Antworten können Ihnen bei der Lösung Ihres Problems helfen!
Ich weiß nicht, ob ich etwas übersehe, da mein kotlin
代码没有找到 golang
套接字服务器。我做了一个 netstat -ano
und Port 8000 bereits für TCP verwendet werden, also gehe ich davon aus, dass der Socket-Server einwandfrei läuft. Aber mein Android kann es immer noch nicht finden. Sowohl Server als auch Emulator befinden sich im selben Netzwerk. Das ist mein Code:
//Server (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]}") }
Update:
Vor der Antwort von @dev.bmax hatte ich einige Informationen zum Aktivieren von Klartextverkehr gefunden und bereits in meinem androidmanifest.xml
上添加了 android:usescleartexttraffic="true"
,但该应用程序仍然无法连接到服务器。 socket.connected()
gibt jetzt false zurück.
Außerdem: Wie soll man eigentlich eine Verbindung zum Server herstellen? Brauche ich nur http://10.0.2.2:8000
ohne Pfad?
Update:
Mir ist gerade aufgefallen, dass ich immer wieder solche Protokolle erhalte:
tagsocket(6) with statstag=0xffffffff, statsuid=-1
Es taucht immer wieder auf Logcat auf
Update:
Ich habe mich nach anderen Codes umgesehen und einen gefunden, der funktioniert. Zum Glück oder leider ist es ziemlich einfach. Dies ist der Code, den ich gefunden habe:
//gehe Sprache
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}") } }
Jetzt frage ich mich, warum der Barebone-Code funktioniert, der von der Googollee-Bibliothek bereitgestellte Code jedoch nicht? Ich glaube nicht, dass ich auf beiden Seiten irgendein Setup verpasst habe.
Update:
Es wurden einige Fortschritte erzielt. Gefunden android
Der Code funktioniert, führt aber aus irgendeinem Grund zu unerwarteten Problemen. Hier sind die Details der Änderungen, die ich auf der Android-Seite vorgenommen habe:
// Anwendung 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
Nach Abschluss dieser Änderungen kann die Anwendung nun eine Verbindung zum Server herstellen. Aber nach dem Herstellen der Verbindung scheint die App sofort die Verbindung zu trennen. Dann stellt es erneut eine Verbindung zum Server her, trennt die Verbindung erneut, stellt dann erneut eine Verbindung zum Server her, und der Zyklus scheint nicht zu stoppen. Ich bekomme lated 客户端命名空间disconnect
, wenn ich die Verbindung trenne.
Endlich habe ich das Teil gefunden, mit dem das funktioniert. Ich denke, das größte Problem liegt auf der Android-Seite. Der Wechsel der zu verwendenden Bibliothek schien alle Probleme behoben zu haben, und dann löste nur eine kleine Änderung das Problem der sofortigen Verbindungstrennung. Hier sind die endgültigen Codes und weitere Details von beiden Parteien:
//gehe Sprache
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)) }
// Android Kotlin
androidmanifest.xml
<uses-permission android:name="android.permission.internet" /> <application ... android:usescleartexttraffic="true">
app-build.gradle
implementation('io.socket:socket.io-client:0.8.3') { exclude group: 'org.json', module: 'json' }
// mainactivity.kt oder wo immer Sie diesen Inhalt platzieren möchten
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() } }
Bezüglich der sofortigen Trennung scheint es so, als müssten Sie /socket.io
。删除它解决了断开连接的问题。而且您的项目中不需要 asset
文件夹。伙计,这个 socket.io
nicht hinzufügen, wenn Sie versuchen, eine Verbindung auf der Android-Seite herzustellen. Etwas ist seltsam.
Das obige ist der detaillierte Inhalt vonDie Android-Anwendung kann keine Verbindung zum socket.io Golang-Server herstellen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!