pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gblfy</groupId>
<artifactId>springboot-websocket</artifactId>
<version>v1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
</parent>
<properties>
<!--编码同意设置-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!--JDK版本-->
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--SpringMVC启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--热部署插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--websocket启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--thymeleaf 模板引擎启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!--maven 打包编译插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置类
package com.gblfy.websocket.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
实体类
package com.gblfy.websocket.entity;
import javax.websocket.Session;
import java.io.Serializable;
public class Client implements Serializable {
private static final long serialVersionUID = 8957107006902627635L;
private String userName;
private Session session;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public Client(String userName, Session session) {
this.userName = userName;
this.session = session;
}
public Client() {
}
}
websocket 服务端
package com.gblfy.websocket.server;
import com.gblfy.websocket.entity.Client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;
@ServerEndpoint(value = "/socketServer/{userName}")
@Component
public class SocketServer {
private static final Logger logger = LoggerFactory.getLogger(SocketServer.class);
private static CopyOnWriteArraySet<Client> socketServers = new CopyOnWriteArraySet<>();
private Session session;
private final static String SYS_USERNAME = "niezhiliang9595";
@OnOpen
public void open(Session session,@PathParam(value="userName")String userName){
this.session = session;
socketServers.add(new Client(userName,session));
logger.info("客户端:【{}】连接成功",userName);
}
@OnMessage
public void onMessage(String message){
Client client = socketServers.stream().filter( cli -> cli.getSession() == session)
.collect(Collectors.toList()).get(0);
sendMessage(client.getUserName()+"<--"+message,SYS_USERNAME);
logger.info("客户端:【{}】发送信息:{}",client.getUserName(),message);
}
@OnClose
public void onClose(){
socketServers.forEach(client ->{
if (client.getSession().getId().equals(session.getId())) {
logger.info("客户端:【{}】断开连接",client.getUserName());
socketServers.remove(client);
}
});
}
@OnError
public void onError(Throwable error) {
socketServers.forEach(client ->{
if (client.getSession().getId().equals(session.getId())) {
socketServers.remove(client);
logger.error("客户端:【{}】发生异常",client.getUserName());
error.printStackTrace();
}
});
}
public synchronized static void sendMessage(String message,String userName) {
socketServers.forEach(client ->{
if (userName.equals(client.getUserName())) {
try {
client.getSession().getBasicRemote().sendText(message);
logger.info("服务端推送给客户端 :【{}】",client.getUserName(),message);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public synchronized static int getOnlineNum(){
return socketServers.stream().filter(client -> !client.getUserName().equals(SYS_USERNAME))
.collect(Collectors.toList()).size();
}
public synchronized static List<String> getOnlineUsers(){
List<String> onlineUsers = socketServers.stream()
.filter(client -> !client.getUserName().equals(SYS_USERNAME))
.map(client -> client.getUserName())
.collect(Collectors.toList());
return onlineUsers;
}
public synchronized static void sendAll(String message) {
socketServers.stream().filter(cli -> cli.getUserName() != SYS_USERNAME)
.forEach(client -> {
try {
client.getSession().getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
});
logger.info("服务端推送给所有客户端 :【{}】",message);
}
public synchronized static void SendMany(String message,String [] persons) {
for (String userName : persons) {
sendMessage(message,userName);
}
}
}
控制器
package com.gblfy.websocket.controller;
import com.gblfy.websocket.server.SocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class WebSocketController {
@Autowired
private SocketServer socketServer;
@RequestMapping(value = "/index")
public String idnex() {
return "index";
}
@RequestMapping(value = "/admin")
public String admin(Model model) {
int num = socketServer.getOnlineNum();
List<String> list = socketServer.getOnlineUsers();
model.addAttribute("num",num);
model.addAttribute("users",list);
return "admin";
}
@RequestMapping("sendmsg")
@ResponseBody
public String sendmsg(String msg, String username){
String [] persons = username.split(",");
SocketServer.SendMany(msg,persons);
return "success";
}
@RequestMapping("sendAll")
@ResponseBody
public String sendAll(String msg){
SocketServer.sendAll(msg);
return "success";
}
}
html验证
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>websocket通讯</title>
</head>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<body>
<div style="width: 900px;border: 1px solid red;float: right;">
<p>【clientUserId】:
<div>
<input id="clientUserId" name="clientUserId" type="text" value="2">
</div>
<p>【收到的消息】:
<div id="contentText"></div>
<br/>
<p>【操作】:
</div>
</body>
<script>
var socket;
if(typeof(WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket");
}else{
console.log("您的浏览器支持WebSocket");
//实现化WebSocket对象,指定要连接的服务器地址与端口,建立连接
var socketUrl="http://localhost:8071/socketServer/" + $("#clientUserId").val();
socketUrl=socketUrl.replace("https","ws").replace("http","ws");
console.log(socketUrl);
if(socket!=null){
socket.close();
socket=null;
}
socket = new WebSocket(socketUrl);
//打开事件
socket.onopen = function() {
console.log("websocket 已打开");
};
//获得消息事件
socket.onmessage = function(msg) {
//发现消息进入,处理前端触发逻辑
console.log(msg.data);
document.getElementById('contentText').innerHTML += msg.data + '<br/>';
};
//关闭事件
socket.onclose = function() {
console.log("websocket 已关闭");
};
//发生了错误事件
socket.onerror = function() {
console.log("websocket 发生了错误");
}
}
</script>
</html>