ssm 整合websocket

前段时间写了个一对一实时聊天,且将数据保存到数据库,所以需将websocket与ssm整合,方便使用注解。

1、pom.xml中添加需要的jar文件

		<dependency>
			<groupId>javax.websocket</groupId>
			<artifactId>javax.websocket-api</artifactId>
			<version>1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-websocket</artifactId>
			<version>4.1.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-messaging</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.3.1</version>
		</dependency>

2、创建拦截器类

public class MyHandShakeInterceptor implements HandshakeInterceptor {

	public boolean beforeHandshake(ServerHttpRequest serverHttpRequest,
			ServerHttpResponse serverHttpResponse,
			WebSocketHandler webSocketHandler, Map<String, Object> map)
			throws Exception {
		if (serverHttpRequest instanceof ServletServerHttpRequest) {
			ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) serverHttpRequest;
			HttpSession session = servletRequest.getServletRequest()
					.getSession(false);
			// 获取登录时保存到session中的用户信息
			UserInfo userInfo = (UserInfo) session.getAttribute("userInfo");
			if (userInfo != null) {
				map.put("userId", userInfo.getId());//为服务器创建WebSocketSession做准备
			} else {
				return false;
			}
		}
		return true;
	}

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

	}
}

3、创建WebSocketMap工具类

public class WebSocketMapService {
	public static final ConcurrentMap<Integer, WebSocketSession> webSocketSessionMap;
	static {
		webSocketSessionMap = new ConcurrentHashMap<Integer, WebSocketSession>();
	}

	public static void put(Integer key, WebSocketSession myWebSocket) {
		webSocketSessionMap.put(key, myWebSocket);
	}

	public static WebSocketSession get(Integer key) {
		return webSocketSessionMap.get(key);
	}

	public static void remove(Integer key) {
		webSocketSessionMap.remove(key);
	}

	public static Collection<WebSocketSession> getValues() {
		return webSocketSessionMap.values();
	}

	public static Set<Entry<Integer, WebSocketSession>> entrySet() {
		return webSocketSessionMap.entrySet();
	}
}

4、创建websocket处理类

@Component
public class MyWebSocketHandler implements WebSocketHandler {

	@Autowired
	private MessageInfoService messageInfoService;

	//握手实现连接后
	public void afterConnectionEstablished(WebSocketSession webSocketSession)
			throws Exception {
		int userId = (Integer) webSocketSession.getAttributes().get("userId");
		if (WebSocketMapService.get(userId) == null) {
			WebSocketMapService.put(userId, webSocketSession);
		}
	}

	//发送信息前的处理
	public void handleMessage(WebSocketSession webSocketSession,
			WebSocketMessage<?> webSocketMessage) throws Exception {

		if (webSocketMessage.getPayloadLength() == 0)
			return;
		//获取Socket通道中的数据
		JSONObject object = JSONObject
				.parseObject(webSocketMessage.getPayload().toString());
		MessageInfo messageInfo = new MessageInfo();
		//...
		//将信息保存至数据库
		messageInfoService.insertMessage(messageInfo);
		// 给自己发送消息
		sendMessageToUser(messageInfo.getSenduserid(),
				new TextMessage(
						new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
								.create().toJson(messageInfo)));
		// 给对方发送消息
		sendMessageToUser(messageInfo.getReuserid(),
				new TextMessage(
						new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss")
								.create().toJson(messageInfo)));
	}

	public void handleTransportError(WebSocketSession webSocketSession,
			Throwable throwable) throws Exception {

	}

	public void afterConnectionClosed(WebSocketSession webSocketSession,
			CloseStatus closeStatus) throws Exception {
		//断开连接即将此用户对应的WebSocketSession移除,以便再次连接时添加新的WebSocketSession
		Iterator<Map.Entry<Integer, WebSocketSession>> iterator = WebSocketMapService
				.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<Integer, WebSocketSession> entry = iterator.next();
			if (entry.getValue().getAttributes()
					.get("userId") == webSocketSession.getAttributes()
							.get("userId")) {
				WebSocketMapService.remove((Integer) webSocketSession
						.getAttributes().get("userId"));
			}
		}
	}

	public boolean supportsPartialMessages() {
		return false;
	}

	//发送信息的实现
	public void sendMessageToUser(Integer userId, TextMessage message)
			throws IOException {
		WebSocketSession session = WebSocketMapService.get(userId);
		if (session != null && session.isOpen()) {
			session.sendMessage(message);
		}
	}
}

5、创建配置类 (也可使用配置文件)

@Component
@EnableWebSocket
public class MyWebSocketConfig extends WebMvcConfigurerAdapter
		implements WebSocketConfigurer {

	@Autowired
	MyWebSocketHandler handler;

	public void registerWebSocketHandlers(
			WebSocketHandlerRegistry webSocketHandlerRegistry) {

		//添加websocket处理器,添加握手拦截器
		webSocketHandlerRegistry.addHandler(handler, "/ws")
				.addInterceptors(new MyHandShakeInterceptor());

		//添加websocket处理器,添加握手拦截器
		webSocketHandlerRegistry.addHandler(handler, "/ws/sockjs")
				.addInterceptors(new MyHandShakeInterceptor()).withSockJS();
	}
}

6、添加前端(客户端)连接(主要代码)

<script src="../../assets/js/plugins/sockjs/sockjs.js"></script>
        var wsServer = null;
		var ws = null;
		wsServer = "ws://ip:端口/项目名/ws";
		ws = new WebSocket(wsServer); //创建WebSocket对象
		ws.onopen = function(evt) {
			layer.msg("已经建立连接", {
				offset : 0
			});
		};
		ws.onmessage = function(evt) {
			var message = JSON.parse(evt.data);//将数据解析成JSON形式
			showMess(message);//展示消息
		};
		ws.onerror = function(evt) {
			layer.msg("产生异常", {
				offset : 0
			});
		};
		ws.onclose = function(evt) {
			layer.msg("已经关闭连接", {
				offset : 0
			});
		};
...
//发送消息
var data = {};//新建data对象,并规定属性名与相应的值
ws.send(JSON.stringify(data));//将对象封装成JSON后发送至服务器










猜你喜欢

转载自blog.csdn.net/qq_21299835/article/details/80775683