springboot集成websocket

springboot集成websocket

在一些项目中,需要做到实时通讯,目前大部分的选择都是websokect。
话不多说,开始造

添加依赖

<!-- websocket-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

新建websocket服务类

package com.qk.common.shiro;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @时间:2023年5月6日 上午11:07:59
 * @作者:秦二少
 * @描述:websocket服务类
 */
@ServerEndpoint(value = "/websocket/{userId}")
@Component
public class WebSocketServer {
	private final static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
	
    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<String,WebSocketServer>();
 
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    
    public static ConcurrentHashMap<String, WebSocketServer> getWebSocketMap() {
		return webSocketMap;
	}
	public static void setWebSocketMap(ConcurrentHashMap<String, WebSocketServer> webSocketMap) {
		WebSocketServer.webSocketMap = webSocketMap;
	}

    /**
     * @类名: WebSocketServer.java 
     * @时间: 2023年5月6日 上午11:08:17 
     * @作者: 秦二少
     * @param session
     * @param userId
     * @描述: 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        //加入map中
        webSocketMap.put(userId, this);
		//sendMessage("CONNECT_SUCCESS", userId);
		System.out.println("【websocket消息】有新的连接,连接id"+userId+";总数:"+ webSocketMap.size());
    }
 
    /**
     * @类名: WebSocketServer.java 
     * @时间: 2023年5月6日 上午11:08:35 
     * @作者: 秦二少
     * @param userId
     * @描述: 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        //从Map中删除
    	webSocketMap.remove(userId);
    	System.out.println("【websocket消息】连接断开,总数:"+ webSocketMap.size());
    }
 
    /**
     * @类名: WebSocketServer.java 
     * @时间: 2023年5月5日 下午5:30:34 
     * @作者: 秦二少
     * @param message 客户端发送过来的消息
     * @描述: 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message) {
       log.info("来自客户端的消息:" + message);
       if (!message.equals("ping")) {
			System.out.println("【websocket消息】收到客户端发来的消息:"+message);
		}
    }
    /**
     * @类名: WebSocketServer.java 
     * @时间: 2023年5月6日 上午11:08:57 
     * @作者: 秦二少
     * @param session
     * @param error
     * @描述: 发生错误
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }
 
    /**
     * @类名: WebSocketServer.java 
     * @时间: 2023年5月5日 下午5:32:41 
     * @作者: 秦二少
     * @param message 发送的消息
     * @param userId 客户端
     * @描述: 主动向客户端发送消息
     */
  	public static void sendMessage(String message, String userId) {
  		WebSocketServer webSocket = webSocketMap.get(userId);
  		if (webSocket != null) {
  			try {
  				webSocket.session.getBasicRemote().sendText(message);
  				System.out.println("【websocket消息】发送消息成功,用户="+userId+",消息内容"+message.toString());
  			} catch (IOException e) {
  				e.printStackTrace();
  			}
  		}
  	}

    
    /**
     * 群发自定义消息
     */
    /*public static void sendInfo(String message){
        for (String userId : webSocketMap.keySet()) {
            WebSocketServer webSocket = webSocketMap.get(userId);
			webSocket.sendMessage(message,userId);
        }
    }*/
 
}

新增websocket配置类

package com.qk.common.shiro;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
 * @时间:2023年5月6日 上午11:09:59
 * @作者:秦二少
 * @描述:开启WebSocket的支持,并把该类注入到spring容器中
 */
@Configuration
public class WebSocketConfig {
	
	//如果使用了springboot启动项目,则需要bean注入,而如果使用了外置tomcat容器,则并不要bean注入,否侧会报错
    @Bean  
    public ServerEndpointExporter serverEndpointExporter() {  
        return new ServerEndpointExporter();  
	}
	
}

调用方法:

WebSocketServer.sendMessage("这里是你需要发送的消息",userId);

到此后端部分已完成!

新建websocket客户端js

document.addEventListener('readystatechange', e => {
      if (document.readyState == 'complete') {//这个等同于window.onload
    	  var websocket = null;
    	  var wsurl = "";
    	  var userId=$("#qk-userId").val();//获取页面上用户ID
    	  // 判断是http还是https协议兼容各种访问
    	  var qkurl=window.location.href;
    	  if(qkurl.indexOf("你的域名")>=0){
    		  var protocolStr = document.location.protocol;
    		  if(protocolStr == "http:"){
    			  wsurl = "ws://你的域名/websocket/"+userId;
    		  }else if(protocolStr == "https:"){
    			  wsurl = "wss://你的域名/websocket/"+userId;
    		  }
    	  }else{
    		  wsurl = "ws://localhost:8080/websocket/"+userId;
    	  }
    	  //判断当前浏览器是否支持WebSocket
    	  if('WebSocket' in window){
    		  websocket = new WebSocket(wsurl);
    	  }else{
    		  alert('你的浏览器版本过低,建议使用最新版的谷歌浏览器!');
    	  }
    	  //连接发生错误的回调方法
    	  websocket.onerror = function(){
    		  reconnect(wsurl);
    	  };
    	  //连接成功建立的回调方法
    	  websocket.onopen = function(event){
    	  }
    	  //接收到消息的回调方法
    	  websocket.onmessage = function(event){
    		  var obj = JSON.parse(event.data);
    		  buildJsonMsg(obj.tag,obj.msg);
    	  }
    	  //连接关闭的回调方法
    	  websocket.onclose = function(){
    	  }
    	  //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    	  window.onbeforeunload = function(){
    		  websocket.close();
    	  }
    	  //关闭连接
    	  function closeWebSocket(){
    		  websocket.close();
    	  }
    	  //发送消息
    	  /* function send(){
				var message = document.getElementById('text').value;
				var obj = {
					form:""+'${user.username }',//发送方
					to:"admin",//收取方
					msg:message
				};
				websocket.send(JSON.stringify(obj));
			}*/
    	  //组织消息
    	  function buildJsonMsg(tag,msg) {
    		  //在此处将后台传递过来的消息修改到页面中
    	  }
    	  function reconnect(wsurl) {
    		  setTimeout(function () {     //没连接上会一直重连,设置延迟避免请求过多
    			  websocket = new WebSocket(wsurl);
    		  }, 3000);
    	  }
    	   
    	  
      }
})

OK!完成了,就是这么简单!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SpringBoot集成WebSocket可以使用Spring框架提供的WebSocket API来实现。在SpringBoot中,使用WebSocket需要进行以下几个步骤: 1. 添加依赖:在pom.xml文件中添加spring-boot-starter-websocket依赖。 2. 创建WebSocket配置类:创建一个WebSocket配置类,用于配置WebSocket相关的参数,如注册EndPoint、消息编解码器、拦截器等。 3. 创建EndPoint:创建一个WebSocket的EndPoint类,用于处理WebSocket连接、消息发送、关闭等操作。可以通过实现Spring提供的WebSocketHandler接口或者继承TextWebSocketHandler来实现。 4. 添加拦截器:可以添加自定义的拦截器,用于处理WebSocket连接建立、消息发送等事件。 5. 配置WebSocket消息代理:使用Spring提供的消息代理,可以实现WebSocket消息的广播和点对点传递。 以下是一个简单的SpringBoot集成WebSocket的示例代码: 1. 添加依赖 ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建WebSocket配置类 ``` @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/myHandler") .addInterceptors(new WebSocketInterceptor()); } @Bean public WebSocketHandler myHandler() { return new MyHandler(); } } ``` 3. 创建EndPoint ``` public class MyHandler extends TextWebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 处理连接建立事件 } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理消息事件 } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { // 处理连接关闭事件 } } ``` 4. 添加拦截器 ``` public class WebSocketInterceptor extends HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { // 处理连接建立前事件 return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { // 处理连接建立后事件 } } ``` 5. 配置WebSocket消息代理 ``` @Configuration @EnableWebSocketMessageBroker public class WebSocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/myEndpoint") .setAllowedOrigins("*") .withSockJS(); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值