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

news2024/11/25 1:44:10

项目地址

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

送奶APP开发:终极指南

您是否有兴趣使用新鲜牛奶和乳制品,但不想每天早上去乳制品店或最近的商店?借助技术,订购日常用品(例如杂货和牛奶)变得更加简单。 DailyMoo 是最受欢迎的送奶应用,收入达数百万人民币。因此,投…

vue门户设计器实现技术方案

一、什么是门户设计器 门户设计器是一种用于创建和设计门户网站或者应用系统首页的工具。它通常是一个软件应用程序,可以帮助用户快速、轻松地设计和构建自己的门户网站或者应用系统的首页。门户设计器通常提供在线拖拉拽设计器,以及各种模板、主题和组…

多项目同时跑多个node版本-比nvm好用的volta

开发环境中多个项目需要node版本不同,且同时不止是一个项目在开发中,用了nvm进行node版本管理和切换,但是太麻烦了。新的解决方案volta可以比较好的处理这种情况 Volta 官网先挂出来:https://volta.sh/ 1、volta是什么&#xff…

Paging-5G 寻呼

处于RRC_IDLE态的UE与网络之间是不存在RRC连接的,处于RRC_INACTIVE态的UE虽然与网络建立了RRC连接,但该连接是挂起的。当网络有下行数据需要发往处于RRC_IDLE或RRC_INACTIVE态的UE时,网络需要先通过Paging流程来寻呼UE,以通知该UE…

瑞芯微 rk3568的npu使用,部署unet网络

文章目录 rk3568-1.6.01.在任一个ubuntu系统上安装RKNN-Toolkit21.1 下载1.2 安装 2.在机器端(板端)查看 RKNPU2的驱动3.RKNN使用说明3.1 模型转换a. RHKNN初始化和释放b. RKNN configc. 加载模型d. 构建模型e. 导出模型f.转换工具 3.2 python 代码示例导…

VS Code配置Go语言开发环境

提示:首先这是一个新型语言,最好把vscode更新到最新版。 1:去官网下载Go语言编译器,之后配置到系统环境中,能看到版本就行。 2:创建一个文件夹,存放go的工具文件,我的在D:\GoFile\G…

引领半导体划片机行业,实现钛酸锶基片切割的卓越效能

在当今快速发展的半导体行业中,博捷芯以其卓越的技术实力和精准的行业应用,脱颖而出,再次引领行业潮流。这次,他们将先进的BJX3356划片机技术应用于钛酸锶基片的切割,为半导体制造行业的进一步发展提供了强大的技术支持…

Python爬虫全解析

一.爬虫--requests 1.常见的爬虫 -通用爬虫: 抓取系统重要组成部分。抓取的是一整张页面数据。 -聚焦爬虫: 是建立在通用爬虫的基础之上。抓取的是页面中特定的局部内容。 -增量式爬虫: 检测网站中数据更新的情况。只会抓取网站中最新更新出来的数据。 2.requests模块 re…

「数据结构」二叉树1

🎇个人主页:Ice_Sugar_7 🎇所属专栏:C启航 🎇欢迎点赞收藏加关注哦! 文章目录 🍉树🍉二叉树🍌特殊二叉树🍌二叉树的性质🍌存储结构 🍉…

通过层进行高效学习:探索深度神经网络中的层次稀疏表示

一、介绍 深度学习中的层次稀疏表示是人工智能领域日益重要的研究领域。本文将探讨分层稀疏表示的概念、它们在深度学习中的意义、应用、挑战和未来方向。 最大限度地提高人工智能的效率和性能:深度学习系统中分层稀疏表示的力量。 二、理解层次稀疏表示 分层稀疏表…

【Unity】运行时创建曲线(贝塞尔的运用)

[Unity]运行时创建线(贝塞尔的运用) 1. 实现的目标 在运行状态下创建一条可以使用贝塞尔方法实时编辑的网格曲线。 2. 原理介绍 2.1 曲线的创建 unity建立网格曲线可以参考Unity程序化网格体的实现方法。主要分为顶点,三角面&#xff0c…

22.JSP技术

JSP起源 在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变。如果使用Servlet程序来输出只有局部内容需要动态改变的网页,其中所有的静态内容也需要程序员用Java程序代码产生,整个Servlet程序的代码将…

智能优化算法应用:基于阿基米德优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于阿基米德优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于阿基米德优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.阿基米德优化算法4.实验参数设定…

智能 GPT 图书馆又重生了

智能 GPT 图书馆又重生了 作者:程序员小白条 1)概述 自从大二寒假准备开始筹备这个项目,到现在已经一年了,这个项目能维护一年,不愧是我.jpg。本来这个项目只是想练练手,因为那时候刚学完 Spring Boot2 V…

构建强大应用的引擎:深度解析Spring Boot Starter机制

目录 引言1. Spring Boot Starter机制1.1 什么是Spring Boot Starter1.2 为什么要使用Spring Boot Starter1.3.应用场景1.4.自动加载核心注解说明 2. 综合案例配置类制作控制功能实现 总结 引言 在当今互联网时代,构建高性能、可维护的应用已成为开发者的首要任务。…

Ansible自动化运维以及模块使用

ansible的作用: 远程操作主机功能 自动化运维(playbook剧本基于yaml格式书写) ansible是基于python开发的配置管理和应用部署工具。在自动化运维中,现在是异军突起 ansible能够批量配置、部署、管理上千台主机。类似于Xshell的一键输入工具。不需要每…

vscode如何开发微信小程序?(保姆级教学)

1.安装“微信小程序开发工具”扩展 2.安装“vscode weapp api”扩展 3.安装“vscode wxml”扩展 4.安装“vscode-wechat”扩展 5.在终端执行命令: vue create -p dcloudio/uni-preset-vue uniapp-test uniapp-test就是我这里的项目名称了 6.如果遇到了这个错误&a…

【C盘清理】Jetbrains全家桶(PyCharm、Clion……)更改 IDE 特定文件(配置、缓存、插件、日志等)存储位置

文章目录 一、官网说明二、更改 IDE 目录的位置1. 转到“帮助”|“编辑自定义属性”2. 各文件位置3. 以PyCharm系统目录为例4. 修改idea.properties 三、清理旧的 IDE 目录 一、官网说明 IDE 使用的目录官网说明 二、更改 IDE 目录的位置 默认情况下,PyCharm 将每…

c语言:输出26个英文字母|练习题

一、题目 分两排&#xff0c;输出26个英文字母 如图&#xff1a; 二、思路分析 1、从第13个字母分行显示 2、从A开始&#xff0c;在A的ASC码后面&#xff0c;按顺序加1~26 三、代码图片【带注释】 四、源代码【带注释】 #include <stdio.h> //题目:输入26个字母&#x…

企业电子招标采购系统源码Spring Cloud + Spring Boot + 前后端分离 + 二次开发

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…