WebSocket介绍
什么是WebSocket
WebSocket是一个协议,归属于IETF。
1.HTTP是运行在TCP协议传输层上的应用协议,而WebSocket是通过HTTP协议协商如何连接,然后独立运行在TCP协议传输层上的应用协议。
2.Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说。
3.Websocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp的连接,从而方便它们之间的通信
为什么需要WebSocket
添加WebSocket特性,是为了更好、更灵活,轻量的与服务器通讯。因为WebSocket提供了简单的消息规范,可以更快的适应长连接的环境,其实现在HTTP协议自身就可以做,但是不太轻便。
WebSocket最大的特点就是实现全双工通信:客户端能够实时推送消息给服务端,服务端也能够实时推送消息给客户端。
WebSocket可以做聊天室,股票实时价格显示等应用
纠正WebSocket误区
WebSocket是一种应用协议,而我们常常看到了HTML5 WebSocket是API,不要将其进行混淆。
广义上的 HTML5 里面包含的是 WebSocket API,并不是 WebSocket。简单的说,可以把 WebSocket 当成 HTTP,WebSocket API 当成 Ajax。
现在我们来用spring boot来使用webSocket实现消息推送
1.首先我们引用Spring-boot所带的websocket依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
复制代码
2.编写前端代码和后台处理后台触发的事件
<script>
var websocket = null;
if('WebSocket' in window){
websocket = new WebSocket('ws://localhost:80/websocket');
}else{
alert("该浏览器不支持WebSocket");
}
websocket.onopen = function (event) {
console.log("建立连接");
}
websocket.onclose = function (event) {
console.log("断开连接");
}
websocket.onmessage = function (event) {
console.log("收到消息" + event.data);
//弹框
$('#myModal').modal('show');
//播放音乐
document.getElementById('notice').play();
}
websocket.onerror = function (event) {
alert("websocket通信发生错误");
}
window.onbeforeunload = function (event) {
websocket.close();
}
</script>
复制代码
3. 使用配置WebSocket部署在Spring容器中
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
复制代码
注:这个Bean会自动使用@ServerEndpoint注解声明的Websocket dedpoint,要注意,如果独立使用Servlet容器,而不是直接使用Spring Boot的内置容器就不需要注入ServerEndpontExporter,因为它将由容器自己提供和管理。
4.编写WebSocket具体的实现类
@ServerEndpoint(value = "/websocket")
@Component
@Slf4j
public class MyWebSocket {
//concurrent 包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/**
* 连接建立成功调用的方法*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this); //加入set中
log.info("有新连接加入!当前连接人数" + webSocketSet.size());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //从set中删除
log.info("关系连接,当前连接人数" + webSocketSet.size());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("来自客户端的消息:" + message);
}
/**
* 发生错误时调用
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
}
/**
* 发送消息
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
}
复制代码
注:使用SpringBoot的唯一区别在于是在@Componet声明下,而使用独立的容器来管理Websocket,但是在springboot中连容器都是Spring管理的,虽然@Componet默认是单例模式 的,但是SpringBoot还是为每个WebSocket Session连接初始化一个Bean,所以可以用一个线程安全的Set进行保存起来。
以上是WebSocket消息推送的列子,启动你的 Spring Boot 的 Application 程序,并在不同浏览器中打开你的 html 文件,查看 Web Socket 的效果。