springboot-websocket实现及原理
本⽂章包括websocket⾯试相关问题以及spring boot如何整合webSocket。
webSocket是HTML5的⼀种新协议,它实现了服务端与客户端的全双⼯通信,建⽴在传输层,tcp协议之上,即浏览器与服务端需要先建⽴tcp协议,再发送webSocket连接建⽴请求。
webSocket的连接:客户端发送请求信息,服务端接受到请求并返回相应的信息。连接建⽴。客户端发送http请求时,通
过 Upgrade:webSocket Connection:Upgrade 告知服务器需要建⽴的是webSocket连接,并且还会传递webSocket版本号,协议的字版本号,原始地址,主机地址等等。
webSocket相互通信的Header很⼩,⼤概只有2Bytes。
以下是基于spring boot及⽀持webScoket的⾼版本浏览器的配置过程。
⼀、l中引⼊webSocket组件
</dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
⼆、后台引⼊webSocket
要想让⼀个类处理webScoket的请求,需要两个东西:
①类名上加webScoket请求拦截注释@ServerEndpoint(value="/***")
②类需要继承org.springframework.web.socket.server.standard.ServerEndpointExporter,重写交互过程中各种情况下调⽤的⽅法(建⽴时、断开时、出错时、接收消息、发送消息)
针对②,⼀⽅⾯根据spring的IOC特性,需要反向代理,另⼀⽅⾯因为webSocket是⼀个功能⽽不仅仅是属于某个业务,所以应当在配置⽂件中声明。配置⽂件可以是xml⽂件,也可以是注释了@Configurati
on的类⽂件,根据个⼈喜好使⽤~,这⾥使⽤的是@Configuration。
@Configuration
public class ProjectConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
使⽤@ServerEndpoint(value="/***") 时会⾃动注⼊返回类型为ServerEndpointExporter的bean。等同于继承了ServerEndpointExporter 类。继承类后再重写onOpen、onClose、onMessage、onError⽅法,因为不是直接使⽤继承,所以⽅法的重写也需要使⽤注释,代码如下
ller.webSocket;
import java.io.IOException;
import urrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
/**
* 双⼯通信websocket⼯具类
* @author wwl
*
*/
@ServerEndpoint(value="/webSocket")
@Component
public class WebSocketUtil{
//静态变量,⽤来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,⽤来存放每个客户端对应的MyWebSocket对象。
private static CopyOnWriteArraySet<WebSocketUtil> webSocketSet = new CopyOnWriteArraySet<WebSocketUtil>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/**
* 连接建⽴成功调⽤的⽅法*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this); //加⼊set中
addOnlineCount(); //在线数加1
System.out.println("有新连接加⼊!当前在线⼈数为" + getOnlineCount());
try {
sendMessage("您是第" + getOnlineCount() + "个双⼯通信的⽤户!"); } catch (IOException e) {
System.out.println("IO异常");
}
}
/**
* 连接关闭调⽤的⽅法
*/
@OnClose
public void onClose() {
subOnlineCount(); //在线数减1
System.out.println("有⼀连接关闭!当前在线⼈数为" + getOnlineCount()); }
/
**
* 收到客户端消息后调⽤的⽅法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("来⾃客户端的消息:" + message);
//发送消息
try {
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发⽣错误时调⽤
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("发⽣错误");
error.printStackTrace();
}
/
**
* 发送消息
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
BasicRemote().sendText(message);
//AsyncRemote().sendText(message);
}
/**
* 发⾃定义消息
* */
public static void sendInfo(String message) throws IOException {
for (WebSocketUtil item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
continue;
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
}
public static synchronized void subOnlineCount() {
}
}
三、前端引⼊webSocket
使⽤ var websocket = new WebSocket("ws://localhost:8081/***") 建⽴webSocket连接,定义websoc
ket的onerror、onopen、onmessage、onclose的属性,跟后台的四个⽅法相对应,完成合理的webSocket交互。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>websocket测试页⾯</title>
<meta http-equiv="keywords" content="websocket,例⼦">
<meta http-equiv="description" content="测试websocket">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
</head>
<body>
Welcome<br/>
<input id="text" type="text"/><button onclick="send()">Send</button><button onclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>
<script type="text/javascript">
var websocket = null;
//判断当前浏览器是否⽀持WebSocket
if('WebSocket' in window){
websocket = new WebSocket("ws://localhost:8081/webSocket");
}else{
alert('Not support websocket')
}
//连接发⽣错误的回调⽅法
setMessageInnerHTML("error");
};
//连接成功建⽴的回调⽅法
setMessageInnerHTML("open");
}
//接收到消息的回调⽅法
springboot原理书籍
setMessageInnerHTML(event.data);
}
//连接关闭的回调⽅法
setMessageInnerHTML("close");
}
//监听窗⼝关闭事件,当窗⼝关闭时,主动去关闭websocket连接,防⽌连接还没断开就关闭窗⼝,server端会抛异常。
websocket.close();
}
//将消息显⽰在⽹页上
function setMessageInnerHTML(innerHTML){
}
//关闭连接
function closeWebSocket(){
websocket.close();
}
//发送消息
function send(){
var message = ElementById('text').value;
websocket.send(message);
}
</script>
</html>
以上为spring boot 整合webSocket的⼀些⼊门知识。有错误欢迎指正。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论