首頁 > 後端開發 > Golang > 主體

Android應用程式無法連接到socket.io Golang伺服器

PHPz
發布: 2024-02-08 21:48:22
轉載
1123 人瀏覽過

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

最近,一些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中文網其他相關文章!

相關標籤:
來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!