spring配置webSocket
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>