最近,一些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
東西很奇怪。
以上是Android應用程式無法連接到socket.io Golang伺服器的詳細內容。更多資訊請關注PHP中文網其他相關文章!