springboot websocket简单聊天

客户端测试工具:coolaf.com/tool/chattest

可以打开两个窗口,模拟用户1用户2聊天,并以userId来区分不同的用户(客户端的唯一标识)。
localhost:8080/webSocket?userId=1
localhost:8080/webSocket?userId=2

pom.xml

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

创建websocket服务端:
/socket/DemoWebSocketHandler.java

@Component
public class DemoWebSocketHandler implements WebSocketHandler{

	// key 用户(客户端标识)value 会话,用来存放每个客户端对应的WebSocketSession对象
	private final Map<Integer, WebSocketSession> webSocketSeesionMap = new HashMap<>();
	
	// websocket连接成功时触发
	@Override
	public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
		// 当我们和客户端建立连接之后,我们可以得到一个会话ID webSocketSession.getId()

		// 获取用户ID(在这里是不能获取url参数,要通过拦截器去获取url参数)
		Map<Striing, Object> attributes = webSocketSession.getAttributes();// 取得拦截器里的那个map
		Integer userId = attributes.get("userId");

		// 接下来把这个userId当成一个key,然后把webSocketSession当成一个value,存到本类的成员变量map集合里
		webSocketSeesionMap.put(userId, webSocketSession);

	}

	// 收到客户端消息时触发
	@Override
	public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
		// 获取来自客户端的消息
		String message = String.valueOf(webSocketMessage.getPayload());
		
		// 获取当前url的用户ID
		Map<String, Object> attributes = webSocketSession.getAttributes();// 取得拦截器里的那个map
		Integer urlUserId = attributes.get("userId");

		// 接下来可以让用户1给用户2发送一条消息
		// 遍历webSocketSeesionMap
		webSocketSeesionMap.forEach((userId,value) => {
			// 判断当前用户ID是不是传递突来的用户ID
			if (userId.equals(urlUserId)) {
				// 如果当前用户ID是他自己(url也是他)的话
				// 那就直接跳过
			}else {
				// 如果不是,把客户端传递过来的Message干到参数里面
				value.sendMessage(new TextMessage(message));
			}
		});

		// 向客户端发送消息
		//webSocketSession.sendMessage(new TextMessage("你好"));

	}

	// websocket连接发生错误时触发
	@Override
	public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
		// 这里可以拿到异常对象throwable
	}

	// websocket连接关闭时触发
	@Override
	public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
		// 一般在连接关闭时,就需要把这个会话从缓存里面移除掉
		
		// 获取当前url的用户ID
		Map<String, Object> attributes = webSocketSession.getAttributes();// 取得拦截器里的那个map
		Integer urlUserId = attributes.get("userId");

		webSocketSessionMap.remove(urlUserId);// 移除当前会话

	}

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

接着对websocket服务端做配置:
/websocket/WebSocketConfig.java

@Configuration
@EnableWebSocket // 表示开启服务端websocket
public class WebSocketConfig imlements WebSocketConfigurer{

	@Resocure
	private DemoWebSocketHandler demoWebSocketHandler;

	@Resource
	private WebSocketInterceptor webSocketInterceptor;// 拦截器

	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
		// 在这里对websocket做一些配置
		webSocketHandlerRegistry.addHandler(demoWebSocketHandler, "/websocket")// 添加一个websocket处理器,websocket链接地址。
			.addInterceptors(webSocketInterceptor)// 可以传递若干个拦截器
			.setAllowedOrigins("*");// 允许跨域访问
	}
}

/webSocket/WebSocketInterceptor.java

@Component
public class WebSocketInterceptor extends HttpSessionHandShackInterceptor {
	
	// 在webSocket连接之前调用
	@Override
	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> atributes) throws Exception {
		if (request instanceof ServletServerHttpRequest) {
			ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest)request;
			ServletRequest servletRequest = servletServerHttpRequest.getServletRequest();
			Integer userId = Integer.valueOf(servletRequest.getParameter("userId"));
			
			// 把获取的参数放到map里面
			attributes.put("userId", userId);
		}
		return super.beforeHandShake(request, response, wsHandler, attributes);
	}
}

以上内容源于网络

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值