欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

spring配置webSocket

程序员文章站 2022-07-10 13:45:51
1)maven引包: org.springframework spring-websocket ${spring.version}

1)maven引包:

<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)先创建握手接口:

import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import org.apache.commons.lang3.StringUtils;

public class MyWebSocketInterceptor extends HttpSessionHandshakeInterceptor{
/**
* 可在此获取 websocket Session 和 Request
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
System.out.println("Before Handshake");
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
String eqIdValue =servletRequest.getServletRequest().getParameter("userId");
if(StringUtils.isBlank(eqIdValue)){
eqIdValue ="";
}
if(StringUtils.isNotBlank(eqIdValue)){
eqIdValue =eqIdValue.trim();
}
HttpSession session = servletRequest.getServletRequest().getSession(false);
attributes.put("userId", eqIdValue);
attributes.put("sessionId", session.getId());
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);
}
}

3) 创建消息 处理程序类 Service层:

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
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;

@Component

public class WebSocketUtil extends TextWebSocketHandler {

//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
// ConcurrentHashMap 是线程安全的map
public static ConcurrentHashMap<String,WebSocketSession> webSocketSet = new ConcurrentHashMap<String,WebSocketSession>();
/**
* 连接建立成功调用的方法
* */
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
//此处的userId 在握手接口中添加
String userId = session.getAttributes().get("userId").toString();
// WebSocketConstant.putWebSocketSessionByUserId(userId,session); //加入set中
webSocketSet.put(userId, session);
addOnlineCount(); //在线数加1
sendMessage(session,"有新连接加入!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
// String value = message.getPayload();
// if(value==null){value="";}
// value = value.trim();
// WebSocketSession userSession = WebSocketConstant.getWebSocketSessionByUserId(value);
//群发消息
sendMessageToAllUsers( message);
// 收到客户端的消息
System.out.println(message.getPayload());
}

/**
* 发送信息给指定用户
* @param clientId
* @param message
* @return
*/
public static boolean sendMessage(WebSocketSession session,String message) {
return sendMessageToUser(session,StringToTextMessage(message));
}
/**
* 发送信息给指定用户
* @param clientId
* @param message
* @return
*/
public static boolean sendMessageToUser(WebSocketSession session, TextMessage message) {
if (!session.isOpen()) return false;
try {
session.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}

/**
* 广播信息
* @param message
* @return
*/
public void sendMessageToAllUsers(TextMessage message) {
//群发消息
// for(WebSocketSession item : WebSocketConstant.getWebSocketSession().values()) {
for(WebSocketSession item : webSocketSet.values()) {
sendMessageToUser(item,message);
}
}
/**
* 广播信息
* @param message
* @return
*/
public static TextMessage StringToTextMessage(String message) {
if(StringUtils.isBlank(message)){
message ="";
}
return new TextMessage(message);
}

/**
* 发生错误时调用
*
* */
@Override
public void handleTransportError(WebSocketSession session, Throwable error) throws Exception {
if (session.isOpen()) {
session.close();
}
System.out.println("连接出错");
error.printStackTrace();
}
/**
* 连接关闭调用的方法
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
String userId = session.getAttributes().get("userId").toString();
// WebSocketConstant.delWebSocketSessionByUserId(userId);
webSocketSet.remove(userId);
subOnlineCount(); //在线数减1
sendMessageToAllUsers( StringToTextMessage("有一连接关闭!当前在线人数为" + getOnlineCount()) );
}

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

public static synchronized int getOnlineCount() {
return onlineCount;
}

public static synchronized void addOnlineCount() {
WebSocketUtil.onlineCount++;
}

public static synchronized void subOnlineCount() {
WebSocketUtil.onlineCount--;
}
}

4)创建 webSocket Controller层:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
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;

import com.hmkj.core.config.MyWebSocketInterceptor;
import com.hmkj.service.estate.WebSocketUtil;

@Configuration
@EnableWebSocket
@Component
public class WebsocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{

@Autowired //@Autowired 注入方式注入时,WebSocketUtil中的webSocketSet变量不能共用,只能保存一个WebSocketSession
WebSocketUtil handler;//处理程序(者)-handler
// private static WebSocketUtil handler = new WebSocketUtil();

public void registerWebSocketHandlers(WebSocketHandlerRegistry reg) {
reg.addHandler(handler, "/appwebSocketServer") //设置websocket的地址,注册到Handler
.addInterceptors(new MyWebSocketInterceptor()) //注册到Interceptor
.setAllowedOrigins("*");

String sockjs_url = "/appwebSocketServer/sockjs"; //设置sockjs的地址
reg.addHandler(handler,sockjs_url ) //注册到Handler
.addInterceptors(new MyWebSocketInterceptor()) //注册到Interceptor
.setAllowedOrigins("*").withSockJS(); //支持sockjs协议

}

// @Bean //@Bean 注入方式注入时,WebSocketUtil中的webSocketSet变量不能共用,只能保存一个WebSocketSession
// public WebSocketUtil gethandler(){
// return new WebSocketUtil();
// }
}

5)前端页面:

<!DOCTYPE HTML>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<html>
<head>
<title>My WebSocket</title>
</head>

<body>
Welcome<br/>
<input id="text1" type="text" /><button onclick="reset()">重连</button><br/>
<input id="text" type="text" /><button onclick="send()">Send</button> <button onclick="closeWebSocket()">Close</button>
<input id="text3" type="text" /><button onclick="sendJson()">获取数据</button>
<div id="message">
</div>
</body>

<script type="text/javascript">
var websocket = null;
var url ="ws://localhost:8093/appwebSocketServer?userId=1";
connectionWebSocket(url);
function connectionWebSocket(url){
//判断当前浏览器是否支持WebSocket
if('WebSocket' in window){
websocket = new WebSocket(url);
}else if('MOzWebSocket' in window){
websocket = new MozWebSocket(url);
}else{
alert('Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function(){
setMessageInnerHTML("error");
};

//连接成功建立的回调方法
websocket.onopen = function(event){
setMessageInnerHTML("open");
}

//接收到消息的回调方法
websocket.onmessage = function(event){
console.log(event.data);
setMessageInnerHTML(event.data);
}
//连接关闭的回调方法
websocket.onclose = function(){
setMessageInnerHTML("close");
}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
websocket.close();
}
}
//重连
function reset(){
connectionWebSocket();
}

//将消息显示在网页上
function setMessageInnerHTML(innerHTML){
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}

//关闭连接
function closeWebSocket(){
websocket.close();
console.log(websocket);
}

//发送消息
function send(){
var message = document.getElementById('text').value;
websocket.send(message);
}

function sendJson(){
var message = "{'startTime':'2018-01-10 15:18:41','filedNames':'waterFrequency,pressureFeedback','deviceName':'thing'}";
websocket.send(message);
}

</script>
</html>