1、导包
java
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.1</version>
</dependency>
2、新建一个websocket包,包中新建两个类,代码如下
java
package com.example.it.springboot.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
//websocket包需要与启动类同级别
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter()
{
return new ServerEndpointExporter();
}
}
java
package com.example.it.springboot.websocket;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import cn.hutool.json.JSONUtil;
import java.io.IOException;
import java.net.http.WebSocket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/***
* 监听websocket地址 /myWs
*/
@ServerEndpoint("/myWs")
@Component
@Slf4j
@EnableScheduling
public class WsServerEndpoint {
static Map<String, Session> map = new ConcurrentHashMap<String,Session>();
//新增一个方法用于主动向客户端发送消息
public static void sendMessage(Object message, String userId) {
Session session = map.get(userId);
if (session != null) {
try {
session.getBasicRemote().sendText(JSONUtil.toJsonStr(message));
System.out.println("【websocket消息】发送消息成功,用户="+userId+",消息内容"+message.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
/***
* 连接建立时执行的操作
* @param session
*/
@OnOpen
public void onOpen(Session session)
{
map.put(session.getId(),session);
log.info("session.getId()="+session.getId());
log.info("session="+session);
log.info("websocket is open");
}
/***
* 收到客户端消息执行的操作
* @param text
*/
@OnMessage
public String OnMessage(String text)
{
log.info("收到了一条信息: "+text);
return "已收到你的信息" ;
}
/***
* 连接关闭时执行的操作
* @param session
*/
@OnClose
public void OnClose(Session session)
{
map.remove(session.getId());
log.info("websocket is close");
}
/***
* 向客户端发送信息
*/
@Scheduled(fixedRate = 2000)
public void sendMsg() throws IOException {
for (String key : map.keySet())
{
//map.get(key).getBasicRemote().sendText("定时发送,你好");
}
}
}
3、新建一个websocket.html
java
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>wsClient</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<style>
.btn-group{
display: inline-block;
}
</style>
</head>
<body>
<input type='text' value='ws://localhost:8080/myWs' class="form-control" style='width:390px;display:inline'
id='wsaddr' />
<div class="btn-group" >
<button type="button" class="btn btn-default" onclick='addsocket();'>连接</button>
<button type="button" class="btn btn-default" onclick='closesocket();'>断开</button>
<button type="button" class="btn btn-default" onclick='$("#wsaddr").val("")'>清空</button>
<button type="button" class="btn btn-default" onclick='restore()'>还原</button>
</div>
<div id="output" style="border:1px solid #ccc;height:365px;overflow: auto;margin: 20px 0;"></div>
<input type="text" id='message' class="form-control" style='width:810px' placeholder="待发信息" onkeydown="en(event);">
<span class="input-group-btn">
<button class="btn btn-default" type="button" onclick="doSend();">发送</button>
</span>
</div>
<script>
/*组织时间*/
function formatDate(now) {
var year = now.getFullYear();
var month = now.getMonth() + 1;
var date = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
return year + "-" + (month = month < 10 ? ("0" + month) : month) + "-" + (date = date < 10 ? ("0" + date) : date) +
" " + (hour = hour < 10 ? ("0" + hour) : hour) + ":" + (minute = minute < 10 ? ("0" + minute) : minute) + ":" + (
second = second < 10 ? ("0" + second) : second);
}
var output;
var websocket;
function init() {
output = document.getElementById("output");
}
/*连接按钮*/
function addsocket() {
var wsaddr = $("#wsaddr").val();
if (wsaddr == '') {
alert("请填写websocket的地址");
return false;
}
StartWebSocket(wsaddr);
}
/*断开按钮*/
function closesocket() {
websocket.close();
}
/*还原按钮*/
function restore(){
$("#wsaddr").val('ws://localhost:8080/myWs');
}
function en(event) {
var evt = evt ? evt : (window.event ? window.event : null);
if (evt.keyCode == 13) {
doSend()
}
}
/*发送按钮*/
function doSend() {
var message = $("#message").val();
if (message == '') {
alert("请先填写发送信息");
$("#message").focus();
return false;
}
if (typeof websocket === "undefined") {
alert("websocket还没有连接,或者连接失败,请检测");
return false;
}
if (websocket.readyState == 3) {
alert("websocket已经关闭,请重新连接");
return false;
}
console.log(websocket);
$("#message").val('');
writeToScreen('<span style="color:green">你发送的信息 ' + formatDate(new Date()) + '</span><br/>' + message);
websocket.send(message);
}
/*书写内容*/
function StartWebSocket(wsUri) {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onclose = function(evt) {
onClose(evt)
};
websocket.onmessage = function(evt) {
onMessage(evt)
};
websocket.onerror = function(evt) {
onError(evt)
};
}
function onOpen(evt) {
writeToScreen("<span style='color:red'>连接成功,现在你可以发送信息啦!!!</span>");
}
function onClose(evt) {
writeToScreen("<span style='color:red'>websocket连接已断开!!!</span>");
websocket.close();
}
function onMessage(evt) {
writeToScreen('<span style="color:blue">服务端回应 ' + formatDate(new Date()) + '</span><br/><span class="bubble">' +
evt.data + '</span>');
}
function onError(evt) {
writeToScreen('<span style="color: red;">发生错误:</span> ' + evt.data);
}
function writeToScreen(message) {
var div = "<div class='newmessage'>" + message + "</div>";
var d = $("#output");
var d = d[0];
var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
$("#output").append(div);
if (doScroll) {
d.scrollTop = d.scrollHeight - d.clientHeight;
}
}
</script>
</body>
</html>
4、新建一个后台发送测试类
java
package com.example.it.springboot.controller;
import com.example.it.springboot.websocket.WsServerEndpoint;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.io.IOException;
@Controller
public class TestController {
private WsServerEndpoint wsServerEndpoint;
//localhost:8080/hello
@GetMapping("/hello")
public String setHello2() {
System.out.println("Hello ???");
wsServerEndpoint.sendMessage("我发了一个测试","0");
return "Hello";
}
}