海量用户通讯系统-服务端结构改进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)

}

}

相关文章
|
网络协议 前端开发 测试技术
海量用户通讯系统——服务端结构改进1|学习笔记
快速学习海量用户通讯系统——服务端结构改进1
海量用户通讯系统——服务端结构改进1|学习笔记
|
网络协议 测试技术 Go
海量用户通讯系统——客户端结构改进1|学习笔记
快速学习海量用户通讯系统——客户端结构改进1
海量用户通讯系统——客户端结构改进1|学习笔记
|
缓存 JSON 网络协议
海量用户系统-客户端结构改进2|学习笔记
快速学习海量用户系统-客户端结构改进2
海量用户系统-客户端结构改进2|学习笔记
|
JSON 网络协议 测试技术
海量用户通讯系统-项目小结|学习笔记
快速学习海量用户通讯系统-项目小结
海量用户通讯系统-项目小结|学习笔记
|
JSON 网络协议 测试技术
海量用户通讯系统-服务器接收消息2|学习笔记
快速学习海量用户通讯系统-服务器接收消息2
海量用户通讯系统-服务器接收消息2|学习笔记
|
网络协议 测试技术 Go
海量用户通讯系统-收发消息分析|学习笔记
快速学习海量用户通讯系统-收发消息分析
海量用户通讯系统-收发消息分析|学习笔记
|
网络协议 测试技术 Go
海量用户通讯系统-服务器接收消息1
海量用户通讯系统-服务器接收消息1
海量用户通讯系统-服务器接收消息1
|
NoSQL 网络协议 关系型数据库
海量用户通讯系统-完成界面|学习笔记
快速学习海量用户通讯系统-完成界面
海量用户通讯系统-完成界面|学习笔记
|
JSON 编解码 网络协议
海量用户通讯信息-服务器接收长度|学习笔记
快速学习海量用户通讯信息-服务器接收长度
海量用户通讯信息-服务器接收长度|学习笔记
|
NoSQL 网络协议 测试技术
海量用户通讯系统-Redis 用户验证分析|学习笔记
快速学习海量用户通讯系统-Redis 用户验证分析
海量用户通讯系统-Redis 用户验证分析|学习笔记
下一篇
无影云桌面