SpringMVC集成websocket

1.在pom文件中添加依赖

			<properties>
				<spring.version>4.3.20.RELEASE</spring.version>
			</properties>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-websocket</artifactId>
				<version>${spring.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-messaging</artifactId>
				<version>${spring.version}</version>
			</dependency>

2.注册处理适配器

MyWebSocketConfig.java

package com.myc.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.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
@EnableWebMvc
@EnableWebSocket
public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

		// 前台 可以使用websocket环境
		registry.addHandler(myWebSocketHandler(), "/websocket").addInterceptors(new HandshakeInterceptor())
				.setAllowedOrigins("*");

		// 前台 不可以使用websocket环境,则使用sockjs进行模拟连接
		registry.addHandler(myWebSocketHandler(), "/sockjs/websocket").addInterceptors(new HandshakeInterceptor())
				.setAllowedOrigins("*").withSockJS();
	}

	// websocket 处理类
	@Bean
	public WebSocketHandler myWebSocketHandler() {
		return new MyWebSocketHandler();
	}

}

3.添加拦截器

HandshakeInterceptor.java

package com.myc.websocket;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
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.support.HttpSessionHandshakeInterceptor;

public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {

	// 握手前
	@Override
	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
			Map<String, Object> attributes) throws Exception {

		System.out.println("++++++++++++++++ HandshakeInterceptor: beforeHandshake  ++++++++++++++" + attributes);
		HttpServletRequest httpRequest = ((ServletServerHttpRequest) request).getServletRequest();
		String uid = httpRequest.getParameter("uid");
		if (StringUtils.isNoneBlank(uid)) {
			attributes.put("uid", uid);
		}
		return super.beforeHandshake(request, response, wsHandler, attributes);
	}

	// 握手后
	@Override
	public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
			Exception ex) {

		System.out.println("++++++++++++++++ HandshakeInterceptor: afterHandshake  ++++++++++++++");

		super.afterHandshake(request, response, wsHandler, ex);
	}

}

4.添加处理适配器

MyWebSocketHandler.java

package com.myc.websocket;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import com.alibaba.fastjson.JSON;

public class MyWebSocketHandler implements WebSocketHandler {

	private static final Logger log = LoggerFactory.getLogger(MyWebSocketHandler.class);

	// 保存未登录用户session
	private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>();
	// 保存登录用户session
	private static final HashMap<Long, WebSocketSession> uidUsers = new HashMap<>();

	// 连接 就绪时
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		Map<String, Object> map = session.getAttributes();
		if (map != null) {
			String uid = (String) map.get("uid");
			if (uid != null) {
				uidUsers.put(Long.valueOf(uid), session);
			} else {
				users.add(session);
			}
		} else {
			users.add(session);
		}
		log.info("connect websocket success.......");
	}

	// 处理信息
	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {

		// 将消息JSON格式通过Gson转换成Map
		// message.getPayload().toString() 获取消息具体内容
		Map<String, Object> msg = JSON.parseObject(message.getPayload().toString(), HashMap.class);

		log.info("handleMessage......." + message.getPayload() + "..........." + msg);

		// session.sendMessage(message);

		// 处理消息 msgContent消息内容
		TextMessage textMessage = new TextMessage(msg.get("msgContent").toString(), true);
		// 调用方法(发送消息给所有人)
		sendMsgToAllUsers(textMessage);

	}

	// 处理传输时异常
	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		// TODO Auto-generated method stub

	}

	// 关闭 连接时
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {

		log.info("connect websocket closed.......");

		users.remove(session);

	}

	@Override
	public boolean supportsPartialMessages() {
		// TODO Auto-generated method stub
		return false;
	}

	// 给所有用户发送 信息
	public void sendMsgToAllUsers(WebSocketMessage<?> message) throws Exception {

		for (WebSocketSession user : users) {
			user.sendMessage(message);
		}

	}

	public void sendMsgToAllUsers(TextMessage msg) throws IOException {
		for (WebSocketSession user : users) {
			user.sendMessage(msg);
		}
		for (WebSocketSession user : uidUsers.values()) {
			user.sendMessage(msg);
		}
	}

	public void sendMsgToUser(Long uid, TextMessage msg) throws IOException {
		for (Long key : uidUsers.keySet()) {
			if (key.equals(uid)) {
				uidUsers.get(uid).sendMessage(msg);
				break;
			}
		}
	}

}

5.控制器

TestSocketController.java

package com.myc.controller;

import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.socket.TextMessage;
import com.myc.websocket.MyWebSocketHandler;

@RestController
@RequestMapping("/api")
public class TestSocketController {

	@Autowired
	MyWebSocketHandler myHandler;
	
	@GetMapping("/websocket")
	public String handle(String uid) throws IOException {
		if (StringUtils.isEmpty(uid)) {
			myHandler.sendMsgToAllUsers(new TextMessage("我是群发"));
		}else {
			myHandler.sendMsgToUser(Long.valueOf(uid),new TextMessage("我是私发"));
		}
	    return "ok";
	}
}

6.测试页面

websocket.html

<!DOCTYPE HTML>
<html>

    <head>
        <title>首页</title>

        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="renderer" content="webkit">

        <!-- 引入 JQuery  -->
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

        <!-- 引入 sockJS  -->
        <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js" ></script>

        <!-- 自定义JS文件 -->
        <script type="text/javascript">
			window.onload = function() {

				 var websocket;

				var uid =116;
				// 首先判断是否 支持 WebSocket
				if('WebSocket' in window) {
				<!--	websocket = new WebSocket("ws://localhost:8081/websocket?uid="+uid);-->
					websocket = new WebSocket("ws://localhost:8081/websocket");
					console.log("type=1");
				} else if('MozWebSocket' in window) {
					websocket = new MozWebSocket("ws://localhost:8081/websocket"+uid);
					console.log("type=2");
				} else {
					websocket = new SockJS("http://localhost:8081/sockjs/websocket"+uid);
					console.log("type=3");
				}

				// 打开时
				websocket.onopen = function(evnt) {
					console.log("  websocket.onopen  ");
				};


				// 处理消息时
				websocket.onmessage = function(evnt) {
					$("#msg").append("<p>(<font color='red'>" + evnt.data + "</font>)</p>");
					console.log("  websocket.onmessage   ");
				};


				websocket.onerror = function(evnt) {
					console.log("  websocket.onerror  ");
				};

				websocket.onclose = function(evnt) {
					console.log("  websocket.onclose  ");
				};
				
				// 点击了发送消息按钮的响应事件
				$("#group").click(function(){
					htmlobj=$.ajax({url:"http://localhost:8081/api/websocket",async:false});
				});
				$("#single").click(function(){
					htmlobj=$.ajax({url:"http://localhost:8081/api/websocket?uid="+uid,async:false});
				});
				// 点击了发送消息按钮的响应事件
				$("#TXBTN").click(function(){

					// 获取消息内容
					var text = $("#tx").val();

					// 判断
					if(text == null || text == ""){
						alert(" content  can not empty!!");
						return false;
					}

					var msg = {
						msgContent: text,
						uid: 116
					};

					// 发送消息
					websocket.send(JSON.stringify(msg));

				});


			};
		
		</script>

    </head>

    <body>

        <!-- 最外边框 -->
        <div style="margin: 20px auto; border: 1px solid blue; width: 300px; height: 500px;">

            <!-- 消息展示框 -->
            <div id="msg" style="width: 100%; height: 56%; border: 1px solid yellow;overflow: auto;"></div>

            <!-- 消息编辑框 -->
            <textarea id="tx" style="width: 100%; height: 20%;"></textarea>

            <!-- 消息发送按钮 -->
            <button id="TXBTN" style="width: 100%; height: 8%;">发送数据</button>
			<!-- 消息发送按钮 -->
            <button id="group" style="width: 100%; height: 8%;">群发</button>
			<button id="single" style="width: 100%; height: 8%;">私发</button>
        </div>


    </body>

</html>

7.web.xml配置

在原来的xml中添加

<async-supported>true</async-supported>

8.websocket配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-4.0.xsd 
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 
            http://www.springframework.org/schema/websocket
            http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd">
			
            <!-- websocket处理类 -->
            <bean id="myHandler" class="com.myc.websocket.MyWebSocketHandler"/>

            <!-- 握手接口/拦截器 -->
            <bean id="myInterceptor" class="com.myc.websocket.HandshakeInterceptor"/>

            <websocket:handlers >
                <websocket:mapping path="/websocket" handler="myHandler"/>
                <websocket:handshake-interceptors>
                    <ref bean="myInterceptor"/>
                </websocket:handshake-interceptors>
            </websocket:handlers>

            <!--  注册 sockJS -->
            <websocket:handlers>
                <websocket:mapping path="/sockjs/websocket" handler="myHandler"/>
                <websocket:handshake-interceptors>
                    <ref bean="myInterceptor"/>
                </websocket:handshake-interceptors>
                <websocket:sockjs />
            </websocket:handlers>   

</beans>     

9.效果如下

这是依次点了下群发、私发、发送数据的按钮,群发可以打开多个页面测试
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值