这个项目是基于WebSocket + MongoDB + MySQL + Redis。业务逻辑很简单,只是两人的聊天。

WebSocket

WebSocket是应用层第七层上的一个应用层协议,它必须依赖 HTTP 协议进行一次握手。 握手成功后,数据就直接从TCP通道传输,与HTTP无关了。即:WebSocket分为握手和数据传输阶段。 即进行了HTTP握手 + 双工的TCP连接。

WebSocket 是一种在单个TCP连接上进行全双工通信的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

如果只是想左图这样的不断发送http请求,轮询的效率是非常低,非常浪费资源,所以就有了websocket协议了,建立在 TCP 协议之上,服务器端的实现比较容易。

WebSocket协议一旦建立之后,互相沟通所消耗的请求头是很小的,服务器向客户端推送消息的功耗就小了。

gorilla/websocket使用

1
2
首先向客户端发送消息使用WriteMessage(messageType int, data []byte),参数1为消息类型参数2消息内容
_ = conn.Socket.WriteMessage(websocket.TextMessage, msg)

json与结构体的相互转化

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 回复的消息
type ReplyMsg struct {
	From    string `json:"from"`
	Code    int    `json:"code"`
	Content string `json:"content"`
}

replyMsg := &ReplyMsg{
    Code:    e.WebsocketEnd,
    Content: "连接已断开",
}

msg, _ := json.Marshal(replyMsg)//将结构体转换成json字符串

//1.Unmarshal的第一个参数是json字符串,第二个参数是接受json解析的数据结构。
//第二个参数必须是指针,否则无法接收解析的数据,如replyMsg2仍为空对象ReplyMsg{}
//2.可以直接stu:=new(StuRead),此时的stu自身就是指针
replyMsg2:= ReplyMsg{}
err:=json.Unmarshal(msg,&replyMsg2)

main.go启动一个线程来监听ws的连接

ws://localhost:3000/ws?uid=1&toUid=2

会创建一个用户实例并将用户注册到用户管理上,并启动2个go线程来实现这个用户的读写线程

Start()监听到了Manager.Register:创建一个replyMsg并转化为json格式传入Socket中

ws://localhost:3000/ws?uid=1&toUid=2

{ “type”:1, “content”:“111” }

reids才会存储Client.Id并设置过期时间

并且会传一个Manager.Broadcast返回给该用户其对方的状态,并将content存入mangodb中

如果对方在线就会往往对方的Client.Send中传入content

一旦某个用户的send中有消息,