Die Android-Anwendung kann keine Verbindung zum socket.io Golang-Server herstellen

PHPz
Freigeben: 2024-02-08 21:48:22
nach vorne
1123 Leute haben es durchsucht

Android应用程序无法连接到socket.io Golang服务器

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!

Frageninhalt

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))
Nach dem Login kopieren

//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]}")
}
Nach dem Login kopieren

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
Nach dem Login kopieren

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")
}
Nach dem Login kopieren

//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}")
    }
}
Nach dem Login kopieren

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'
}
Nach dem Login kopieren

//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}")
    }
}
Nach dem Login kopieren

// androidmanifest.xml

android:usesCleartextTraffic="true"
//I used to have android:networkSecurityConfig="@xml/network_security_config" here as well
Nach dem Login kopieren

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 客户端命名空间dis​​connect, wenn ich die Verbindung trenne.

Workaround

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))
}
Nach dem Login kopieren

// Android Kotlin

androidmanifest.xml

<uses-permission android:name="android.permission.internet" />

<application
    ...
    android:usescleartexttraffic="true">
Nach dem Login kopieren

app-build.gradle

implementation('io.socket:socket.io-client:0.8.3') {
        exclude group: 'org.json', module: 'json'
    }
Nach dem Login kopieren

// 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()
    }
}
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!