spring整合websocket(一)

1.pom文件引入依赖:spring.version为对应的spring版本

<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.配置文件

<?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: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/websocket
            http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd">
 	<!-- 配置webSocket  -->
    <!-- websocket消息处理bean -->
    <bean id="WebsocketHandler" class="com.thinkgem.jeesite.modules.meeting.websocket.WebsocketHandler"/>
    <websocket:handlers>
        <!-- 配置消息处理bean和路径的映射关系 -->
        <websocket:mapping path="/websocket" handler="WebsocketHandler"/>
        <!-- 配置握手拦截器 -->
        <websocket:handshake-interceptors>
            <bean class="com.thinkgem.jeesite.modules.meeting.websocket.HandshakeInterceptor"/>
        </websocket:handshake-interceptors>
        <!-- 开启sockjs,去掉则关闭sockjs -->
        <!--<websocket:sockjs/>-->
    </websocket:handlers>
    <!-- 配置websocket消息的最大缓冲区长度 -->
    <bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
        <property name="maxTextMessageBufferSize" value="8192"/>
        <property name="maxBinaryMessageBufferSize" value="8192"/>
    </bean>
</beans>   

3.java代码

package com.thinkgem.jeesite.modules.meeting.websocket;

import java.util.Map;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import com.thinkgem.jeesite.modules.meeting.utils.Constant;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;

@Service
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request,
                                   ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Map<String, Object> attributes) throws Exception {
        System.out.println("Before Handshake ... 握手前......");
        // 解决The extension [x-webkit-deflate-frame] is not supported问题
 		if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
 			request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
 		}
 		// 使用userid区分WebSocketHandler,以便定向发送消息(使用shiro获取session)  
 		String userid = UserUtils.getUser().getId();
 		if (userid == null) {
 			userid = "default-system";
 		}
 		attributes.put(Constant.WEBSOCKET_USERID, userid);
        
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request,
                               ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception ex) {
        System.out.println("After Handshake ... 握手后 ......");
        super.afterHandshake(request, response, wsHandler, ex);
    }
}
package com.thinkgem.jeesite.modules.meeting.websocket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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

import com.thinkgem.jeesite.modules.meeting.utils.Constant;

public class WebsocketHandler extends TextWebSocketHandler {
	
	//存储用户
	private static final List<WebSocketSession> users = new ArrayList<>();
	
	//接收到客户端消息时调用
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        System.out.println("text message: " + session.getPrincipal() + "-" + message.getPayload());
        String text = "get message by "+session.getPrincipal()+":"+message.getPayload();
        System.out.println(text);
        session.sendMessage(new TextMessage(text.getBytes()));
    }

   //用户进入系统监听
    @Override
    public void afterConnectionEstablished(WebSocketSession session)
            throws Exception {
        users.add(session);
    }

    // 消息传输出错时调用
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.out.println("handleTransportError");
    }

	// 一个客户端连接断开时关闭
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        System.out.println("afterConnectionClosed");
        if (session.isOpen()) {
            session.close();
        }
        users.remove(session);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
    
    /**
     * 给所有的用户发送消息
     */
    public void sendMessagesToUsers(TextMessage message) {
        for (WebSocketSession user : users) {
            try {
                //isOpen()在线就发送
                if (user.isOpen()) {
                    user.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 发送消息给指定的用户
     */
    public void sendMessageToUser(String userId, TextMessage message) {
        for (WebSocketSession user : users) {
            if (user.getAttributes().get(Constant.WEBSOCKET_USERID).equals(userId)) {
                try {
                    //isOpen()在线就发送
                    if (user.isOpen()) {
                        user.sendMessage(message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4.前端页面

<%@ page language="java" import="java.util.*"
	contentType="text/html;charset=UTF-8"%>
<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
<%@include file="/WEB-INF/views/include/head.jsp"%>
<html>
<head>
	<title>test</title>
	<meta name="decorator" content="default" />
	<meta charset="UTF-8">
	<!-- <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script> -->
	<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
	<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
	<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script>
	<!-- <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script> -->
	<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
	<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
	<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
	<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
	<title>测试</title>
	<script type="text/javascript">
	
    var stomp,sock;
    
	$(document).ready(function () {
		if (window.WebSocket){
			websocketConfig();
		} else {
			alert("错误","浏览器不支持websocket技术通讯.");
		}
	});
 
    //websocket配置
	function websocketConfig() {
		/* if('WebSocket' in window) {
            console.log("此浏览器支持websocket");
            sock = new WebSocket("ws://localhost:8080"+ctx+"/webSocket");
        } else {
			//连接url为endpointChat的endpoint,对应后台WebSoccketConfig的配置
        } */
      //SockJS所处理的URL是http://或https://,不再是ws://和wss://
        //使用相对URL。例如,如果包含JavaScript的页面位于"http://localhost:8080/websocket"的路径下
		sock = new SockJS("http://localhost:8080/hprd_business/webSocket");
		sockHandle();
		stompConfig();
	}
   
	function stompConfig() {
		//使用STOMP子协议的websocket客户端
		console.log("Connection status  "+sock.readyState);
		stomp = Stomp.over(sock);
		stomp.connect({}, function(frame) {
			//这里的订阅地址和controller的convertAndSendToUser地址一致,多出的user必须的,指的是用户之间发送消息
			//这里的地址和后台的Controller sendChatMsg方法的chatAddress 一致
			stomp.subscribe("/user/queue/showQRCode", function (message) {
				//处理响应消息
				var json = JSON.parse(message.body);
				console.log(json);
			});
	 
			//订阅处理错误的消息地址,接收错误消息
			stomp.subscribe("/user/queue/contactErrors${chatId}", function (message) {
					var response = JSON.parse(message.body);
					var error = response.error;
					alert("发送失败"+error);
			});
		});
	}
	//发送消息
	function sendMessage() {
		//文本框的内容
		var content =  $("#content").val();
		if ($.trim($("#content").val()).length <= 0){
			return ;
		}
		//拼接成json传到后台
		var data = {
			 chatId:'${chatId}',
			 schoolId:'${schoolId}',
			 toUserId:'${receiverId}',
			 content:content,
			 fromUserId:'${accountId}',
			 appId:'${appId}',
			 msgType:1
		};
		//发送
		stomp.send("/sendChatMsg",{},JSON.stringify(data) );
	}
 
	function sockHandle() {
		sock.onopen = function () { 
			console.log("------连接成功------"); 
		};
		sock.onmessage = function (event) {
			console.log('-------Received: ' + event.data);
		};
		sock.onclose = function (event) {
			console.log('--------Info: connection closed.------');
		};
        //连接发生错误
		sock.onerror = function () {
             alert("连接错误", "网络超时或通讯地址错误.");
             disconnect();
		};
	}
	//关闭websocket
	function disconnect() {
		if (sock != null) {
			sock.close();
			sock = null;
		}
	}

    </script>
</head>

<body>
	<div class="page-header" id="tou">webSocket多终端聊天测试</div>
	<div class="well" id="msg"></div>
	<div class="col-lg">
		<div class="input-group">
			<input type="text" class="form-control" placeholder="发送信息..."
				width="10" id="message"> <span class="input-group-btn">
				<button class="btn btn-default" type="button" id="send">发送</button>
			</span>
		</div>
	</div>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值