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

项目地址

https://github.com/cmdch2017/http_tcpServer

项目结构

在这里插入图片描述

如何快速上手

http篇

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

package controllerimport ("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 routerimport ("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 commonimport ("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 = iotaHttpStatusError
)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 controllerimport ("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 entityimport "net"type ClientInfo struct {Conn net.Conn
}
package entitytype Person struct {Name  string `json:"name"`Age   int    `json:"age"`Title string `json:"title"`
}
package httpServerimport ("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 mainimport ("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 routerimport ("testproject12/controller""testproject12/httpServer"
)func SetupRoutes(server *httpServer.HTTPServer) {// 添加路由server.AddRoute("/person", controller.PersonHandler)// Add more routes as needed
}
package tcpserverimport ("encoding/hex""fmt""net""sync""testproject12/entity"
)// 所有用户信息
var AllConnectionList []net.Conn// Server 服务端结构体
type Server struct {Clients map[string]entity.ClientInfoMutex   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 utilimport ("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 testproject12go 1.21.4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/220517.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创建型模式之抽象工厂模式

一、概述 1、抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 2、抽象工厂模式:一个工厂可以生产一系列产品(一族产品),极大减少了工厂类的数量 3、抽象工厂模式&am…

SpringBoot配置mysql加密之Druid方式

一、导入Druid依赖 <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.22</version> </dependency>二、生成密文 方式1. 找到存放druid jar包的目录 1-1、在目录…

局域网其他pc如何访问宿主机虚拟机IP?

文章目录 背景贝瑞蒲公英设置虚拟机网络连接测试 背景 使用贝瑞蒲公英异地组网&#xff0c;将家里的pc作为pgsql服务器在公司使用&#xff0c;但是虚拟机的ip和端口访问不了 贝瑞蒲公英 设置虚拟机网络 就是添加端口转发规则 连接测试 公网内其他pc连接测试 可以看到已经连接成…

教你玩转Shopify独立站!六招运营技巧不可错过

作为一个新手卖家&#xff0c;想要在 Shopify 上运营自己的独立站&#xff0c;可能会感到有些困惑。不过&#xff0c;只要掌握了一些技巧&#xff0c;就可以轻松上手。今天就为大家介绍六个运营 Shopify 独立站的技巧&#xff0c;帮助大家更好玩转 Shopify 独立站&#xff01; …

隐私计算介绍

这里只对隐私计算做一些概念性的浅显介绍&#xff0c;作为入门了解即可 目录 隐私计算概述隐私计算概念隐私计算背景国外各个国家和地区纷纷出台了围绕数据使用和保护的公共政策国内近年来也出台了数据安全、隐私和使用相关的政策法规 隐私计算技术发展 隐私计算技术安全多方计…

【vSphere | PowerCLI】使用 PowerCLI 连接 vCenter 查看 VM 故障排错

这里写目录标题 1. 连接vCenter Server2. 客户机操作系统内提供网络配置信息3. 创建VM4. 迁移VM5.故障排错连接 VC 报错&#xff1a; Error: Invalid server certificate解决方法 参考资料 1. 连接vCenter Server PS C:\Users\Administrator> Connect-VIServer 192.168.1.1…

Kubernetes (k8s) 快速认知

应用部署方式 传统部署时代 早期的时候&#xff0c;各个组织是在物理服务器上运行应用程序。缺点 资源分配问题&#xff1a; 无法限制在物理服务器中运行的应用程序资源使用 维护成本问题&#xff1a; 部署多个物理机&#xff0c;维护许多物理服务器的成本很高 虚拟化部署时…

【Qt之Quick模块】1. 概述及Quick应用程序创建流程

概述 Qt的Quick模块是用于创建现代化、动态和响应式用户界面的工具集。它是基于QML&#xff08;Qt Meta-Object Language&#xff09;和JavaScript的。 QML是一种声明性的语言&#xff0c;用于描述用户界面的结构和行为。它使用层叠样式表&#xff08;CSS&#xff09;的语法来…

轻量化压缩之【剪枝】

在深度学习领域&#xff0c;剪枝是一种常用的模型轻量化技术&#xff0c;主要是通过移除神经网络中被认为不重要的连接&#xff08;即权重&#xff09;来减少模型的大小和计算量。移除的连接可以是单独的权重&#xff08;非结构化剪枝&#xff09;&#xff0c;也可以是整个神经…

RabbitMQ入门案例

RabbitMQ 是目前比较主流的MQ消息队列中间件&#xff0c;下面简单总结RabbitMQ入门时所做的一些笔记 1.RabbitMQ 入门案例 需求&#xff1a;用 Java 编写两个程序。发送单个消息的生产者和接收消息并打印出来的消费者 1.1 添加依赖 <!--rabbitmq 依赖客户端--> <de…

美颜SDK是什么?视频美颜SDK在直播平台中的集成与接入教程详解

当下&#xff0c;主播们追求更加自然、精致的外观&#xff0c;而观众也期待在屏幕前欣赏到更为清晰、美丽的画面。为了满足这一需求&#xff0c;美颜SDK应运而生&#xff0c;成为直播平台的重要利器之一。 一、什么是美颜SDK&#xff1f; 通过美颜SDK&#xff0c;开发者可以…

三菱PLC FX3U滑动平均值滤波

三菱PLC滑动平均值滤波其它相关写法,请参考下面文章链接: https://rxxw-control.blog.csdn.net/article/details/125044013https://rxxw-control.blog.csdn.net/article/details/125044013滑动平均值滤波程序总共分为三部分,第一步为:滑动采样。 第二步为:队列求和,第三…

最强笔记生成AI —— NotionAI

NotionAI是Notion推出的一款革命性AI工具&#xff0c;它正通过利用其先进的AI技术来扩大用户群。这款强大的生成式AI工具能够帮助用户完成笔记总结、识别会议中的行动项&#xff0c;并创建和修改文本。NotionAI通过自动化枯燥的任务、为用户提供建议和模板&#xff0c;极大地简…

深度学习模型轻量化方法介绍

深度学习模型轻量化是指通过一系列技术手段减少模型的大小和计算需求&#xff0c;使其能够在资源有限的环境中&#xff08;如移动设备、嵌入式系统&#xff09;运行。下面是一些常见的模型轻量化方法&#xff1a; 模型剪枝&#xff08;Pruning&#xff09;: 描述: 模型剪枝涉及…

【Java异常】idea 报错:无效的目标发行版:17 的解决办法

【Java异常】idea 报错&#xff1a;无效的目标发行版&#xff1a;17 的解决办法 一&#xff0c;问题来源 springcloud的第一个demo项目就给我干趴了 二、原因分析 java: 无效的目标发行版: 17 原因就是 JDK 版本不对。从 IDEA 编辑器中可以找到问题的原因所在&#xff0c;…

Axure之交互与情节与一些实例

目录 一.交互与情节简介 二.ERP登录页到主页的跳转 三.ERP的菜单跳转到各个页面的跳转 四.省市联动 五.手机下拉加载 今天就到这里了&#xff0c;希望帮到你哦&#xff01;&#xff01;&#xff01; 一.交互与情节简介 "交互"通常指的是人与人、人与计算机或物体…

卷积层里的填充和步幅(padding和strides)

目录 一、填充和步幅相关概念 1、填充(padding) 2、步幅(strides) 3、总结 二、代码实现 1、填充(padding) 2、步幅(strides) 3、小结 一、填充和步幅相关概念 1、填充(padding) 当输入图片比较小的时候&#xff0c;我们一般会进行填充&#xff0c;填充是指在输入周围…

【TB作品】STM32 PWM之实现呼吸灯,STM32F103RCT6,晨启

文章目录 完整工程参考资料实验过程 实验任务&#xff1a; 1&#xff1a;实现PWM呼吸灯&#xff0c;定时器产生PWM&#xff0c;控制实验板上的LED灯亮灭&#xff1b; 2&#xff1a;通过任意两个按键切换PWM呼吸灯输出到两个不同的LED灯&#xff0c;实现亮灭效果&#xff1b; 3&…

Flink系列之:自定义函数

Flink系列之&#xff1a;自定义函数 一、自定义函数二、概述三、开发指南四、函数类五、求值方法六、类型推导七、自动类型推导八、定制类型推导九、确定性十、内置函数的确定性十一、运行时集成十二、标量函数十三、表值函数十四、聚合函数十五、表值聚合函数 一、自定义函数 …

【EI会议征稿通知】第三届区块链、信息技术与智慧金融国际学术会议 (ICBIS2024)

第三届区块链、信息技术与智慧金融国际学术会议 (ICBIS2024) The 3rd International Academic Conference on Blockchain, Information Technology and Smart Finance 第三届区块链、信息技术与智慧金融国际学术会议 (ICBIS2024) 将于2024年2月23-25日在马来西亚举行。本次会…