Heim > Backend-Entwicklung > Golang > Das Starten des Socket-Servers stört die gRPC/http-Client-Server-Kommunikation Golang

Das Starten des Socket-Servers stört die gRPC/http-Client-Server-Kommunikation Golang

PHPz
Freigeben: 2024-02-05 23:30:07
nach vorne
1282 Leute haben es durchsucht

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

Frageninhalt

Ich habe einen Server, der stark auf diesem Tutorial basiert. Nachdem ich weitere Änderungen vorgenommen hatte, funktionierte es einwandfrei. Aber jetzt, wo ich versucht habe, socket.io ,它现在遇到了一些问题。在测试我添加的 socket.io Code hinzuzufügen, scheint es den Mechanismus zu beeinflussen, durch den clientseitiger Code (Endpunkte) serverseitigen Code aufruft (Datenbankabfragen, Verarbeitung). Wenn das Protokoll des Endpunktanrufs auf dem Terminal angezeigt wird, erreicht der Anruf die Clientseite des Servers, ruft jedoch anscheinend nicht die Serverseite auf.

Dies ist der Code für den Socket-Server:

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))
}
Nach dem Login kopieren

// main.go serverseitig

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)
    }
}
Nach dem Login kopieren

// main.go-Client

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")
}
Nach dem Login kopieren

Den vollständigen Client- und Servercode finden Sie in dem Tutorial, das ich oben verlinkt habe. Wenn ich nicht anrufe startsocket(), funktioniert alles einwandfrei.

Beim Aufrufen des API-Endpunkts erhalte ich diesen Fehler, der durch den Code ausgelöst wird, der den serverseitigen Code aufruft:

"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.""
Nach dem Login kopieren

Der Code lautet wie folgt:

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,
    })
})
Nach dem Login kopieren

error2 ist das, was der API-Aufruf zurückgibt


Richtige Antwort


Diese Codezeile blockiert, die Funktion StartSocket() wird niemals zurückkehren:

fmt.Print(http.ListenAndServe(":8000", nil))

Zu Testzwecken können Sie danach ein Protokoll hinzufügen. Die Protokollmeldung wird dann nicht gedruckt.

Sie müssen es in einer separaten, nicht blockierenden Goroutine ausführen StartSocket().

P.S. Diese Zeile ist zum Beispiel log.Fatal(http.ListenAndServe(":8000", nil)). Ihr Code hat einen Fehler verschluckt.

Das obige ist der detaillierte Inhalt vonDas Starten des Socket-Servers stört die gRPC/http-Client-Server-Kommunikation Golang. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage