spingmvc 实现websoket

本文介绍了一个基于Spring的WebSocket应用实现,重点在于如何通过会话管理确保消息能够准确地发送到正确的客户端。文章详细展示了如何利用Spring框架提供的工具来实现WebSocket连接的建立、维护和断开,并通过唯一标识符进行消息定向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先是前端页面定义
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>

jyl

下面是 在请求发过来到服务端时 进行会话的添加 用于标识这个哪一个会话 因为 服务端会有很多的连接

package com.jyl.ws;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.HttpSession;
import java.util.Map;

@Component
public class WebSocketInterceptor implements HandshakeInterceptor {

public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
	Map<String, Object> map) throws Exception {
	
	if (request instanceof ServletServerHttpRequest) {
		ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
		HttpSession session = serverHttpRequest.getServletRequest().getSession();
		if (session != null) {
		//这里的username  就是获取你那个唯一标识的id
			map.put(MyHandler.CLIENT_ID, session.getAttribute("username"));
		}
		else
		{
		  return false;
		}

	}
	return true;
}

public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse,
		WebSocketHandler webSocketHandler, Exception e) {

}

}

package com.jyl.ws;

import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

这里在创建连接以后 成功的把 那个 session 存到 session 池 这样 才可以 准确的 下次去发请求给谁
@Service
public class MyHandler extends TextWebSocketHandler {
private static final Map<String, WebSocketSession> users;
public static final String CLIENT_ID = “username”;

static {
    users = new HashMap<String, WebSocketSession>();
}

@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
    String username= getClientId(session);
    if (username != null) {
        users.put(username, session);
        session.sendMessage(new TextMessage("成功建立socket连接"));
        System.out.println("建立连接:" + username);
    }
}

@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
    try {
    	System.out.println(message.getPayload());
    	WebSocketMessage msg = new TextMessage("server:"+message);
        session.sendMessage(msg);
    } catch (IOException e) {
        e.printStackTrace();
    }
}


public boolean sendMessageToUser(String clientId, TextMessage message) {
    if (users.get(clientId) == null) return false;
    
    WebSocketSession session = users.get(clientId);
    System.out.println("sendMessage:" + session);
    if (!session.isOpen()) return false;
    
    try {
        session.sendMessage(message);
    } catch (IOException e) {
        System.out.println(e);
        return false;
    }
    return true;
}
public boolean sendMessageToAllUsers(TextMessage message) {
    Set<String> clientIds = users.keySet();
    WebSocketSession session = null;
    for (String clientId : clientIds) {
        try {
            session = users.get(clientId);
            if (session.isOpen()) {
                session.sendMessage(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return  false;
        }
    }
    return  true;
}


private String getClientId(WebSocketSession session) {
    try {
        String clientId = (String) session.getAttributes().get(CLIENT_ID);
        return clientId;
    } catch (Exception e) {
        return null;
    }
}

@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
    if (session.isOpen()) {
        session.close();
    }
    System.out.println("连接出错");
    users.remove(getClientId(session));
}

@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
    System.out.println("连接已关闭:" + status);
    users.remove(getClientId(session));
}

@Override
public boolean supportsPartialMessages() {
    return false;
}

}

package com.jyl.ws;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

存入自定义的过滤个拦截器

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){
    registry.addHandler(myHandler(), "/myHandler").addInterceptors(new WebSocketInterceptor()).setAllowedOrigins("*");
}



@Bean
public WebSocketHandler myHandler() {
    return new MyHandler();
}

}

controller

请求 :

package com.jyl.controller;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.socket.TextMessage;

import com.jyl.ws.MyHandler;

@Controller
public class JylController {
@Autowired
MyHandler handler;

@RequestMapping("/login/{username}")
public String  login(HttpSession session, @PathVariable("username") String username) {
    session.setAttribute(MyHandler.CLIENT_ID, username);
    System.out.println("登录:" + session.getAttribute(MyHandler.CLIENT_ID));
   	return "jyl";
}

@RequestMapping("/msg/{username}/{msg}")
public @ResponseBody String sendMessage(@PathVariable("username") String username,@PathVariable("msg") String msg) {   	   	
    handler.sendMessageToUser(username, new TextMessage(msg));
    return "";
}

}

其他配置再说
https://blog.csdn.net/jiyanglin/article/details/87899729?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-87899729-blog-94554033.pc_relevant_scanpaymentv1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-87899729-blog-94554033.pc_relevant_scanpaymentv1&utm_relevant_index=2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值