springboot集成websocket
websocket能干什么
- 主动从服务端向客户端传递消息,这个可以实现我们定时获取后台信息的需求。前台页面不需要定期刷新,后台可以定时或者有更新的时候向前台传递信息。
- 可以实现类似聊天室的需求。
基本实例
- 引入所需的jar包
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
- 创建一个config,开启websocket支持
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
- 创建一个websocket的服务端
WebSocketServer
@ServerEndpoint("/websocket")
@Component
@Slf4j
public class WebSocketServer {
//静态变量,用来记录当前在线连接数。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
//接收sid
private String userId ="";
/**
* 连接建立成功调用的方法
* @param session
* @param userId
*/
@OnOpen
public void onOpen(Session session,@PathParam("userId") String userId) {
this.session = session;
this.userId =userId;
webSocketSet.add(this); //加入set中
addOnlineCount(); //在线数加1
log.info("有新窗口开始监听:"+userId+",当前在线人数为" + getOnlineCount());
try {
//向客户端发送消息
sendMessage("连接成功");
} catch (IOException e) {
log.error("websocket IO异常" + e.getMessage());
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息内容
* @param session
*/
@OnMessage
public void onMessage(String message, Session session) {
//接收到消息后,在这里可以处理自己的业务
log.info("收到来自窗口"+ userId +"的信息:"+message);
//如果是一个聊天室,可以在这里群发消息(这个只是举例,具体业务逻辑看自己的需要)
for (WebSocketServer item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 发生错误时调用的方法
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误:"+ error.getMessage());
error.printStackTrace();
}
/**
* 服务器主动推送到客户端,这个客户端时当前连接的客户端(this.session)
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 群发自定义消息
* @param message
* @throws IOException
*/
public static void sendInfo(String message) throws IOException {
for (WebSocketServer item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
continue;
}
}
}
/**
* 群发一个对象信息
* @param studentList
*/
public static void sendInfo(List<Student> studentList){
for (WebSocketServer item : webSocketSet) {
try {
item.sendMessage(JSON.toJSONString(studentList));
} catch (IOException e) {
continue;
}
}
}
private static synchronized int getOnlineCount() {
return onlineCount;
}
private static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
private static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
}
- 可以把这个WebSocketServer当成是controller一样使用,但是他是ws协议,不是http协议,所以要连接这个服务器端就要使用
ws://ip:port/projectName/@ServerEndpoint
的格式,例如我们的示例是ws://127.0.0.1:8088/moyundong/websocket
- @ServerEndpoint(“/imserver/{userId}”)类似controller里面的@RequestMapping,也可以后面带参数,例如@ServerEndpoint(“/websocket/{userId}”)
WebSocketServer
里面包含接收到消息的方法,发送给客户端的方法,关闭连接等等许多方法,大家根据需要添加自己的业务- 使用CopyOnWriteArraySet来存放每个连接的实例,方便我们给全部或者指定客户端发送消息
- 创建一个客户端测试(index.jsp页面)
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>WebSocket 聊天室</title>
</head>
<body>
<script type="text/javascript">
var socket;
if (!window.WebSocket) {
window.WebSocket = window.MozWebSocket;
}
if (window.WebSocket) {
socket = new WebSocket("ws://127.0.0.1:8088/moyundong/websocket");
socket.onmessage = function(event) {
var ta = document.getElementById('responseText');
ta.value = ta.value + '\n' + event.data
};
socket.onopen = function(event) {
var ta = document.getElementById('responseText');
ta.value = "连接开启!";
};
socket.onclose = function(event) {
var ta = document.getElementById('responseText');
ta.value = ta.value + "连接被关闭";
};
} else {
alert("你的浏览器不支持 WebSocket!");
}
function send(message) {
if (!window.WebSocket) {
return;
}
if (socket.readyState == WebSocket.OPEN) {
socket.send(message);
} else {
alert("连接没有开启.");
}
}
</script>
<form οnsubmit="return false;">
<h3>WebSocket 聊天室:</h3>
<textarea id="responseText" style="width: 500px; height: 300px;"></textarea>
<br>
<input type="text" name="message" style="width: 300px" value='随便输入:'>
<input type="button" value="发送消息" οnclick="send(this.form.message.value)">
<input type="button" οnclick="javascript:document.getElementById('responseText').value=''" value="清空聊天记录">
</form>
</body>
</html>
这是一个简易聊天室的例子
new WebSocket("ws://127.0.0.1:8088/moyundong/websocket");
创建一个连接socket.onmessage
当客户端接收到消息时的方法,可以处理自己的业务socket.onopen
连接成功后的方法socket.onclose
连接断开后的方法
- 在浏览器运行
http://localhost:8088/moyundong/index.jsp
就可以客气客户端了
::: tip 提示
这个只是最基本的例子,连接的时候也没有加userId,但是原理就是这些,大家可以根据自己的业务需求去拓展。
:::
websocket加定时任务
前面我们学习了定时任务,我们可以把定时任务和websocket结合起来,这样可以实现定时向客户端发送特点信息,并且客户端页面也不用实时发送请求查询后台信息。
有这方面需求的朋友可以去试下。原理就是在定时任务里面调用WebSocketServer
的静态方法就可以了
1介绍
2springboot定时任务
3springboot定时任务配置详解
4springboot动态定时任务
5springboot集成websocket
6springboot多数据源
7springboot配置druid监听
8springboot自定义注解
9springboot常见注解详解
10springboot接收参数详解
11springboot验证机制@Valid和@Validated
12springboot集成Swagger2
13springboot集成swagger-bootstrap-ui
14springboot集成shiro
15springboot集成shiro(二)
16springboot集成jwt
17springboot集成ActiveMQ
18springboot缓存机制
🍉🍉🍉 欢迎大家来博客了解更多内容:java乐园 🍉🍉🍉
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/13511.html