基于gin+websocket单台机器⽀持百万连接分布式聊天(IM)
系统
本⽂将介绍如何实现⼀个基于websocket分布式聊天(IM)系统。
使⽤golang实现websocket通讯,单机可以⽀持百万连接,使⽤gin框架、nginx负载、可以⽔平部署、程序内部相互通讯、使⽤grpc通讯协议。
本⽂内容⽐较长,如果直接想clone项⽬体验直接进⼊项⽬体验 goWebSocket项⽬下载 ,⽂本从介绍webSocket是什么开始,然后开始介绍这个项⽬,以及在Nginx中配置域名做webSocket的转发,然后介绍如何搭建⼀个分布式系统。
1、项⽬说明
1.1 ⼀般项⽬中webSocket使⽤的架构图
1.2 项⽬体验
2、介绍webSocket
2.1 webSocket 是什么
WebSocket 协议在2008年诞⽣,2011年成为国际标准。所有浏览器都已经⽀持了。
它的最⼤特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的⼀种。
HTTP和WebSocket在通讯过程的⽐较
HTTP和webSocket都⽀持配置证书,ws:// ⽆证书 wss:// 配置证书的协议标识
2.2 webSocket的兼容性
浏览器的兼容性,开始⽀持webSocket的版本
服务端的⽀持 golang、java、php、node.js、python、nginx 都有不错的⽀持Android和IOS的⽀持 Android可以使⽤java-webSocket对webSocket⽀持iOS 4.2及更⾼版本具有WebSockets⽀持
2.3 为什么要⽤webSocket
从业务上出发,需要⼀个主动通达客户端的能⼒ ⽬前⼤多数的请求都是使⽤HTTP,都是由客户端发起⼀个请求,有服务端处理,然后返回结果,不可以服务端主动向某⼀个客户端主动发送数据
⼤多数场景我们需要主动通知⽤户,如:聊天系统、⽤户完成任务主动告诉⽤户、⼀些运营活动需要通知到在线的⽤户
可以获取⽤户在线状态
在没有长连接的时候通过客户端主动轮询获取数据
可以通过⼀种⽅式实现,多种不同平台(H5/Android/IOS)去使⽤
websocket和socket
2.4 webSocket建⽴过程
2.4.1 客户端先发起升级协议的请求
客户端发起升级协议的请求,采⽤标准的HTTP报⽂格式,在报⽂中添加头部信息
Connection: Upgrade 表明连接需要升级
Upgrade: websocket 需要升级到 websocket协议
Sec-WebSocket-Version: 13  协议的版本为13
Sec-WebSocket-Key: I6qjdEaqYljv3+9x+GrhqA== 这个是base64 encode 的值,是浏览器随机⽣成的,与服务器响应的 Sec-WebSocket-Accept对应
1# Request Headers
2Connection: Upgrade
3Host: im.91vh
4Origin: im.91vh
5Pragma: no-cache
6Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
7Sec-WebSocket-Key: I6qjdEaqYljv3+9x+GrhqA==
8Sec-WebSocket-Version: 13
9Upgrade: websocket
2.4.2 服务器响应升级协议
服务端接收到升级协议的请求,如果服务端⽀持升级协议会做如下响应
返回:
Status Code: 101 Switching Protocols 表⽰⽀持切换协议
1# Response Headers
2Connection: upgrade
3Date: Fri, 09 Aug 2019 07:36:59 GMT
4Sec-WebSocket-Accept: mB5emvxi2jwTUhDdlRtADuBax9E=
5Server: nginx/1.12.1
6Upgrade: websocket
2.4.3 升级协议完成以后,客户端和服务器就可以相互发送数据
3、如何实现基于webSocket 的长连接系统
3.1 使⽤go 实现webSocket 服务端
3.1.1 启动端⼝监听
websocket需要监听端⼝,所以需要在golang 成功的 main 函数中⽤协程的⽅式去启动程序
< 实现启动
启动程序
3.1.2 升级协议客户端是通过http请求发送到服务端,我们需要对http协议进⾏升级为websocket协议对http请求协议进⾏升级 golang 库gorilla/websocket 已经做得很好了,我们直接使⽤就可以了
在实际使⽤的时候,建议每个连接使⽤两个协程处理客户端请求数据和向客户端发送数据,虽然开启协程会占⽤⼀些内存,但是读取分离,减少收发数据堵塞的可能
go websocket.StartWebSocket()
1
// 启动程序2
func StartWebSocket() {3
http.HandleFunc("/acc", wsPage)4    http.ListenAndServe(":8089", nil)5}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。