我有一个服务器,很大程度上是基于这tutorial.在我对其应用了额外的更改后,它工作正常.但现在我正试着给它加socket.io
,它现在出现了一些问题.在测试我为socket.io
添加的代码后,它似乎影响了使客户端代码(端点)调用服务器端代码(数据库查询、处理)的机制.当终端上出现端点呼叫的日志(log)时,呼叫到达服务器的客户端,但它似乎没有呼叫服务器端.
以下是套接字服务器的代码:
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服务器端
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)
}
}
//main.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")
}
有关完整的客户端和服务器代码,您可以查看我上面链接的教程.如果我不拨打StartSocket()
,一切都会好的.
在调用我的API的AN终结点时,我收到了这个错误,它是由调用服务器端代码的代码引发的:
"RPC错误:代码=不可用描述=连接错误:描述= "传输:拨号时出错:拨号tcp[::1]:50051:ConnectEx:no 由于目标计算机主动拒绝,因此可以建立连接 它.""
代码如下所示:
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是API调用返回的内容