Pelayan soket permulaan mengganggu komunikasi pelayan klien gRPC/http Golang

PHPz
Lepaskan: 2024-02-05 23:30:07
ke hadapan
1218 orang telah melayarinya

启动套接字服务器会干扰 gRPC/http 客户端服务器通信 Golang

Kandungan soalan

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

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

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

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.""
Salin selepas log masuk

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

error2 ialah apa yang dipulangkan oleh panggilan api


Jawapan betul


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!

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
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!