Rumah >pembangunan bahagian belakang >Golang >Pelayan soket permulaan mengganggu komunikasi pelayan klien gRPC/http Golang
Saya mempunyai pelayan yang banyak berdasarkan tutorial ini. Selepas saya menggunakan perubahan tambahan padanya, ia berfungsi dengan baik. Tetapi sekarang setelah saya cuba menambahkan kod socket.io
,它现在遇到了一些问题。在测试我添加的 socket.io
padanya, ia nampaknya menjejaskan mekanisme yang menggunakan kod sebelah klien (titik akhir) memanggil kod sebelah pelayan (pertanyaan pangkalan data, pemprosesan). Apabila log panggilan titik akhir muncul pada terminal, panggilan itu sampai ke bahagian klien pelayan, tetapi ia nampaknya tidak memanggil bahagian pelayan.
Ini adalah kod untuk pelayan soket:
package helpers 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 startsocket() { 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("socket 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)) }
// main.go bahagian pelayan
package main import ( "flag" "fmt" "log" "net" pb "github.com/<me>/<project_name>/api/proto/out" "github.com/<me>/<project_name>/cmd/server/handlers" "github.com/<me>/<project_name>/cmd/server/helpers" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) func init() { helpers.databaseconnection() } var ( tls = flag.bool("tls", true, "connection uses tls if true, else plain tcp") certfile = flag.string("cert_file", "", "the tls cert file") keyfile = flag.string("key_file", "", "the tls key file") port = flag.int("port", 50051, "the server port") ) func main() { flag.parse() // helpers.startsocket() lis, err := net.listen("tcp", fmt.sprintf("localhost:%d", *port)) if err != nil { log.fatalf("failed to listen: %v", err) } var opts []grpc.serveroption if *tls { if *certfile == "" { *certfile = "service.pem" } if *keyfile == "" { *keyfile = "service.key" } creds, err := credentials.newservertlsfromfile(*certfile, *keyfile) if err != nil { log.fatalf("failed to generate credentials: %v", err) } opts = []grpc.serveroption{grpc.creds(creds)} } mserv := grpc.newserver(opts...) fmt.println("grpc server running ...") pb.registersomethingserviceserver(mserv, &handlers.somethingserver{}) log.printf("server listening at %v", lis.addr()) if err := mserv.serve(lis); err != nil { log.fatalf("failed to serve : %v", err) } }
// pelanggan utama.go
package main import ( "bytes" "encoding/json" "flag" "fmt" "log" "sort" "strings" "github.com/<me>/<project_name>/cmd/client/handlers" "github.com/gin-gonic/gin" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) var ( addr = flag.string("addr", "localhost:50051", "the address to connect to") ) func main() { flag.parse() creds, err := credentials.newclienttlsfromfile("service.pem", "") if err != nil { log.fatalf("could not process the credentials: %v", err) } conn, err := grpc.dial(*addr, grpc.withtransportcredentials(creds)) if err != nil { log.fatalf("did not connect: %v", err) } defer conn.close() var gingine = gin.default() startclient(conn, gingine) } func startclient(conn *grpc.clientconn, gingine *gin.engine) { handlers.somethingapihandler(conn, gingine) gingine.run(":5000") }
Untuk kod klien dan pelayan yang lengkap, anda boleh lihat tutorial yang saya pautkan di atas. Jika saya tidak menghubungi startsocket()
, semuanya berfungsi dengan baik.
Apabila memanggil titik akhir api, saya mendapat ralat ini, yang ditimbulkan oleh kod yang memanggil kod sebelah pelayan:
"rpc error: code = unavailable desc = connection error: desc = "transport: error while dialing: dial tcp [::1]:50051: connectex: no connection could be made because the target machine actively refused it.""
Kod adalah seperti berikut:
ginGine.POST("/account/login", func(ctx *gin.Context) { var account models.Account err := ctx.ShouldBind(&account) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{ "error1": err.Error(), }) return } res, err := srvClient.service.ValidateAccount(ctx, &pb.ValidateAccountRequest{ Account: &pb.Account{ Id: account.ID, FirstName: account.FirstName, LastName: account.LastName, UserName: account.UserName, Password: account.Password, }, }) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{ "error2": err.Error(), }) return } ctx.JSON(http.StatusOK, gin.H{ "status": res.Status, "access_token": res.AccessToken, }) })
error2 ialah apa yang dipulangkan oleh panggilan api
Baris kod ini menyekat, fungsi StartSocket()
tidak akan kembali:
fmt.Print(http.ListenAndServe(":8000", nil))
Untuk ujian, anda boleh menambah log selepasnya dan mesej log tidak akan dicetak.
Anda perlu menjalankannya dalam goroutine tanpa sekat yang berasingan StartSocket()
.
P.S. Sebagai contoh, baris ini ialah log.Fatal(http.ListenAndServe(":8000", nil))
. Kod anda menelan ralat.
Atas ialah kandungan terperinci Pelayan soket permulaan mengganggu komunikasi pelayan klien gRPC/http Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!