即时IM通信
用开源websocket框架mongoose编写网页版本的群聊即时通信工具,使用websocket+mongoose+session+mysql+jsoncpp的技术构成,完成IM工具。
实现功能:
- 使用WebSocket协议来实现客户端与服务端之间数据的双向交互,以此完成聊天功能。
- 使用开源的mongoose框架遍历在线用户列表,广播发送消息,实现群聊、提醒某用户上线下线的功能
- 下载前端源代码:实现注册、登录、聊天界面,实现聊天室的可视化功能
- 使用MySQL数据库存储用户信息,通过与数据库交互来实现用户登录、注册等功能
一、很多网站为了实现推送技术,所用的技术都是轮询。
- 轮询是指在特定的时间间隔(如每一秒),由浏览器对服务器发起HTTP请求,然后由服务器返回数据给浏览器。由于HTTP协议是惰性的,只有客户端发起请求,服务器才会返回数据。
轮询技术实现的前提条件同样是基于这种机制。而WebSocket属于服务端推送技术,本质是一种应用层协议,可以实现持久连接的全双工双向通信。
- WebSocket协议(应用层协议)的目标是在一个独立的持久连接上提供全双工双向通信。客户端和服务器可以向对方主动发送和接受数据。在JS中创建WebSocket后,会有一个HTTP请求发向浏览器以发起请求。在取得服务器响应后,建立的连接会使用HTTP升级将HTTP协议转换为WebSocket协议。也就是说,使用标准的HTTP协议无法实现WebSocket,只 有支持那些协议的专门浏览器才能正常工作。WebSocket协议的建立需要先借助HTTP协议,在服务器返回101状态码之后,就可以进行websocket全双工双向通信了,就没有HTTP协议什么事情了。
二. 心跳、Ajax长短轮询
1、心跳机制:
原理:客户端每隔N秒向服务端发送一个心跳消息,服务端收到心跳消息后,回复同样的心跳消息给客户端。如果服务端或客户端在M秒(M>N)内都没有收到包括心跳消息在内的任何消息,即心跳超时,我们就认为目标TCP连接已经断开了。
心跳包的实现,通常有两种技术:
(1)应用层自己实现的心跳包
- 由应用程序自己发送心跳包来检测连接是否正常,服务器每隔一定时间向客户端发送一个短小的数据包,然后启动一个线程,在线程中不断检测客户端的回应, 如果在一定时间内没有收到客户端的回应,即认为客户端已经掉线;同样,如果客户端在一定时间内没有收到服务器的心跳包,则认为连接不可用。
(2)使用SO_KEEPALIVE套接字选项
- 在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项. 不论是服务端还是客户端,一方开启KeepAlive功能后,就会自动在规定时间内向对方发送心跳包, 而另一方在收到心跳包后就会自动回复,以告诉对方我仍然在线。因为开启KeepAlive功能需要消耗额外的宽带和流量,所以TCP协议层默认并不开启默认的KeepAlive超时需要7,200,000 MilliSeconds, 即2小时,探测次数为5次。对于很多服务端应用程序来说,2小时的空闲时间太长。因此,我们需要手工开启KeepAlive功能并设置合理的KeepAlive参数
2、轮询及实现:
(1)短轮询
- Ajax短轮询即客户端周期性的向服务器发起HTTP请求,不管服务器是否真正获取到数据,都会向客户端返回响应(有就返回新数据,没有就返回一个表示’空’的自定义数据格式),一个HTTP连接结束。
- 每个request对应一个response,由于HTTP/1.1的持久连接(建立一次TCP连接,发送多个请求)和管线化技术(异步发送请求),使得HTTP请求可以在建立一次TCP连接之后发起多个异步请求。
(2)长轮询
- 长轮询是短轮询的一种变体。
- 在客户端向服务器发起HTTP请求之后,服务器并不是每次都立即响应:
- 当服务器得到最新数据时,会向客户端传输数据;当数据没有更新时,服务器会保持这个连接,等待更新数据之后,才向客户端传输数据。
- 当然,如果服务端数据长时间没有更新,一段时间后,请求就会超 时。客户端收到超时信息后,会重新发送一个HTTP请求给服务器。
长轮询的经典实现 —— Comet:基于 HTTP 长连接的“服务器推”技术
三、http和websocket的长连接
-
短连接:
连接->传输数据->关闭连接
HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。
也可以这样说:短连接是指SOCKET连接后发送后接收完数据后马上断开连接。 -
长连接
连接->传输数据->保持连接 -> 传输数据-> 。。。 ->关闭连接。
长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差。
HTTP长连接:
- HTTP1.1通过使用Connection:keep-alive进行长连接,HTTP 1.1默认进行持久连接。在一次 TCP 连接中可以完成多个 HTTP 请求,但是对每个请求仍然要单独发 header,Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。这种长连接是一种“伪链接”。
websocket的长连接:
-
websocket的长连接,是一个真正的全双工。长连接第一次tcp链路建立之后,后续数据可以双方都进行发送,不需要发送请求头。
-
keep-alive双方并没有建立正真的连接会话,服务端可以在任何一次请求完成后关闭。WebSocket 它本身就规定了是正真的、双工的长连接,两边都必须要维持住连接的状态。
四、Mongoose是c语言写成的网络库。
- 它为TCP、UDP、HTTP、WebSocket、CoAP、MQTT实现了事件驱动型的非阻塞 api。
五、相关知识点:
1、HTTP请求/响应报文:
- HTTP请求报文:
报文首部:请求行(请求方法、请求URL、HTTP版本号)、请求首部字段、通用首部字段、实体首部字段、其他(可能会包含HTTP的RFC里未定义的首部(cookie等))
空行
报文主体 - HTTP响应报文:
报文首部:状态行(响应结果状态码、原因语句、HTTP版本)、各种首部字段(请求和响应的各种条件和属性的各类首部)通用首部字段、实体首部字段、响应首部字段。
空行:
报文主体:
2、HTTP状态码:
1XX 信息性状态码(接受的请求正在处理)
2XX 成功状态码(请求正常处理完毕)
- 200:请求已正常处理
- 204:请求处理成功,但没有资源要返回
- 206:客户端进行范围请求,而服务器成功执行Get请求。
3XX 重定向状态码(需要添加附加操作以完成请求)
- 301:永久性重定向
- 302:临时性重定向(请求上Post换为get)
- 303:
- 304:资源已找到,但未符合条件请求
- 307:临时性重定向
4XX 客户端错误状态码(服务器无法处理请求)
- 400:请求报文中存在语法错误
- 401:发送的请求需要经过HTTP请求
- 403:对请求访问的资源被服务器拒绝访问
- 404:服务器上没有请求资源
5XX 服务器错误状态码(服务器处理请求出错)
- 500:服务器请求错误
- 503:服务器处于超负载或正处于停机维护
3、Cookie和session区别:
- Cookie和session都是会话技术,cookie是运行在客户端,session是运行在服务器端。
- Cookie有大小限制以及浏览器存cookie的个数也有限制,session没有大小限制和服务器内存有关。
- Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可进行攻击,session保存在服务器端一段时间才会消失,如果session过多会增加服务器的压力。
- Session原理:浏览器第一次访问服务器时会创建一个session对象并返回jessionID=ID的值,创建一个Cookie对象key为jessionID、value为ID的值。将这个cookie写回浏览器。当浏览器第二次访问服务器时携带cookie信息JESSIONID的值,如果已被销毁,需要重新创建一个新的session再返回一个新的JESSIONID通过Cookie返回到浏览器。
4、get/post/head/各种请求方法
- GET: 请求指定的页面信息,并返回实体主体。
- HEAD: 只请求页面的首部。
- POST: 请求服务器接受所指定的文档作为对所标识的URI的新的从属实体。
- PUT: 从客户端向服务器传送的数据取代指定的文档的内容。
- Delete: 请求服务器删除指定的页面。
- OPTIONS: 允许客户端查看服务器的性能。