开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:客户端发消息代码实现】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9821
客户端发消息代码实现
内容介绍
一、 新增结构体
二、 实际运用
三、 代码总结
一、新增结构体
先将新增的两个结构体完成,分别是 SmsMes 和 CurUser.
1、SmsMes
在 message.go 中继续写
//增加一个 SmsMe //发送的消息
type SmsMes struct {
Content string ‘json:”content”’//内容
User //匿名结构体,继承
将 SmsMes 增加进去
在 const 的最后一行添加
SmsMesType =“SmsMes”
// SmsReMes 有些服务器拿到消息后会进行一定的过滤或增加一些东西,比如服务器发现群发消息有些敏感词汇,可能会被替换成*。不仅客户端可以做,服务器也要做。例如在qq发送消息中包含敏感词汇,对方收到的消息中敏感词汇会被替换成*,或者无法发送消息。甚至有时发送消息后,会顺带发送一个广告。
CurUser 用于维护自身的信息。比如在登录之后,会发送恭喜xxx登陆成功,这是不礼貌的,应该用名字替换xxx。此时将用到CurUser。
CurUser应写在model包里,新建一个文件夹,命名为curUser.go
Package model
import (
“net”
”go_code/chatroom/common/message”
)
2、CurUser
//因为在客户端,我们很多地方会使用到 curUser,我们将其作为一个全局
type CurUser struct {
Conn net.Conn
message.User
}
全局变量也可放在userMgr.go中的map里,增加
var CurUser model.CurUser//我们在用户登陆成功后,完成对CurUser初始化
在import中将第三行改为
“go_code/chatroom/client/model”
在userProcess.go中找到
if loginResMes.Code == 200{
//初始化CurUser
CurUser.Conn = conn
CurUser.UserId = userId
CurUser.UserStatus = message.UserOnline
如果想加入性别,则在 user.go 包中最后一行增加
Sex string ‘json:”sex”’//性别.
3、群发
在smsProcess.go中
package process
import(
“fmt”
“go_code/chatroom/common/message”
“go_code/chatroom/client/utils”
“encoding/json”
)
type SmsProcess struct{
}
//发送群聊的消息
func(this *SmsProcess) sendGroupMes(content string) (err error){
//1 创建一个Mes
var mes message.Message
mes.Type = message.SmsMesType
//2 创建一个 SmsMes 实例
var smsMes message.SmsMes
smsMes.content = content//内容.
smsMes.UserId = CurUser.UserId//
smsMes.UserStatus = CurUser.UserStatus//
//3.序列化 smsMes
date,err :=json.Marshal(smsMes)
if err != nil{
fmt.Println(“SendGroupes json.Marshal fail =”,err.Error())
return
}
mes.Data = string(data)
//4.对mes再次序列化
date,err :=json.Marshal(mes)
if err != nil{
fmt.Println(“SendGroupes json.Marshal fail =”,err.Error())
return
}
//5.将mes发送给服务器。。
tf := &utils.Transfer{
Conn : CurUser.Conn,
}
//发送
err = tf.WritePkg(data)
if err != nil {
fmt.Println(“SendGroupMes err=”,err.Error())
return
}
return
}
二、实际运用
1、server.go 和群发的衔接
现在已经把 SmsMes 和 CurUse r解决了,群发时输入内容是利用 server.go 主菜单提示的,所以现在可以完成 server.go 和群发的衔接。
此时 server.go 中 switch key 的 case 2换成
fmt.Println(“你想对大家说的什么:)”)
fmt.Scanf(“%s\n”,&content)
smsProcess.SendGroupMes(content)
接收时在 var key int 后面增加
var content string
//因为我们总会使用到 SmsProcess 实例,因此我们将其定义在 switch
SmsProcess := &SmsProcess{}
2、如何验证消息发送成功
只需要在服务器中找到processor.go(总的服务器),不论什么消息,总服务器都会收到,可以验证客户端发的消息总服务器收到与否,收到后可以继续转发的工作。
在main中找到processor.go,找到serverProcessMes,在后面加一句话
//看看是否能接收到客户端发送的群发消息
fmt.Println(“mes=”,mes)
打开 server 端编译,编译完成开始运行,启用客户端,开始编译。编译过程中没有任何问题,客户端发出的消息在服务器中可以顺利收到,由于没有开始逻辑处理,无法进行回应
三、代码总结
实现功能-完成登录用可以群聊
步骤1:当一个用户上线后,可以将群聊消息发给服务器,服务器可以接收到
思路分析:
增加了两个结构体,一个函数,userProcess.go 中增加了一个方法。
代码实现:
[1]common/message/message.go
//增加一个SmsMes //发送的消息
Type SmsMes struct {
content string ‘json:”content”’ //内容
User //匿名结构体,继承
}
[2]client/model/curUser.go
package model
import(
“net”
“go_code/chatroom/common/message”
)
//因为在客户端,我们很多地方会使用到curUser,我们将其作为一个全局
type CurUser struct {
Conn net.Conn
message.User
}
[3]client/process/smsProcess.go 增加了发送群聊消息
type SmsProcess struct{
}
//发送群聊的消息
func(this *SmsProcess) sendGroupMes(content string) (err error){
//1 创建一个 Mes
var mes message.Message
mes.Type = message.SmsMesType
//2 创建一个 SmsMes 实例
var smsMes message.SmsMes
smsMes.content = content//内容.
smsMes.UserId = CurUser.UserId//
smsMes.UserStatus = CurUser.UserStatus//
//3.序列化 smsMes
date,err :=json.Marshal(smsMes)
if err != nil{
fmt.Println(“SendGroupes json.Marshal fail =”,err.Error())
return
}
mes.Data = string(data)
//4.对mes再次序列化
date,err :=json.Marshal(mes)
if err != nil{
fmt.Println(“SendGroupes json.Marshal fail =”,err.Error())
return
}
//5.将mes发送给服务器。。
tf := &utils.Transfer{
Conn : CurUser.Conn,
}
//发送
err = tf.WritePkg(data)
if err != nil {
fmt.Println(“SendGroupMes err=”,err.Error())
return
}
return
}
[4]测试结果如下:
能正确接收到 SmsMes 包包,就说明成功了