websocket使用springboot实现的详细步骤

2022-08-18 13:47:27

websocket在前端页面加载时实现一次握手通讯后,可相互发送信息。一般用来实现推送服务或短间隔长连接数据请求

springboot实现websocket方式
1、使用maven添加websocket依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
			<version>2.3.0.RELEASE</version>
		</dependency>

2、websocket核心工具类,使用set存储session的目的在于:发送信息时可以将信息通过遍历set发送到所有在线的前端页面客户端,如果需要区分客户端页面实现信息的不同发送,则可以使用ConcurrentHashMap<String,Session>

import java.io.IOException;
import java.util.concurrent.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工具类
 */
@ServerEndpoint(value ="websocket")
@Component
public class WebSocketServer {
 
	// 与某个客户端的连接会话后,需要通过它来给客户端发送数据
	private Session session;
  
    // 用于存储session会话对象的set集合
    private static CopyOnWriteArraySet<Session> webSocketSet = new CopyOnWriteArraySet<Session>();

	@OnOpen
	public void onOpen(Session session) {
		this.session = session;
		System.out.println("连接已建立: "+session);
		webSocketSet.add(session);
	}

	
	public void sendMessage(String message) throws IOException {
		System.out.println("向当前在线的 "+webSocketSet.size()+" 个客户端,发送信息: "+message);
		for(Session s : webSocketSet ){
			s.getBasicRemote().sendText(message);
		}
		
	}

	@OnClose
	public void onClose() {
		System.out.println("移除失去联系的session: " + this.session);
		webSocketSet.remove(this.session);
	}

	@OnMessage
	public void onMessage(String message, Session session) {
		System.out.println("来自客户端的消息:" + message);
	}

	@OnError
	public void onError(Session session, Throwable error) {
		System.out.println("发生错误");
		error.printStackTrace();
	}

}

3、在springboot项目中开启websocket支持,注意:如果需要将springboot项目打成war包部署到tomcat中时,需要将该类方法注释掉,因为tomcat不需要使用此方法开启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();
	}

}

4、controller调用websocket进行测试

	@Autowired
	private WebSocketServer websocket;

	/**
	 * 接收数据
	 */
	@RequestMapping(value="/receive")
	public void receive(HttpServletRequest request){
			// 使用websocket刷新指定页面
			try {
				websocket.sendMessage("1010");
			} catch (IOException e) {
				e.printStackTrace();
			}
	}

5、HTML页面,可在控制台console中查看websocket数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="row">websocket</div>
<script src="resocket.js"></script>
<script>
    socket = new ReconnectingWebSocket("ws://127.0.0.1:8080/ws/bitcoinServer");
    //连接打开事件
    socket.onopen = function () {
        console.log("Socket 已打开");
        //socket.send("消息发送测试(From Client)");
    };

    socket.onclose = () => {
       alert("失去连接,请刷新页面")
    };
	

	socket.readyState = function (e) {
        console.log("连接状态:"+e.data);
    }
	
    socket.onmessage = function (e) {
        console.log(e.data);
    }
</script>
</body>
</html>

6、赠送resocket.js代码

!function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a});
  • 作者:在线笔记本
  • 原文链接:https://blog.csdn.net/wangshao5122/article/details/106922399
    更新时间:2022-08-18 13:47:27