无框架Java转go语言写http与tcp请求

2023-12-18 18:24:58

项目地址

https://github.com/cmdch2017/http_tcpServer

项目结构

在这里插入图片描述

如何快速上手

http篇

1、controller包就相当于@RestController,这里返回了一个Person对象,当你需要新建一个接口时,再新写一个func仿照下面的方法就行了

package controller

import (
	"net/http"
	"testproject12/common"
	"testproject12/entity"
	"testproject12/util"
)

// PersonHandler 无入参,返回person类
func PersonHandler(w http.ResponseWriter, r *http.Request) {
	// 创建一个Person对象
	person := entity.Person{
		Name:  "John Doe",
		Age:   30,
		Title: "Software Engineer",
	}
	messageHex := "FFFFFF"
	util.SendHexMessageToAllUser(messageHex)
	// 封装为JSON格式的CommonResult并写入响应体
	common.WriteJSONResponse(w, http.StatusOK, common.DefaultSuccessMsg, person)
}

2、router.go负责配置路由,下面的代码中,server.AddRoute的key相当于@RequestMapping(“/person”),value是上面文件在controller包下,方法是PersonHandler

package router

import (
	"testproject12/controller"
	"testproject12/httpServer"
)

func SetupRoutes(server *httpServer.HTTPServer) {
	// 添加路由
	server.AddRoute("/person", controller.PersonHandler)
	// Add more routes as needed
}

在这里插入图片描述

tcp篇

用SocketTool新建一个客户端
在这里插入图片描述
在这里插入图片描述
http://localhost:8080/person
在这里插入图片描述
服务器收到数据FFFFFF
在这里插入图片描述

总结

实现了http请求与tcp请求,如果有需要的话请fork我的github代码

性能

在这里插入图片描述

附录

完整代码

package common

import (
	"encoding/json"
	"fmt"
	"net/http"
)

// Constants for CommonResult keys
const (
	CodeTag = "code"
	MsgTag  = "msg"
	DataTag = "data"
)

// Default success and failure messages
const (
	DefaultSuccessMsg = "操作成功"
	DefaultFailedMsg  = "操作失败"
)

// CommonResult creates a new CommonResult object with the given code and message
func CommonResult(code int, msg string) map[string]interface{} {
	return map[string]interface{}{
		CodeTag: code,
		MsgTag:  msg,
	}
}

func CommonResultWithData(code int, msg string, data interface{}) map[string]interface{} {
	result := CommonResult(code, msg)
	if data != nil {
		result[DataTag] = data
	}
	return result
}

// Success returns a CommonResult representing success with an optional data payload
func Success(data ...interface{}) map[string]interface{} {
	result := CommonResult(HttpStatusSuccess, DefaultSuccessMsg)
	if len(data) > 0 {
		result[DataTag] = data[0]
	}
	return result
}

// Error returns a CommonResult representing an error with an optional data payload
func Error(msg string, data ...interface{}) map[string]interface{} {
	result := CommonResult(HttpStatusError, msg)
	if len(data) > 0 {
		result[DataTag] = data[0]
	}
	return result
}

// HttpStatus constants
const (
	HttpStatusSuccess = iota
	HttpStatusError
)

func WriteJSONResponse(w http.ResponseWriter, code int, msg string, data interface{}) {
	// 创建一个CommonResult并将数据放入其中
	result := CommonResultWithData(code, msg, data)

	// 将CommonResult对象序列化为JSON格式的字符串
	resultData, err := json.Marshal(result)
	if err != nil {
		fmt.Println("json格式化错误")
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}

	// 设置响应头为JSON格式
	w.Header().Set("Content-Type", "application/json")

	// 将JSON数据写入响应体
	w.Write(resultData)
}

package controller

import (
	"net/http"
	"testproject12/common"
	"testproject12/entity"
	"testproject12/util"
)

// PersonHandler 无入参,返回person类
func PersonHandler(w http.ResponseWriter, r *http.Request) {
	// 创建一个Person对象
	person := entity.Person{
		Name:  "John Doe",
		Age:   30,
		Title: "Software Engineer",
	}
	messageHex := "FFFFFF"
	util.SendHexMessageToAllUser(messageHex)
	// 封装为JSON格式的CommonResult并写入响应体
	common.WriteJSONResponse(w, http.StatusOK, common.DefaultSuccessMsg, person)
}

package entity

import "net"

type ClientInfo struct {
	Conn net.Conn
}

package entity

type Person struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Title string `json:"title"`
}

package httpServer

import (
	"fmt"
	"net/http"
)

// HTTPServer represents an HTTP tcpserver
type HTTPServer struct {
	routes map[string]http.HandlerFunc
}

// NewHTTPServer creates a new HTTPServer instance
func NewHTTPServer() *HTTPServer {
	return &HTTPServer{
		routes: make(map[string]http.HandlerFunc),
	}
}

// AddRoute adds a new route to the HTTP tcpserver
func (s *HTTPServer) AddRoute(path string, handler http.HandlerFunc) {
	s.routes[path] = handler
}

// RunHTTPServer starts the HTTP tcpserver and sets up the routes
func (s *HTTPServer) RunHTTPServer() {
	for path, handler := range s.routes {
		// 添加http路由
		http.HandleFunc(path, handler)
	}

	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		fmt.Println("HTTP服务器启动失败:", err)
	}
}

package main

import (
	"testproject12/httpServer"
	"testproject12/router"
	"testproject12/tcpserver"
)

func main() {
	// 创建并运行TCP服务器
	go tcpserver.NewServer().RunTCPServer()
	// 创建HTTP服务器
	httpserver := httpServer.NewHTTPServer()

	// 设置路由
	router.SetupRoutes(httpserver)

	// 启动HTTP服务器
	go httpserver.RunHTTPServer()
	select {}
}

package router

import (
	"testproject12/controller"
	"testproject12/httpServer"
)

func SetupRoutes(server *httpServer.HTTPServer) {
	// 添加路由
	server.AddRoute("/person", controller.PersonHandler)
	// Add more routes as needed
}

package tcpserver

import (
	"encoding/hex"
	"fmt"
	"net"
	"sync"
	"testproject12/entity"
)

// 所有用户信息
var AllConnectionList []net.Conn

// Server 服务端结构体
type Server struct {
	Clients map[string]entity.ClientInfo
	Mutex   sync.Mutex
}

// NewServer creates a new Server instance
func NewServer() *Server {
	return &Server{
		Clients: make(map[string]entity.ClientInfo),
	}
}
func SendHexMessage(conn net.Conn, hexMessage string) error {
	messageBytes, err := hex.DecodeString(hexMessage)
	if err != nil {
		fmt.Println("转换错误", err)
		return err
	}

	_, err = conn.Write(messageBytes)
	if err != nil {
		fmt.Println("发送消息失败", err)
		return err
	}

	return nil
}

// RemoveConnection removes a connection from AllConnectionList
func RemoveConnection(conn net.Conn) {
	for i, c := range AllConnectionList {
		if c == conn {
			AllConnectionList = append(AllConnectionList[:i], AllConnectionList[i+1:]...)
			break
		}
	}
}

// RunTCPServer starts the TCP tcpserver
func (s *Server) RunTCPServer() {
	fmt.Println("服务端启动了")

	listen, err := net.Listen("tcp", "0.0.0.0:8888")
	if err != nil {
		fmt.Println("监听失败", err)
		return
	}

	// 循环等待客户端的连接
	for {
		conn, err := listen.Accept()
		if err != nil {
			fmt.Println("客户端的等待失败", err)
			return
		} else {
			fmt.Printf("等待连接成功:,con=%v,接受到的客户端信息:%v \n", conn, conn.RemoteAddr().String())
			// 服务端主动发送消息给客户端
			messageHex := "48656c6c6f2066726f6d20736572766572" // "Hello from tcpserver" 的十六进制表示
			SendHexMessage(conn, messageHex)
		}

		// 处理客户端连接的协程
		go s.handleClient(conn)
	}
}

// 处理客户端连接
func (s *Server) handleClient(conn net.Conn) {
	defer conn.Close()

	// 获取客户端地址
	clientAddr := conn.RemoteAddr().String()

	// 将客户端信息存储到 map 中
	s.Mutex.Lock()
	s.Clients[clientAddr] = entity.ClientInfo{
		Conn: conn, // 存储客户端连接对象
	}
	AllConnectionList = append(AllConnectionList, conn)
	s.Mutex.Unlock()

	// 处理客户端消息
	for {
		buf := make([]byte, 1024)
		n, err := conn.Read(buf)
		if err != nil {
			break
		}

		// 处理接收到的消息
		hexData := hex.EncodeToString(buf[:n])
		fmt.Println("收到客户端消息:", clientAddr, ":", hexData)
	}

	// 客户端断开连接,从 map 中移除该用户
	s.Mutex.Lock()
	delete(s.Clients, clientAddr)
	RemoveConnection(conn)
	s.Mutex.Unlock()

	fmt.Println("客户端断开连接:", clientAddr)
}

package util

import (
	"encoding/hex"
	"testproject12/tcpserver"
)

// SendHexMessage 发送十六进制消息

// SendHexMessageToAllUser 广播发送十六进制消息
func SendHexMessageToAllUser(message string) {
	messageHex := hex.EncodeToString([]byte(message))
	for _, conn := range tcpserver.AllConnectionList {
		tcpserver.SendHexMessage(conn, messageHex)
	}
}

Dockerfile

# Use the official Golang image as the base image
FROM golang:1.21-alpine

# Set the working directory inside the container
WORKDIR /go/src/app

# Copy the contents of the current directory to the working directory inside the container
COPY . .

# Build the Go application
RUN go build -o abc ./main

# Add executable permission to the main binary
RUN chmod +x ./abc

# Expose the port the application runs on
EXPOSE 8888 8080

# Define the command to run the application
CMD ["./abc"]

go.mod

module testproject12

go 1.21.4

文章来源:https://blog.csdn.net/weixin_43914278/article/details/135065187
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。