我使用gRPC和protobuf构建了一个具有VueJS前端(客户端)和Go back(服务器)的简单Web应用程序。 为了进行通信,必须在它们之间建立一个特使代理,以将Web客户端HTTP / 1.1转换为HTTP / 2。 我在Linux上部署此应用程序没有任何问题,并且已经对这三项服务进行了Docker处理。
但是,我无法使我的服务在MacOS上进行通信。
可在以下位置找到应用程序存储库:https://github.com/42Projects/nPuzzle
deploy文件夹包含docker-compose文件,envoy容器所需的envoy.yaml文件以及所有三个dockerfile。
在MacOS上,envoy.yaml的最后一行需要更新,localhost
必须更改为host.docker.internal
。
客户端包含一个ping函数(位于client / src / App.vue中),可能需要将window.location.hostname更改为docker-machine IP,但不确定的是,我的尝试没有影响:>
created () {
this.client = new NpuzzleClient('http://' + window.location.hostname + ':8080', null, null);
const ping = () => {
let message = new Message();
message.setMessage('ping');
this.client.greets(message, {}, err => this.serverOnline = !err);
};
ping();
window.setInterval(ping, 1000);
},
每秒执行一次,并在右上角显示服务器已联机。到目前为止,在MacOS上进行部署时,我一直无法访问服务器。在Linux上可以正常工作。
这是go服务器的代码,我认为在localhost:9090上侦听是正确的,因为服务器将被docker化,但是我可能错了,可能需要更改地址。
package main
import (
"context"
"flag"
"fmt"
pb "github.com/42Projects/nPuzzle/proto"
npuzzle "github.com/42Projects/nPuzzle/src"
"google.golang.org/grpc"
"log"
"net"
"time"
)
var port = flag.Int("port", 9090, "the server port")
type server struct{}
func (s *server) Greets(ctx context.Context, message *pb.Message) (*pb.Message, error) {
return &pb.Message{Message: "pong!"}, nil
}
func (s *server) Parse(ctx context.Context, message *pb.Message) (*pb.Matrix, error) {
log.Printf("received parsing request: %#v", message.Message)
m, err := npuzzle.ParseMatrix(message.Message)
if err != nil {
log.Println(err)
return &pb.Matrix{
Success: false,
Error: err.Error(),
}, nil
}
rows := make([]*pb.Matrix_Row, len(m))
for index, row := range m {
/* We need unsigned 32bits integer for protobuf */
uIntRow := make([]uint32, len(m))
for rowIndex, num := range row {
uIntRow[rowIndex] = uint32(num)
}
rows[index] = &pb.Matrix_Row{Num: uIntRow}
}
return &pb.Matrix{
Success: true,
Rows: rows,
}, nil
}
func (s *server) Solve(ctx context.Context, problem *pb.Problem) (*pb.Result, error) {
/* Choose heuristic function */
var heuristic npuzzle.Heuristic
switch problem.Heuristic {
case "hamming":
heuristic = npuzzle.HammingDistance
case "manhattan":
heuristic = npuzzle.ManhattanDistance
case "manhattan + linear conflicts":
heuristic = npuzzle.ManhattanPlusLinearConflicts
}
/* Choose between greedy search and uniform-cost search */
var goal npuzzle.Goal
var search npuzzle.Search
switch problem.Search {
case "greedy":
goal = npuzzle.GreedyGoalReached
search = npuzzle.GreedySearch
case "uniform-cost":
goal = npuzzle.UniformCostGoalReached
search = npuzzle.UniformCostSearch
}
/* Convert protobuf unsigned 32bits integer to regular integer */
size := len(problem.Rows)
m := make(npuzzle.Matrix, size)
for y, row := range problem.Rows {
m[y] = make([]int, size)
for x, num := range row.Num {
m[y][x] = int(num)
}
}
log.Printf("received problem:\n - heuristic: %v\n - search: %v\n - matrix: %v\n", problem.Heuristic, problem.Search, m)
if npuzzle.IsSolvable(m) == false {
log.Println("failed to solve problem: unsolvable")
return &pb.Result{
Success: false,
Error: "unsolvable",
}, nil
}
begin := time.Now()
log.Printf("starting solve on %v...", m)
res, totalNumberOfStates, maxNumberOfStates, err := m.Solve(heuristic, search, goal, 30*time.Second)
if err != nil {
log.Printf("timed ouf after %v", 30*time.Second)
return &pb.Result{
Success: false,
Error: fmt.Sprintf("timed ouf after %v", 30*time.Second),
}, nil
}
duration := time.Since(begin)
log.Printf("solved %v in %v seconds", m, duration)
var path string
if res.Parent == nil {
path = "already solved!"
} else {
path = npuzzle.StringifyPath(res)
}
return &pb.Result{
Success: true,
Time: duration.String(),
Moves: int32(res.Cost),
TotalStates: int32(totalNumberOfStates),
MaxStates: int32(maxNumberOfStates),
Path: path,
}, nil
}
func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v\n", err)
}
s := grpc.NewServer()
pb.RegisterNpuzzleServer(s, &server{})
log.Printf("starting server on port %v\n", *port)
log.Fatalf("failed to serve: %v\n", s.Serve(lis))
}
我尝试在本地启动客户端和服务器,仅容器化envoy代理,同时尝试其他地址(我的docker机器IP地址和localhost),但是没有用。我也尝试启动所有三个容器,但在这里也都没有结果。 我不确定要成功进行哪些更改才能成功使我的应用在MacOS上正常运行。