WebSocket 介绍及使用


  今天带来的是webSocket技术。若有不足,敬请指正。。百度百科中这样解释:javascript

1、WebSocket背景

  如今,不少网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,而后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器须要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费不少的带宽等资源。html

  而比较新的技术去作轮询的效果是Comet。这种技术虽然能够双向通讯,但依然须要反复发出请求。并且在Comet中,广泛采用的长连接,也会消耗服务器资源。前端

  在这种状况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,而且可以更实时地进行通信。java

2、使用WebSocket的优势

  • 较少的控制开销。在链接建立后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的状况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还须要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减小了。
  • 更强的实时性。因为协议是全双工的,因此服务器能够随时主动给客户端下发数据。相对于HTTP请求须要等待客户端发起请求服务端才能响应,延迟明显更少;即便是和Comet等相似的长轮询比较,其也能在短期内更屡次地传递数据。
  • 保持链接状态。与HTTP不一样的是,Websocket须要先建立链接,这就使得其成为一种有状态的协议,以后通讯时能够省略部分状态信息。而HTTP请求可能须要在每一个请求都携带状态信息(如身份认证等)。
  • 更好的二进制支持。Websocket定义了二进制帧,相对HTTP,能够更轻松地处理二进制内容。
  • 能够支持扩展。Websocket定义了扩展,用户能够扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
  • 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,能够沿用以前内容的上下文,在传递相似的数据时,能够显著地提升压缩率。

3、握手协议

  • WebSocket 是独立的、建立在 TCP 上的协议。
  • Websocket 经过HTTP/1.1 协议的101状态码进行握手。
  • 为了建立Websocket链接,须要经过浏览器发出请求,以后服务器进行回应,这个过程一般称为“握手”(handshaking)。

4、API 简介

4.1 ServerApplicationConfig

  项目启动时会自动启动,相似与ContextListener,是WebSocket的核心配置。 其有两个方法:web

  1. getEndPointConfigs获取全部以接口方式配置的webSocket类
  2. getAnnotatedEndpointClasses 扫描src下的全部类(@ServerEndPoint注解的类

  注:EndPoint就指的是一个webSocket的一个服务端程序。编程

5、实现浏览器到服务器的交互

5.1 项目结构以下

项目结构

5.2 DemoConfiig

package com.rrs.config;

import java.util.Set;

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;

/**
 * @author lzx
 *
 */
public class DemoConfig implements ServerApplicationConfig {

	// 注解式方式编程
	@Override
	public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) {
		System.out.println("webSocket:" + scan.size());

		// 服务端扫描到服务返回,能够起到过滤做用
		return scan;
	}

	// 接口式方式编程
	@Override
	public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses) {
		// TODO Auto-generated method stub
		return null;
	}

}

5.3 EchoSocket

package com.rrs.socket;

import java.io.IOException;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

//多例模式
/**
 * @author lzx
 *
 */
@ServerEndpoint("/echo")
public class EchoSocket {

	@OnOpen // 只要访问此路径此方法就会执行
	public void open(Session session) {
		// 一个session 表明一个会话(管道)
		System.out.println("sessionId:" + session.getId() + "开启...");
	}

	@OnMessage
	public void getMessage(Session session, String msg) {

		System.out.println("来自客户端的消息:" + msg);

		// 服务器发送消息
		try {
			session.getBasicRemote().sendText("服务器发送消息:Hello客户端  ");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 会话关闭的时候调用
	@OnClose
	public void close(Session session) {

		System.out.println("sessionId:" + session.getId() + "关闭...");
	}

}

5.4 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webScoket</title>
</head>
<body>

	<button onclick=subOpen();>send</button>
	<br>
	<input type="text" id="message" />
	<button onclick=subSend();>send2</button>

	<div id="sp"></div>

	<script type="text/javascript">
		
		var ws;//一个ws对象就是一个通讯管道
		
		var target = "ws://localhost:8080/websocketproject/echo";
		function subOpen(){
			if ('WebSocket' in window) {
				ws = new WebSocket(target);
			} else if ('MozWebSocket' in window) {
				ws = new MozWebSocket(target);
			} else {
				alert('WebSocket is not supported by this browser.');
				return;
			}
		}
		
		function subSend(){
			if (ws != null) {
                var message = document.getElementById('message').value;
                ws.send(message);
                
			document.getElementById('message').value=""
			  
			// 经过事件
			ws.onmessage = function(event){
				var sp = document.getElementById("sp");
				sp.innerHTML+=event.data;
			}
            } else {
                alert('WebSocket connection not established, please connect.');
            }
		}
		
	</script>
</body>
</html>

5.5 开启服务器,打开会话管道请求服务器,完成示例。

  • 项目启动控制台打印
console
  • 前端页面发起请求到后端响应:
  1. 先send开启管道
  2. 发送数据到后端send2
浏览器,服务器

版权说明:欢迎以任何方式进行转载,但请在转载后注明出处!后端

相关文章
相关标签/搜索