WebSocket是一种规范,是Html5规范的一部分,websocket解决什么问题呢?解决http协议的一些不足。我们知道,http协议是一种无状态的,基于请求响应模式的协议。
网页聊天的程序(基于http协议的),浏览器客户端发送一个数据,服务器接收到这个浏览器数据之后,如何将数据推送给其他的浏览器客户端呢?
这就涉及到服务器的推技术。早年为了实现这种服务器也可以像浏览器客户端推送消息的长连接需求,有很多方案,比如说最常用的采用一种轮询技术,就是客户端每隔一段时间,比如说2s或者3s向服务器发送请求,去请求服务器端是否还有信息没有响应给客户端,有就响应给客户端,当然没有响应就只是一种无用的请求。
这种长轮询技术的缺点有:
1)响应数据不是实时的,在下一次轮询请求的时候才会得到这个响应信息,只能说是准实时,而不是严格意义的实时。
2)大多数轮询请求的空轮询,造成大量的资源带宽的浪费,每次http请求携带了大量无用的头信息,而服务器端其实大多数都不关注这些头信息,而实际大多数情况下这些头信息都远远大于body信息,造成了资源的消耗。
拓展
比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。
WebSocket一种在单个 TCP 连接上进行 全双工通讯 的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。WebSocket API也被W3C定为标准。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许 服务端主动向客户端推送数据 。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
websocket的出现就是解决了客户端与服务端的这种长连接问题,这种长连接是真正意义上的长连接。客户端与服务器一旦连接建立双方就是对等的实体,不再区分严格意义的客户端和服务端。长连接只有在初次建立的时候,客户端才会向服务端发送一些请求,这些请求包括请求头和请求体,一旦建立好连接之后,客户端和服务器只会发送数据本身而不需要再去发送请求头信息,这样大量减少了
网络带宽。websocket协议本身是构建在http协议之上的升级协议,客户端首先向服务器端去建立连接,这个连接本身就是http协议只是在头信息中包含了一些websocket协议的相关信息,一旦http连接建立之后,服务器端读到这些websocket协议的相关信息就将此协议升级成websocket协议。websocket协议也可以应用在非浏览器应用,只需要引入相关的websocket库就可以了。
HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。Websocket使用ws或wss的统一资源标志符,类似于HTTPS,其中wss表示在TLS之上的Websocket。如:
优点
浏览器页面向服务器发送消息,服务器将当前消息发送时间反馈给浏览器页面。
服务器端
服务器端初始化连接
WebSocketServerProtocolHandler :参数是访问路径,这边指定的是ws,服务客户端访问服务器的时候指定的url是: ws://localhost:8899/ws 。
它负责websocket握手以及处理控制框架(Close,Ping(心跳检检测request),Pong(心跳检测响应))。 文本和二进制数据帧被传递到管道中的下一个处理程序进行处理。
桢 :
WebSocket规范中定义了6种类型的桢,netty为其提供了具体的对应的POJO实现。
WebSocketFrame:所有桢的父类,所谓桢就是WebSocket服务在建立的时候,在通道中处理的数据类型。本列子中客户端和服务器之间处理的是文本信息。所以范型参数是TextWebSocketFrame。
自定义Handler
页面 :
启动服务器,然后运行客户端页面,当客户端和服务器端连接建立的时候,服务器端执行 handlerAdded 回调方法,客户端执行 onopen 回调方法
服务器端控制台:
页面:
客户端发送消息,服务器端进行响应,
服务端控制台打印:
客户端也收到服务器端的响应:
打开开发者工具 :
在从标准的HTTP或者HTTPS协议切换到WebSocket时,将会使用一种升级握手的机制。因此,使用WebSocket的应用程序将始终以HTTP/S作为开始,然后再执行升级。这个升级动作发生的确定时刻特定与应用程序;它可能会发生在启动时候,也可能会发生在请求了某个特定的IURL之后。
参考技术
java web 服务器推送技术--comet4j
Comet:基于 HTTP 长连接的“服务器推”技术
客户端是发送消息给服务器的,服务器不可能主动发消息给客户端。就是长链接,比如,客户端发送一个消息你好的消息给服务器,那么服务器会接收到,这时候就有客户端的所有信息,比如id+ip组成的管道,管道id(一般是用户id)。如果“向所有客户端发送某消息”,那么要想办法在设置一个资格(比如登陆的时候保存客户端的信息用对象存储,这样更利于更改更新管道)。然后把所有客户端放到一个list里面存储。遍历list,给每个用户发送消息。
首先,App的服务端跟Web的服务端没有多大区别,而且在实际的开发过程中,业务逻辑也都是共用一套,只是会针对不同的客户端做不同的适配(这点可参考Amazon,其对PC的web端,移动的Web端,移动的App都做了不同程度的适配).其次,既然与Web的服务端没多大区别,那所用的技术也大同小异,对于App而言,服务端更多是一个数据接口,所以框架页大同小异;
最后,大致总结一下:
技术:
网络通信: tcp,http等;
Web服务:servlet, cgi脚本,asp等;
系统调度:多线程,并发等;
框架:
对应不同的web服务技术,采用的编程语言不同;
对应不同的网络通信协议,采用的框架也不同,netty->tcp,servlet等web服务框架->http等;
对应系统调度,有不同的多线程,多进程通信框架等;
对应提供不同的服务接口,有web service和restful两大类,前者基于soap协议,后者基于http协议,对应的框架就很多,不一一叙述;
除此之外,还有很多其他的技术,可先做,发现问题,自然就知道怎么去找相应的技术、解决方案(包含框架)来解决,所以先动手吧;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)