Server
Tổng quan
Fountain cung cấp các cài đặt server đa giao thức dưới libs/fnet. Mỗi server triển khai vòng đời AppInstance (Initialize / Serving / Destroy) và được kết nối vào framework thông qua fountain.New().WithAppInstances(...).
Các server hiện có:
fhttp— HTTP server xây dựng trên Fiber, với routing, middleware và tùy chọn mã hóa payload.fgrpc— gRPC server với interceptor, metadata và tích hợp service discovery.ftcp— TCP server dạng raw và có wrap.fudp— UDP server.fquic— QUIC server hỗ trợ stream và datagram.
Ví dụ
Một gRPC server instance:
go
/* !!
* File: server.go
* File Created: Monday, 6th June 2022 10:07:23 am
* Author: Kim Ericko ([email protected])
* -----
* Last Modified: Monday, 6th June 2022 10:07:23 am
* Modified By: Kim Ericko ([email protected])
* -----
* Copyright 2022 Soludian, soludian.com
* All rights reserved.
*
* Licensed under the SOLUDIAN TECHNOLOGY SOLUTION CO., LTD Software License Agreement.
* Unauthorized use, reproduction, or distribution is prohibited (the "License");
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* [email protected] / https://www.soludian.com/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -----
*
* HISTORY:
*
* Date By Comments
* ---------- --- ---------------------------------------------------------
*/
package main
import (
"context"
"fmt"
"log"
"net"
"gitlab.soludian.com/soludian/fountain/examples/grpc/chat"
"google.golang.org/grpc"
)
func main() {
fmt.Println("Go gRPC Beginners Tutorial!")
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 9000))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := &ChatService{}
grpcServer := grpc.NewServer()
chat.RegisterChatServiceServer(grpcServer, s)
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %s", err)
}
}
type ChatService struct {
chat.UnimplementedChatServiceServer
}
func (s *ChatService) SayHello(ctx context.Context, req *chat.Message) (*chat.Message, error) {
log.Printf("Receive message body from client: %s", req.Body)
return &chat.Message{Body: "Hello From the Server!"}, nil
}Một HTTP server với mã hóa payload:
go
/* !!
* File: main.go
* File Created: Friday, 28th October 2022 5:19:38 pm
* Author: Kim Ericko ([email protected])
* -----
* Last Modified: Wednesday, 8th March 2023 4:40:18 pm
* Modified By: Kim Ericko ([email protected])
* -----
* Copyright 2022 Soludian, soludian.com
* All rights reserved.
*
* Licensed under the SOLUDIAN TECHNOLOGY SOLUTION CO., LTD Software License Agreement.
* Unauthorized use, reproduction, or distribution is prohibited (the "License");
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* [email protected] / https://www.soludian.com/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -----
*
* HISTORY:
*
* Date By Comments
* ---------- --- ---------------------------------------------------------
*/
package main
import (
"fmt"
"log"
"time"
"github.com/gofiber/fiber/v3"
"gitlab.soludian.com/soludian/fountain"
"gitlab.soludian.com/soludian/fountain/biz/core"
"gitlab.soludian.com/soludian/fountain/libs/base/lib_3rd"
"gitlab.soludian.com/soludian/fountain/libs/crypto"
"gitlab.soludian.com/soludian/fountain/libs/flog"
"gitlab.soludian.com/soludian/fountain/libs/fnet/fhttp"
)
var logger = flog.NewFountainLoggerOnce()
type NoModule struct {
}
func (NoModule) Liveness() bool {
return true
}
func (NoModule) Readiness() bool {
return false
}
type APIServer struct {
*fhttp.Server
}
func (s *APIServer) Initialize() error {
s.Server = fhttp.WithConfigKey("server.fhttp").InstallFountainInstance()
core.InstallCoreControllers()
cr := crypto.InstallFountainInstances()
log.Printf("Initializing: %+v", cr.GetFountainInstanceNames())
s.Server.Get("/panic", func(ctx fiber.Ctx) error {
err := fmt.Errorf("route panic")
logger.WErr(err).Panicf(err.Error())
return err
})
s.Server.Get("/200", func(ctx fiber.Ctx) error {
return ctx.SendString("hello")
})
s.Server.Get("/hello", func(ctx fiber.Ctx) error {
logger.Infof(ctx.Route().Path)
return ctx.JSON("Hello client: " + ctx.Get("app"))
})
s.Server.Get("/encrypt", func(ctx fiber.Ctx) error {
logger.Infof(ctx.Route().Path)
return fhttp.WithContext(ctx).WithEncryption().WithStatus(200).WriteSuccess("Hello client: " + ctx.Get("app"))
})
s.Server.Get("/encrypt-cbc", func(ctx fiber.Ctx) error {
data := make(map[string]any)
data["server"] = "encrypt-cbc"
data["time"] = time.Now().String()
logger.Infof(ctx.Route().Path)
return fhttp.WithContext(ctx).WithEncryptionFunc(crypto.GetFountainInstance("AES-CBC")).WithStatus(200).WriteSuccess(data)
})
s.Server.Get("/encrypt-ctr", func(ctx fiber.Ctx) error {
data := make(map[string]any)
data["server"] = "encrypt-ctr"
data["time"] = time.Now().String()
logger.Infof(ctx.Route().Path)
return fhttp.WithContext(ctx).WithEncryptionFunc(crypto.GetFountainInstance("AES-CTR")).WithStatus(200).WriteSuccess(data)
})
s.Server.Get("/500", func(ctx fiber.Ctx) error {
return ctx.Status(500).JSON("Hello client: " + ctx.Get("app"))
})
lib_3rd.RegisterHealthCheck("NoModule", &NoModule{})
s.Server.InitHealthCheckPath("/")
return nil
}
func main() {
server := &APIServer{}
fountain.WithAppInstances(server).Serving()
}