总结
1. 引用其他大佬的总结 : SSL(Secure Socket Layer,安全套接层) 来说是一种加密技术,在 SSL 上运行 WebSocket 协议就是 WSS, 在 SSL 上运行 HTTP 协议就是 HTTPS
2. HTTP 协议有一个很大的缺陷:通信只能由客户端发起,服务器无法主动通知到客户端,而WSS的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向对话,恰好弥补了HTTP的缺陷
3. WSS的其他特点:
3.1 建立在 TCP 协议之上,服务器端的实现比较容易
3.2 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器
3.3 可以发送文本,也可以发送二进制数据
3.4 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL,注意不能是IP地址
配置(我的环境:ubuntu16.04,go1.13,nginx)
1. nginx处理
我的nginx是默认安装,安装路径 : /etc/nginx/
我们需要增加一个配置来让让nginx进行认证wss,升级协议,转发到不同的网关进程,我们在目录 /etc/nginx/conf.d中添加一个443.conf的文件,命名成443是用来标识这个文件用来处理443端口的转发,如下图
443.conf文件里面配置如下,要注意的点(实际的ws服务器IP地址,本服务器的域名url,https证书和密钥的路径,Connection要升级的标记Upgrade等等),特别注意下:location后面带了后缀:/ws,跟代码中的“http.Handle("/ws", s)”必须一致
这样我们发到 wxminigame.yingywz.com/ws 这个url的wss连接会被转发到81.71.13.84:12010,12012,12014这些端口
切记:配置好443.conf后需要让nginx重新加载配置,可以先运行命令 nginx -t 来检测配置是否有错,没错再运行命令 nginx -s reload,让nginx重新加载配置
2. 代码处理(这里贴出主要代码,原理:使用github.com/gorilla/websocket的Upgrader进行操作)
type wsServer struct {
worker workerFunc // 新连接时的处理函数
enableHTTPS bool // 开启https
}
// 继承自本目录的server
var _ server = new(wsServer)
// 新连接时的处理
func (s *wsServer) workOnSocket(conn *websocket.Conn) {
defer func() {
// 断开时的关闭处理
conn.Close()
}()
// 真正处理
s.worker(&client{
conn: conn,
})
}
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// 实现 net/http.Handler 的 ServeHTTP() 接口
func (s *wsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
logrus.Debugf("http server 收到新的连接")
// 升级为websocket协议
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logrus.Errorln("fuck the origin:", err)
return
}
// 连接时的处理
s.workOnSocket(ws)
}
// 启动服务
func (s *wsServer) Serve(addr string, worker workerFunc) error {
logrus.Debugf("启动websocket服务,addr=%s", addr)
// 处理函数
s.worker = worker
http.Handle("/ws", s)
return nil
}