Rumah > pembangunan bahagian belakang > Golang > Aplikasi Android tidak boleh menyambung ke pelayan socket.io Golang

Aplikasi Android tidak boleh menyambung ke pelayan socket.io Golang

PHPz
Lepaskan: 2024-02-08 21:48:22
ke hadapan
1185 orang telah melayarinya

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

Baru-baru ini, masalah beberapa aplikasi Android tidak dapat disambungkan ke pelayan socket.io Golang telah menarik perhatian meluas. Editor PHP Xinyi berada di sini untuk menjawab soalan untuk semua orang. Apabila menggunakan pelayan socket.io Golang, terdapat beberapa isu sambungan biasa yang boleh menyebabkan aplikasi Android gagal disambungkan. Mula-mula, pastikan aplikasi dan pelayan Android anda berada pada persekitaran rangkaian yang sama dan boleh mengakses satu sama lain. Juga, semak bahawa alamat dan port pelayan ditetapkan dengan betul dalam kod anda. Jika masalah berterusan, anda boleh cuba menggunakan alat penyahpepijatan rangkaian lain untuk menyemak isu sambungan, seperti Wireshark, dsb. Harap jawapan ini dapat membantu anda menyelesaikan masalah anda!

Kandungan soalan

Saya tidak tahu sama ada saya kehilangan sesuatu, kerana kotlin 代码没有找到 golang 套接字服务器。我做了一个 netstat -ano dan port 8000 saya sudah digunakan untuk tcp, jadi saya menganggap pelayan soket berfungsi dengan baik. Tetapi Android saya masih tidak menemuinya. Kedua-dua pelayan dan emulator berada pada rangkaian yang sama. Ini kod saya:

//Pelayan (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))
Salin selepas log masuk

// 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]}")
}
Salin selepas log masuk

Kemas kini:

Sebelum jawapan @dev.bmax, saya telah menemui beberapa maklumat tentang mendayakan cleartexttraffic dan sudah ada dalam saya androidmanifest.xml上添加了 android:usescleartexttraffic="true" ,但该应用程序仍然无法连接到服务器。 socket.connected() kini mengembalikan palsu.

Selain itu, bagaimanakah anda sepatutnya menyambung ke pelayan? Adakah saya hanya perlukan http://10.0.2.2:8000 tanpa sebarang laluan?

Kemas kini:

Saya baru perasan bahawa saya terus mendapat log seperti ini:

tagsocket(6) with statstag=0xffffffff, statsuid=-1
Salin selepas log masuk

Ia terus muncul di logcat

Kemas kini:

Saya melihat sekeliling untuk mencari kod lain dan mendapati kod yang berfungsi. Nasib baik atau malangnya, ia agak mudah. Ini kod yang saya jumpa:

//go language

listener, _ := net.listen("tcp", ":8000")
for {
    conn, _ := listener.accept()
    fmt.printf("%s --- %s\n", conn.localaddr(), conn.remoteaddr())
    io.writestring(conn, "welcome to socket")
}
Salin selepas log masuk

//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}")
    }
}
Salin selepas log masuk

Sekarang saya tertanya-tanya, mengapa kod barebones berfungsi tetapi kod yang disediakan oleh perpustakaan googollee tidak berfungsi? Saya tidak fikir saya terlepas sebarang persediaan di kedua-dua belah pihak.

Kemas kini:

Beberapa kemajuan telah dicapai. Ditemui android Kod berfungsi tetapi atas sebab tertentu sedang melaksanakan beberapa isu yang tidak dijangka. Berikut adalah butiran perubahan yang saya buat pada bahagian android:

// binaan aplikasi.gradle

implementation('io.socket:socket.io-client:0.8.3') {
    exclude group: 'org.json', module: 'json'
}
Salin selepas log masuk

//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}")
    }
}
Salin selepas log masuk

// androidmanifest.xml

android:usesCleartextTraffic="true"
//I used to have android:networkSecurityConfig="@xml/network_security_config" here as well
Salin selepas log masuk

Selepas melengkapkan perubahan ini, aplikasi kini boleh menyambung ke pelayan. Tetapi selepas menyambung, apl itu nampaknya terputus sambungan serta-merta. Kemudian ia menyambung ke pelayan sekali lagi, kemudian memutuskan sambungan lagi, kemudian menyambung ke pelayan, dan kitaran nampaknya tidak berhenti. Saya mendapat lated 客户端命名空间dis​​connect apabila memutuskan sambungan.

Penyelesaian

Saya akhirnya menemui bahagian yang membuat ini berfungsi. Saya fikir masalah terbesar adalah pada bahagian android. Menukar pustaka untuk digunakan nampaknya telah membetulkan semua isu, dan kemudian hanya perubahan kecil menyelesaikan isu putus sambungan serta-merta. Berikut ialah kod akhir dan butiran lain daripada kedua-dua pihak:

//go language

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))
}
Salin selepas log masuk

// Android kotlin

androidmanifest.xml

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

<application
    ...
    android:usescleartexttraffic="true">
Salin selepas log masuk

app-build.gradle

implementation('io.socket:socket.io-client:0.8.3') {
        exclude group: 'org.json', module: 'json'
    }
Salin selepas log masuk

// mainactivity.kt atau di mana sahaja anda nak letak kandungan ini

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()
    }
}
Salin selepas log masuk

Berkenaan putus sambungan serta-merta, nampaknya anda tidak perlu menambah /socket.io。删除它解决了断开连接的问题。而且您的项目中不需要 asset 文件夹。伙计,这个 socket.io apabila cuba menyambung di bahagian android.

Atas ialah kandungan terperinci Aplikasi Android tidak boleh menyambung ke pelayan socket.io Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan