10分钟教对象搭建了一个多人聊天室~

Demo演示

10分钟教对象搭建了一个多人聊天室~_第1张图片

体验demo链接: http://socket.vjscoder.com/websocket-chatroom/index.html#/

去github查看完整源码: https://github.com/ReeceLeaf/websocket-chatroom

前言

从不认识Websocket到接手H5聊天室项目,接着就是一年多的聊天室功能更新和迭代,总的来说,入门很简单,要深入还是要花一些时间去学习实践才可以。网上已经有不少大佬发表过关于Websocket实现聊天室的文章,这里我自己总结了Websocket的基础知识,实现了一个简单的聊天室入门的demo,作为记录和复习,也分享给需要入门的人。

大纲

10分钟教对象搭建了一个多人聊天室~_第2张图片

了解Websocket

背景

在许多场景下,用户需要得到实时的消息,比如聊天,医疗设备读数等,旧的解决方案是基于轮询的方式获取最新数据,但是并不会完全实时消息同步,并且大多数情况下请求都是没必要的,反而浪费了大量的流量和服务器资源。基于这种背景下,websocket诞生了。

Websocket基本概念

WebSocket 是 HTML5 开始提供的一种在「单个 TCP 连接上」进行「全双工通讯」「协议」。WebSocket通信协议诞生于2008年,2011年成为国际标准. WebSocket使得客户端和服务器之间的数据交换变得更加简单,「允许服务端主动向客户端推送数据」。在WebSocket API中,浏览器和服务器「只需要完成一次握手」,两者之间就直接可以创建「持久性的连接」,并进行「双向数据传输」

兼容性问题(主流浏览器都支持)

10分钟教对象搭建了一个多人聊天室~_第3张图片

image

Websocket特点

  • 「控制开销。」 在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。

  • 「实时通信」。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。

  • 「保持连接状态」。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。

  • 「支持二进制传输」。可以发送文本,也可以发送二进制数据。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。

  • 「协议标识符是ws(如果加密,则为wss),服务器网址就是 URL」

  • 实现简单。建立在 TCP 协议之上,服务器端的实现比较容易,并且没有同源限制,客户端可以与任意服务器通信。

  • 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

  • 支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。

Websocket初始握手

每个Websocket连接都始于一个HTTP请求,该请求和其他请求类似,但是包含一个特殊的首标 —— 「Upgrade」。Upgrade表示客户端将「把连接升级到Websocket协议」

在握手前,Websocket遵循HTTP/1.1协议。

客户端发送升级为Websocket的请求也称为初始握手。客户端发送HTTP升级请求后,直到服务端响应 101 状态码、Upgrade和Sec-WebSocket-Accept首标才算连接成功,否则不能连接成功。下面是拷贝的websocket握手的请求头和相应头:

// 客户端发送的请求头
GET wss://www.example.cn/webSocket HTTP/1.1  // 使用的https协议, 对应的wss请求
Host: www.example.cn
Connection: Upgrade  // 带upgrade头的http1.1消息必须含有connection头,表示任何接受此消息的人都在在转发此消息之前处理掉connection中指定的域(即不转发upgrade域)
Upgrade: websocket  // 定义转换协议的header域,如果服务器支持,客户端希望使用已经建立好的http(tcp)连接
Sec-WebSocket-Version: 13 // 客户端支持的WebSocket协议的版本列表
Origin: http://example.cn // Origin为安全使用,防止跨站攻击,浏览器一般会使用这个来标识原始域。
Sec-WebSocket-Key: afmbhhBRQuwCLmnWDRWHxw== // 首标 客户端随机生成,服务器会使用此字段组装成另一个key值放在握手返回信息里。用于客户端到服务器websocket的初始握手,避免跨协议攻击。
Sec-WebSocket-Protocol: chat, superchat // 首标 告诉客户端应用程序可使用的协议
Sec-WebSocket-Extensions: permessage-deflate(协商使用传输数据压缩); client_max_window_bits(采用LZ77压缩算法时,滑动窗口相关SIZE大小)// 首标


// 服务器发出的响应头
HTTP/1.1 101
Server: nginx/1.12.2
Date: Sat, 11 Aug 2018 13:21:27 GMT
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: sLMyWetYOwus23qJyUD/fa1hztc= // 确认服务器是否理解websocket协议
Sec-WebSocket-Protoc

你可能感兴趣的:(Java,Java程序员,java)