spring websocket实现

注:需spring4.0及以上版本。

步骤:

1、导入jar包(maven方式)

<!-- Spring websocket -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>4.3.10.RELEASE</version>
</dependency>

2、编写WebSocketConfig类,用于配置websocket

package com.websocket;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
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
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{

	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		//允许连接的域;只能以http或https开头
		String[] allowsOrigins = {"https://www.xxx.com"};
		//WebIM WebSocket通道
		registry.addHandler(WebSocketHandler(), "/websocket").addInterceptors(WebScoketInterceptor());
	}
	@Bean
	public WebSocketHandler WebSocketHandler() {
		return WebSocketHandler();
	}
	@Bean
	public WebScoketInterceptor WebScoketInterceptor() {
		return new WebScoketInterceptor();
	}
}

也可用spring的配置文件:

文件头部添加websocket的xsd文件:

xmlns:websocket="http://www.springframework.org/schema/websocket"
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket.xsd
<!-- websocket处理器 -->
<bean id="websocket" class="com.websocket.WebSocketHandler"></bean>
<websocket:handlers>
	<websocket:mapping path="/websocket" handler="websocket"></websocket:mapping>
	<!-- websocket拦截器 -->
	<websocket:handshake-interceptors>
		<bean class="com.websocket.WebScoketInterceptor"/>
	</websocket:handshake-interceptors>
</websocket:handlers>

3、编写WebScoketInterceptor,拦截器的作用是将此连接与用户对应

package com.websocket;

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

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

public class WebScoketInterceptor implements HandshakeInterceptor{

	@Override
	public void afterHandshake(ServerHttpRequest httpRequest, ServerHttpResponse httpResponse, WebSocketHandler handler, Exception e) {
		
	}

	@Override
	public boolean beforeHandshake(ServerHttpRequest httpRequest, ServerHttpResponse httpResponse, WebSocketHandler handler,
			Map<String, Object> map) throws Exception {
		ServletServerHttpRequest request = (ServletServerHttpRequest) httpRequest;
		//获取httpSession拿到此链接对应的用户,websocket中可以拿到http协议对应的httpSession
		HttpSession session = request.getServletRequest().getSession();
		if (session != null) {
			map.put("userId", session.getAttribute("userId"));
		}
		return true;
	}
}

4、编写WebSocketHandler,继承自AbstractWebSocketHandler,提供了建立连接,关闭连接,连接发生错误等回调方法,用于实现自己的业务逻辑

package com.websocket;

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

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
/**
 * websocket处理器
 * @author Administrator
 *
 */
public class WebSocketHandler extends AbstractWebSocketHandler {
	private static final Map<Integer, WebSocketSession> wsUserMap = new HashMap<Integer, WebSocketSession>();
	/**
	 * 处理前端发送的文本信息
	 * @throws IOException
	 */
	@Override
	public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		Integer userId = getUserIdBySession(session);
		System.out.println("收到userId为:" + userId + "的用户发的消息" + message.toString());
		//给用户回复一条消息
//		session.sendMessage(new TextMessage("reply msg:" + message.getPayload()));
	}
	/**
	 * 成功建立连接
	 */
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		Integer userId = getUserIdBySession(session);
		wsUserMap.put(userId, session);
		super.afterConnectionEstablished(session);
		System.out.println("用户id为" + userId + "的用户建立连接");
	}
	/**
	 * 关闭连接
	 */
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		Integer userId = getUserIdBySession(session);
		wsUserMap.remove(userId);
		super.afterConnectionClosed(session, status);
		System.out.println("用户id为" + userId + "的用户关闭了连接");
	}
	/**
	 * 连接发生错误
	 */
	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		exception.printStackTrace();
		Integer userId = getUserIdBySession(session);
		wsUserMap.remove(userId);
		super.handleTransportError(session, exception);
	}
	/**
	 * 给某个用户发送消息
	 */
	public static boolean sendMessageToUser(Integer userId,Integer toUserId, TextMessage message) {
		WebSocketSession tosession = wsUserMap.get(toUserId);
		if (tosession != null && tosession.isOpen()) {
			try {
				tosession.sendMessage(new TextMessage("{" + userId + ":" + message.getPayload()+ "}"));
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
			return true;
		} else {
			return false;
		}
	}
	/**
	 * 给全部用户发送消息
	 */
	public static void sendMessageToAllUser(TextMessage message) {
		Set<Integer> userSet = wsUserMap.keySet();
		for (Integer i : userSet) {
			WebSocketSession session = wsUserMap.get(i);
			if (session != null && !session.isOpen()) {
				try {
					session.sendMessage(message);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	private Integer getUserIdBySession(WebSocketSession session) {
		Integer userId = (Integer) session.getAttributes().get("userId");
		return userId;
	}
}

5、配置SpringWebSocketConfig了配置类随spring容器启动,此步骤为使用WebSocketConfig类做配置是使用,用spring配置文件做websocket的配置时可省略。

<!-- websocket配置扫描 -->
<context:component-scan base-package="com.websocket"/>

6、创建controller,仅简单测试。

package com.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.socket.TextMessage;

import com.websocket.WebSocketHandler;

@Controller
public class WebSocketController {
	//模拟登录
	@RequestMapping("login")
	public void login(HttpServletRequest request, HttpServletResponse response) {
		int userId = Integer.parseInt(request.getParameter("userId"));
		HttpSession session = request.getSession();
		session.setAttribute("userId", userId);
	}
	//用户给另一用户发送消息
	@RequestMapping("sendMessageToUser")
	public void sendMessageToUser(HttpServletRequest request, HttpServletResponse response) {
		int toUserId = Integer.parseInt(request.getParameter("toUserId"));
		int userId = Integer.parseInt(request.getParameter("userId"));
		CharSequence message = request.getParameter("message");
		TextMessage mess = new TextMessage(message);
		WebSocketHandler.sendMessageToUser(userId, toUserId, mess);
	}
	//给当前所有在线用户发送消息
	
}

7、客户端代码(创建连接部分)

var ws;
function websocketTest() {
	ws = new WebSocket("ws://localhost:8080/websocketTest/websocket");
	ws.open = function() {
		console.log("open");
	}
	ws.onclose = function() {
		console.log("onclose");
	}
	ws.onmessage = function(evt) {
		console.log(evt);
		alert(evt.data);
	};
}


猜你喜欢

转载自blog.csdn.net/weixin_39383071/article/details/80368120
今日推荐