开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:海量用户通讯系统-项目小结】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9824
海量用户通讯系统-项目小结
内容介绍
一、代码运行
二、代码实现
三、思考题
一、代码运行
把代码编译后,尝试是否能运行。整个系统都要进行编译,因为服务器端、客户端都发生了很大的变化。
经过第一轮编译,服务器端和客户端都顺利完成,没有发生错误,此时把三个端口放在一起
接下来进行测试工作
先启动服务器
D:、goproject>server.exe
登录第一个
D:\goproject>client.exe
输入id:100
输入密码:123456
登录成功,此时无法发送群聊消息
在第二个中登录聊天室
D:\goproject>client.exe
输入id:200
密码:123456
此时在200号中可以看见100号在线,在100号中可以看到200号上线
登录300号
D:\goproject>client.exe
输入id:300
密码:123456
输入2可以在群聊发送消息
发送:hello
在100号和200号中都可以看到300号在群聊中发送了hello
同理,在200号或100号中发送消息,其余二人都可以收到消息,证明代码是正确的。
二、代码整理
1、思路分析:
粉色:model/CurUser
struct{
Conn
蓝色:SmsMes{
User
Content…
}
虚线:完成客户端可发送消息的思路
① 新增一个消息结构体SmsMes…
② 新增一个model CurUser
③ 在smsProcess.go增加相应的方法SendGroupMes发送一个群聊的消息
④ 在服务器端接收到SmsMes消息
⑤ 在server/process/smsProcess.go文件增加群发消息的方法
⑥ 在客户端还要增加去处理服务器端转发的群发消息SmsMes
2、代码实现
【1】s
erver/process/smsProcess.go
package process2
i
mport (
“fmt”
“net”
“go_code/chatroom/common/message”
“go_code/chatroom/server/utils”
“encoding/json”
)
t
ype SmsProcess struct {
//..[暂时不需字段]}
//写方法转发消息
func (this *SmsProcess) SendGroupMes(mes *message.Message){
//遍历服务器端的onlineUsers map[int]*UserProcess,
//将消息转发取出
//取出mes的内容 SmsMes
var smsMes message.SmsMes
err := json.Unmarshasl([]byte(mes.Data),&smsMes)
if err !=nil{
fmt.Println(“json.Unmarshal err=”,err)
return
}
data,err :=
json.Marshal(mes)
if err != nil {
fmt.Println(“json.Marshal err=”, err)
}
for id,up := range userMgr.onlineUsers {
//这里,还需要过滤到自己,即不要再发给自己
If id == smsMes.UserId {
continue
}
this.SendMesToEachOnlineUser(data ,up.Conn)
}
}
func (this *SmsProcess) SendMesToEachOnlineUser (dat
a
[]byte ,conn net.Conn){
//创建一个Transfer 实例,发送data
tf :=&utils.Transfer{
Conn : conn, //
}
err := tf.WritePkg(data)
if err != nil {
fmt.Println(“
转发消息失败
err=
”,
err)
}
}
【2】server/main/processor.go
//处理注册
up := &process2.UserProcess{
Conn : this.Conn,
}
err up.ServerProcessRegister(mes) //
type
:data
case
message.SmsMesType :
//创建一个SmsProcess实例完成转发群聊消息.
smsProcess := &process2.SmsProcess{}
smsProcess.SendGroupMes(mes)
d
efault :
fmt.Println(“
消息类型不存在,无法处理
…”)
}
【3】client/process/smsMgr.go
package process
i
mport (
“fmt”
“go_code/chatroom/common/message”
“encoding/json”
)
func outputGroupMes(mes *message.Message)
{//这个地方mes一定SmsMes
//显示即可
//1、反序列化mes,Data
var smsMes message.SmsMes
err :=json.Unmarshal([]byte(mes.Data),&smsMes)
if err != nil {
fmt.Println(“json.Unmarshal err=”,err.Error())
return
}
//显示信息
info := fmt.Sprintf(“
用户id
:\t%s
对大家说:\
t%s”,
smsMes.UserId,smsMes.Content”)
fmt.Println(info)
f
mt.Println()
}
【4】client/process/server.go
case message.SmsMesType
:/
/
有人群发消息
out
putGroupMes(&mes)
default
:
fmt.Println(“
服务器端反悔了未知的消息类型
”)
}
/
/fmt.Printf(“mes=%v\n,mes)
}
三、思考题
18.5.10聊天的项目的扩展功能要求
1.实现私聊.[点对点聊天]
2.如果一个登录用户离线,就把这个人从在线列表去掉
3.实现离线留言,在群聊时,如果某个用户没有在线,当登录后,可以接受离线的消息