1 配置
- pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.3.6.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
- applicationContext.xml
<context:component-scan base-package="com.websocket"/>
- ssmPureBackend-servlet.xml
<mvc:resources location="/resource/static" mapping="*.html"/>
<mvc:resources location="/resource/static/images" mapping="/resource/static/images/**"/>
<mvc:resources location="/resource/static/js" mapping="*.js"/>
- web.xml
<async-supported>true</async-supported>
2 资源
2.1 插件
- sockjs.min.js
Socket通信JS:https://github.com/sockjs/sockjs-client/blob/master/dist/sockjs.min.js - jquery-3.2.1.min.js
jQuery配置:https://code.jquery.com/jquery-3.2.1.min.js - jquery-3.4.1.min.js
https://code.jquery.com/jquery-3.4.1.min.js
websocket配置
2.2 完整路径
├ssmPureBackend
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── websocket
│ │ │ ├── MsgSocketHandle.java
│ │ │ ├── WebSocketConfig.java
│ │ │ └── WebSocketHandshakeInterceptor.java
│ │ │ ├── controller
│ │ │ │ ├── webchat
│ │ │ │ ├── MsgController.java
│ │ └── webapp
│ │ ├── index.jsp
│ │ ├── resource
│ │ │ └── static
│ │ │ └── js
│ │ │ ├── jquery-3.2.1.js
│ │ │ ├── jquery-3.2.1.min.js
│ │ │ ├── jquery-3.4.1.js
│ │ │ ├── jquery-3.4.1.min.js
│ │ │ ├── jquery.js
│ │ │ ├── sockjs.min.js
│ │ └── WEB-INF
│ │ ├── jsp
│ │ │ └── websocket
│ │ │ ├── chat.jsp
│ │ │ └── login.jsp
3 源文件
3.1 websocket源文件
3.1.0 MsgSocketHandle.java
/**
* @Description
* @Author Nobody
* @Date 2019/10/18 14:19
* @Version 1.0
**/
package com.websocket;
import com.po.People;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Component
public class MsgSocketHandle implements WebSocketHandler {
/**已经连接的用户*/
private static final List<WebSocketSession> peoples;
static {
//保存当前连接用户
peoples = new ArrayList<>();
}
@Override
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
//将用户信息添加到list中
peoples.add(webSocketSession);
System.out.println("=====================建立连接成功==========================");
People people = (People) webSocketSession.getAttributes().get("people");
if(people != null){
System.out.println("当前连接用户======"+people.getUserName());
}
System.out.println("webSocket连接数量====="+peoples.size());
}
@Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
People people = (People) webSocketSession.getAttributes().get("people");
System.out.println("收到用户:"+people.getUserName()+"的消息");
}
@Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
if (webSocketSession.isOpen()){
//关闭session
try {
webSocketSession.close();
} catch (IOException e) {
}
}
//移除用户
peoples.remove(webSocketSession);
}
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
peoples.remove(webSocketSession);
People people = (People) webSocketSession.getAttributes().get("people");
System.out.println(people.getUserName()+"断开连接");
}
@Override
public boolean supportsPartialMessages() {
return false;
}
public void sendMessageToUser(People people, TextMessage messageInfo){
for (WebSocketSession session : peoples) {
People sessionUser = (People) session.getAttributes().get("people");
//根据用户名去判断用户接收消息的用户
if(people.getUserName().equals(sessionUser.getUserName())){
try {
if (session.isOpen()){
session.sendMessage(messageInfo);
System.out.println("发送消息给:"+people.getUserName()+"内容:"+messageInfo);
}
break;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void sendMsgToAllUsers(TextMessage messageInfo) throws Exception{
for (WebSocketSession user : peoples) {
user.sendMessage(messageInfo);
}
}
}
3.1.2 WebSocketConfig.java
/**
* @Description
* @Author Nobody
* @Date 2019/10/18 14:19
* @Version 1.0
**/
package com.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;
/**
* @Description
* @Author Nobody
* @Date 2019/10/18 14:19
* @Version 1.0
**/
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
System.out.println("===========================注册websocket================");
webSocketHandlerRegistry.addHandler(msgSocketHandle(),"/websocket")
.addInterceptors(new WebSocketHandshakeInterceptor());
webSocketHandlerRegistry.addHandler(msgSocketHandle(),
"/sockjs/websocket").
addInterceptors(new WebSocketHandshakeInterceptor())
.withSockJS();
}
@Bean(name = "msgSocketHandle")
public WebSocketHandler msgSocketHandle(){
return new MsgSocketHandle();
}
}
3.1.3 WebSocketHandshakeInterceptor.java
/**
* @Description
* @Author Nobody
* @Date 2019/10/18 14:19
* @Version 1.0
**/
package com.websocket;
import com.po.People;
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;
import javax.servlet.http.HttpSession;
import java.util.Map;
public class WebSocketHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
if (request instanceof ServletServerHttpRequest){
ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) request;
HttpSession session = servletServerHttpRequest.getServletRequest().getSession(false);
if(session != null){
//从session中获取当前用户
People people = (People) session.getAttribute("people");
map.put("people",people);
}
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
super.afterHandshake(serverHttpRequest,serverHttpResponse,webSocketHandler,e);
}
}
3.2 控制器
- MsgController.java
/**
* @Description
* @Author Nobody
* @Date 2019/10/18 14:19
* @Version 1.0
**/
package com.controller.webchat;
import com.po.People;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.socket.TextMessage;
import javax.servlet.http.HttpServletRequest;
// import com.websocket.fullversion.MsgSocketHandle;
import com.websocket.MsgSocketHandle;
@RequestMapping("/websocket")
@Controller
public class MsgController {
@Autowired
private MsgSocketHandle msgSocketHandle;
@RequestMapping("/index")
public String login(){
return "websocket/login";
}
@RequestMapping("/login")
public String login(People people, HttpServletRequest request){
System.out.format("name:"+people.getUserName());
request.getSession().setAttribute("people",people);
return "websocket/chat";
}
@ResponseBody
@RequestMapping(value = "/sendMsg",produces = "application/json; charset=utf-8")
public String sendMsgToUser(String content,String toUserName){
People people = new People();
people.setUserName(toUserName);
TextMessage textMessage = new TextMessage(content);
msgSocketHandle.sendMessageToUser(people,textMessage);
return "发送成功";
}
@ResponseBody
@RequestMapping(value = "/sendMsg2",produces = "application/json; charset=utf-8")
public String sendMsgToAll(String content) throws Exception {
TextMessage textMessage = new TextMessage(content);
msgSocketHandle.sendMsgToAllUsers(textMessage);
return "发送成功";
}
}
3.3 前端展示
3.3.1 login.jsp
<%--
该页面用于登录,将用户存于session
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>测试websocket</title>
<base href="<%=basePath%>">
</head>
<body>
<form:form action="websocket/login">
<input type="text" name="userName" value="admin"/>
<input type="text" name="passWord" value="admin"/>
<input type="submit" value="测试websocket"/>
</form:form>
</body>
</html>
3.3.2 chat.jsp
<%--
该页面用于消息推送
--%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
<title>测试requestbody</title>
</head>
<script type="text/javascript" src="<%=path%>/resource/static/js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="<%=path%>/resource/static/js/sockjs.min.js"></script>
<body>
当前登录用户:${pageContext.session.getAttribute("people").userName}<br>
<input type="text" id="text">
<button id="btn1" value="发送给所有人">发送给所有人</button>
<button id="btn2" value="发送给特定用户">发送给特定用户</button>
<div id="msg"></div>
</body>
</html>
<script>
console.log("path:"+"<%=path%>");
$(function() {
var websocket;
// 首先判断是否 支持 WebSocket
if('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/ssmPureBackend/websocket");
} else if('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://localhost:8080/ssmPureBackend/websocket");
} else {
websocket = new SockJS("http://localhost:8080/ssmPureBackend/sockjs/websocket");
}
// 打开时
websocket.onopen = function(evnt) {
console.log(" websocket.onopen ");
};
// 处理消息时
websocket.onmessage = function(evnt) {
alert("你有一条新消息");
$("#msg").html(evnt.data);
};
websocket.onerror = function(evnt) {
console.log(" websocket.onerror ");
};
websocket.onclose = function(evnt) {
console.log(" websocket.onclose ");
};
// 点击了发送消息按钮的响应事件
$("#btn2").bind("click",function () {
var url = "${pageContext.request.contextPath}/websocket/sendMsg";
var content = $("#text").val();
var toUserName = "admin"
$.ajax({
data: "content=" + content + "&toUserName=" + toUserName,
type: "get",
dataType: 'text',
async: false,
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
encoding: "UTF-8",
url: url,
success: function (data) {
alert(data.toString());
},
error: function (msg) {
alert(msg);
},
});
})
$("#btn1").bind("click",function () {
var url = "${pageContext.request.contextPath}/websocket/sendMsg2";
var content = $("#text").val();
$.ajax({
data: "content=" + content ,
type: "get",
dataType: 'text',
async: false,
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
encoding: "UTF-8",
url: url,
success: function (data) {
alert(data.toString());
},
error: function (msg) {
alert(msg);
},
});
})
});
</script>
4 访问
- 登录
http://localhost:8080/ssmPureBackend/websocket/index
- 对话
http://localhost:8080/ssmPureBackend/websocket/login
- Firefox控制台
【参考文献】
[1]https://blog.csdn.net/qq_35615462/article/details/82595071
[2]https://www.jb51.net/article/137433.htm