服务端转发消息代码实现|学习笔记

简介: 快速学习服务端转发消息代码实现

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:服务端转发消息代码实现】学习笔记,与课程紧密联系,让用户快速学习知识。

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


服务端转发消息代码实现

 

内容介绍

一、在服务器端接收到 SmsMes 消息

二、在 server/process/smsProcess.go. 文件增加群发消息的方法

三、在客户端增加处理服务器端转发的群发消息 SmsMes

 

一、在服务器端接收到 SmsMes 消息

首先打开 VS Code,找到 server 端的 processor.go,在37行后增加

case message.RegisterMesType :

//创建一个 SmsProcess 实例完成转发群聊消息。

此时消息类型改为 SmsMesType

同样道理,

up := &process2.UserProcess{在处理消息时服务器一定要创建新的,不可以共用,因为 connect 不一样。服务器端是连接每一个不知道是谁,陌生人不能共用。

打开 smsProcess.go

package process2

import (

“fmt”

“net”

“go_code/chatroom/common/message”

“go_code/chatroom/server/utils”

“encoding/json”

)

type SmsProcess struct {

//..[暂时不需字段]

因为整个服务器端的连接已经在 UserMgr 上了,消息也拿不到,所以不需要字段了
}

//写方法转发消息

func (this *SmsProcess) SendGroupMes(mes *message.Message){

需要知道 mes 的对象,在总控中是可以拿到的,在 processor 中 message 已经有了,所以在 sms 中是可以拿到 message 的,只是格式不同。现在的任务是需要群发

//遍历服务器端的 onlineUsers map[int]*UserProcess,

//将消息转发取出

//取出 mes 的内容 SmsMes              

因为 mes 是藏在 SmsMes 中,所以应反序列化。

var smsMes message.SmsMes

err := json.Unmarshasl([]byte(mes.Data),&smsMes)

Data 部分是 sms 的字符串,需要反序列化,所以要先改成切片,再将引用穿进去。

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)、

连接在 up 里面,上面的 up 发东西,后面的 up.Conn

}

}

因为一个函数不好处理,所以添加一个函数

func (this *SmsProcess) SendMesToEachOnlineUser (data []byte ,conn net.Conn){

需要把消息发出去,发消息的方法是先得到信息内容,再得到发送的链接。这相当于直接把 smsmes 转发,所以没必要把它打开,所以不应该转发 info 的字符串,而是应该转发 mes 序列化过后的切片即可。

data,err :=

json.Marshal(mes)

if err != nil {

fmt.Println(“json.Marshal err=”, err)

}

逻辑:先拿到 mes,把 mes 取出来,取出来的目的是在31行处用了一下,用完了过后,真正要发的仍然是 mes 序列化的 data,相当于做转发,没有落盘,直接通过链接扔走了。

如果做离线留言,就要扫描所有的 id,发现有人不在线就要把消息放到一个数据库中,记住该消息是某人没有拿到的。等到上线的时候,就去读消息。

//创建一个 Transfer 实例,发送 data

tf :=&utils.Transfer{

Conn : conn, //

}

err := tf.WritePkg(data)

if err != nil {

fmt.Println(“转发消息失败 err=”, err)

}

}

 

二、在 server/process/smsProcess.go. 文件增加群发消息的方法

找到总控

//创建一个 SmsProcess 实例完成转发群聊消息.

smsProcess := &process2.SmsProcess{}

smsProcess.SendGroupMes(mes)

这个方法叫sendgroupmes

 

三、在客户端增加处理服务器端转发的群发消息 SmsMes

在 server.go 中增加一个逻辑处理

case message.SmsMesType : //有人群发消息

outputGroupMes(&mes)

在 process 中增加一个新的文件 smsMgr.go

用来做管理 message 的

package process

import (

“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)

fmt.Println()

}

相关文章
|
Web App开发 缓存 网络协议
如何实现服务端向客户端推送数据
常见的http协议只能从客户端主动向服务端请求数据,而服务端无法向客户端发送数据.本文通过介绍几种方式来实现上述功能.
|
6月前
Socket网络编程练习题二:客户端发送一条数据,接收服务端反馈的消息并打印;服务端接收数据并打印,再给客户端反馈消息
Socket网络编程练习题二:客户端发送一条数据,接收服务端反馈的消息并打印;服务端接收数据并打印,再给客户端反馈消息
|
前端开发 JavaScript Java
Springboot 整合 Socket 实战案例 ,实现 单点发送、广播群发,1对1,1对多
Springboot 整合 Socket 实战案例 ,实现 单点发送、广播群发,1对1,1对多
1489 0
Springboot 整合 Socket 实战案例 ,实现 单点发送、广播群发,1对1,1对多
|
存储 编解码 网络协议
Netty各组件基本用法、入站和出站详情、群聊系统的实现、粘包和拆包
Netty各组件基本用法、入站和出站详情、群聊系统的实现、粘包和拆包
117 0
|
消息中间件 Java RocketMQ
路由注册之发送心跳包|学习笔记
快速学习路由注册之发送心跳包
路由注册之发送心跳包|学习笔记
|
JSON 网络协议 测试技术
客户端发消息代码实现|学习笔记
快速学习客户端发消息代码实现
客户端发消息代码实现|学习笔记
|
移动开发 网络协议 测试技术
服务器循环接收客户端消息|学习笔记
快速学习服务器循环接收客户端消息
服务器循环接收客户端消息|学习笔记
|
网络协议 测试技术 Go
服务端转发消息思路分析|学习笔记
快速学习服务端转发消息思路分析
|
JSON 网络协议 测试技术
客户端发消息思路分析|学习笔记
快速学习客户端发消息思路分析
|
移动开发 网络协议 测试技术
服务器接收客户端消息|学习笔记
快速学习服务器接收客户端消息
下一篇
无影云桌面