海量用户通讯系统-服务端结构改进2|学习笔记

简介: 快速学习海量用户通讯系统-服务端结构改进2

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:海量用户通讯系统——服务端结构改进2】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/626/detail/9804


海量用户通讯系统-服务端结构改进2

 

一、更改方法

1、步骤:

(1)首先把分析出来的文件创建好,然后放入相应的文件夹中(实际就是包,因为在Go里面文件夹就体现一种包,因为一般来说一个文件夹就对应一个包)

(2) 现在根据各个文件,完成的任务不同,将 main.go 的文件剥离到对应的文件中即可

(3) 先修改了 utils/utils.go

package utils

Import (

“fmt”

“net”

“go_code/chatroom/common/message

“encoding/binary”

“encoding/json”

)

//这里将这些方法关联到结构体中

type Transfer struct {

//分析它应该有哪些字段

conn net.conn

Buf [8096]byte //这时传输时,使用缓冲

}

func (this *Transfer) ReadPkg() (mes message.Message, err error)  {

//buf :=make([ ]byte, 8096)

fmt.PrintIn(“读取客户端发送的数据”)

//conn.Read 在conn没有被关闭的情况下才会阻塞

//如果客户端关闭了 conn 则,就不会阻塞

_,err  =  this.conn.Read(this.Buf[:4])

If err != nil {

//err = errors.New(“read pkg header error”)

return

}

//根据buf[:4] 转成一个 uint32类型

var pkgLen uint32

pkgLen =binary.BigEndian.uint32(this.Buf[0:4])

//根据 pkgLen 读取消息内容

n, err :=this.Conn.Read(this.Buf[ :pkgLen])

if n != int(pkgLen) II err != nil {

//err  =  errors.New(“read pkg body error”)

return

}

//把pkgLen 反序列化成 ->  message.Message

//技术就是一层窗户纸 &mes! !

err  =  json.Unmarsha1(this.Buf[:pkgLen],  &mes)

if err !=  nil  {

fmt.PrintIn(“json.Unmarsha err”, err)

return

}

return

}

func (this *Transfer) writePkg(data [ ]byte) (err error) {

//先发送一个长度给对方

var pkgLen uint32

pkgLen = uint32(len(data))

//var buf [4]byte

binary.BigEndian.PutUint32(this.Buf[0:4], pkgLen)

//发送长度

n, err : = this.conn.write(this.Buf[:4])

if n != 4 | | err != nil {

fmt.PrintIn(“conn.write(bytes) fail”,err)

return

}

//发送data本身

n, err = this.Conn.write(data)

if n != int(pkgLen) | | err != nil {

fmt.PrintIn(“conn.write(bytes) fail”, err)

return

}

return

}

(4) 修改了process2/userprocess.go

package process2

Import (

“fmt”

“net”

“go_code/chatroom/common/message”

“go_code/chatroom/server/utils”

“encoding/json”

)

type Userprocess struct {

//字段

Conn net.Conn

//

}

//编写一个函数serverProcessLogin函数,专门处理登录请求

fanc (this *UserProcess) ServerProcessLogin(mes *message.Messsage) (err errror) {

//核心代码

//1. 先从mes中取出 mes . Data ,并直接反序列化成LoginMes

var loginMes message.LoginMes

err = json.Unmarshal([ ]byte(mes.Data), &loginMes)

if err != nil {

fmt.PrintIn(“json.Unmarshal err=”, err)

return

}

//1先声明一个 resMes

var resMes message.Message

resMes.Type = message.LoginResMesType

//2先声明一个 LoginResMes,并完成赋值

var loginResMes message.LoginResMes

//如果用户id= 100,密码=123456, 认为合法,否则不合法

if loginMes.UserId == 100 && loginMes.UserPwd ==”12345” {

//合法

loginResMes.Code = 200

} else {

//不合法

loginResMes.Code =500 // 500 状态码,表示该用户不存在

loginResMes.Error = “该用户不存在,请注册后再使用...”

}

//3将 loginResMes 序列化

data, err := json.Marshal(loginResMes)

If err != nil {

fmt.PrintIn(“json.Marshal fail”, err)

return

}

//4. 将data 赋值给resMes

resMes.Data = string(data)

//5. 对resMes 进行序列化,准备发送

data,err = json.Marshal(resMes)

if err != nil {

fmt.PrintIn(“json,Marshal fail”,err)

return

}

//6. 发送data,我们将其装到writePkg函数

//因为使用分层模式(mvc),我们先创建一个Transfer 实例,然后读取

tf := &utils.Transfer {

Conn : this.Conn,

}

err = tf.writePkg(data)

return

}

(5) 修改了 main/processor.go

package main

Import (

“fmt”

“net”

“go_code/chatroom/common/message”

“go_code/chatroom/server/utils”

“go_code/chatroom/server/process”

“io”

)

//先创建一个 Processor 的结构体

type Processor struct {

Conn

}

//编写一个serverProcessMes 函数

//功能: 根据客户端发送消息种类不同,决定调用那个函数来处理

fanc (this *Processor) serverProcessMes(mes *message.Message) (err error) {

switch mes.Type {

case message.LoginMesType :

//处理登录登录

//创建一个UserProcess实例

up := &process2.UserProcess{

Conn : this.Conn,

}

err = up.ServerProcessLogin(mes)

case message.RegisterMesType

//处理注册

default :

Fmt.PrintIn(“消息类型不存在,无法处理...”)

}

Return

}

func (this *Processor) process2() (err error) {

//循环的客户端发生的消息

for {

//这里我们将读取数据包,直接封装成一个函数readPkg( ),返回Message, err

//创建一个Transfer 实例完成读包任务

tf := &utils.Transfer{

Conn : this.Conn,

}

mes, err := tf.ReadPkg( )

if err != nil {

fmt.PrintIn(“客户端退出,服务端也退出..”)

return

}

}

err = this.serverProcessMes(&mes)

if err != nil {

return err

}

}

}

(5) 修改了main/main.go

//处理和客户端的通讯

fanc process(conn net.conn) {

//这里需要延时关闭conn

defer conn.Close( )

//这里调用监控,创建一个

processsor := &Processor{

conn : conn,

}

err := processor.process( )

if err != nil {

fmt.PrintIn(“客户端和服务器通讯承认协程错误=err”, err)

}

}

相关文章
|
2天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
4天前
|
云安全 数据采集 人工智能
古茗联名引爆全网,阿里云三层防护助力对抗黑产
阿里云三层校验+风险识别,为古茗每一杯奶茶保驾护航!
古茗联名引爆全网,阿里云三层防护助力对抗黑产
|
4天前
|
存储 机器学习/深度学习 人工智能
大模型微调技术:LoRA原理与实践
本文深入解析大语言模型微调中的关键技术——低秩自适应(LoRA)。通过分析全参数微调的计算瓶颈,详细阐述LoRA的数学原理、实现机制和优势特点。文章包含完整的PyTorch实现代码、性能对比实验以及实际应用场景,为开发者提供高效微调大模型的实践指南。
537 2
kde
|
4天前
|
人工智能 关系型数据库 PostgreSQL
n8n Docker 部署手册
n8n是一款开源工作流自动化平台,支持低代码与可编程模式,集成400+服务节点,原生支持AI与API连接,可自托管部署,助力团队构建安全高效的自动化流程。
kde
362 3
|
2天前
|
Linux 虚拟化 iOS开发
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
754 4
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
|
3天前
|
JavaScript 开发工具 Android开发
如何在原生 App 中调用 Uniapp 的页面?
如何在原生 App 中调用 Uniapp 的页面?
243 138
|
4天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段四:学术分析 AI 项目 RAG 落地指南:基于 Spring AI 的本地与阿里云知识库实践
本文介绍RAG(检索增强生成)技术,结合Spring AI与本地及云知识库实现学术分析AI应用,利用阿里云Qwen-Plus模型提升回答准确性与可信度。
254 91
AI 超级智能体全栈项目阶段四:学术分析 AI 项目 RAG 落地指南:基于 Spring AI 的本地与阿里云知识库实践