Spring Boot 开发私有即时通信系统(WebSocket)

时间:2022-09-20 00:19:30

1/ 概述

利用spring boot作为基础框架,spring security作为安全框架,websocket作为通信框架,实现点对点聊天和群聊天。

2/ 所需依赖

spring boot 版本 1.5.3,使用mongodb存储数据(非必须),maven依赖如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<properties>
 <java.version>1.8</java.version>
 <thymeleaf.version>3.0.0.release</thymeleaf.version>
 <thymeleaf-layout-dialect.version>2.0.0</thymeleaf-layout-dialect.version>
 </properties>
 
 <dependencies>
 
 <!-- websocket依赖,移除tomcat容器 -->
 <dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-websocket</artifactid>
  <exclusions>
  <exclusion>
   <groupid>org.springframework.boot</groupid>
   <artifactid>spring-boot-starter-tomcat</artifactid>
  </exclusion>
  </exclusions>
 </dependency>
 
 <!-- 使用undertow容器 -->
 <dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-undertow</artifactid>
 </dependency>
 
 <!-- spring security 框架 -->
 <dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-security</artifactid>
 </dependency>
 
 <!-- mongodb数据库 -->
 <dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-data-mongodb</artifactid>
 </dependency>
 
 <!-- thymeleaf 模版引擎 -->
 <dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-thymeleaf</artifactid>
 </dependency>
 
 <dependency>
  <groupid>org.projectlombok</groupid>
  <artifactid>lombok</artifactid>
  <version>1.16.16</version>
 </dependency>
 
 <dependency>
  <groupid>com.alibaba</groupid>
  <artifactid>fastjson</artifactid>
  <version>1.2.30</version>
 </dependency>
 
 <!-- 静态资源 -->
 <dependency>
  <groupid>org.webjars</groupid>
  <artifactid>webjars-locator</artifactid>
 </dependency>
 <dependency>
  <groupid>org.webjars</groupid>
  <artifactid>sockjs-client</artifactid>
  <version>1.0.2</version>
 </dependency>
 <dependency>
  <groupid>org.webjars</groupid>
  <artifactid>stomp-websocket</artifactid>
  <version>2.3.3</version>
 </dependency>
 <dependency>
  <groupid>org.webjars</groupid>
  <artifactid>bootstrap</artifactid>
  <version>3.3.7</version>
 </dependency>
 <dependency>
  <groupid>org.webjars</groupid>
  <artifactid>jquery</artifactid>
  <version>3.1.0</version>
 </dependency>
 
 </dependencies>

配置文件内容:

?
1
2
3
4
5
6
7
8
9
10
server:
 port: 80
 
# 若使用mongodb则配置如下参数
spring:
 data:
 mongodb:
  uri: mongodb://username:password@172.25.11.228:27017
  authentication-database: admin
  database: chat

大致程序结构,仅供参考:

Spring Boot 开发私有即时通信系统(WebSocket)

3/ 创建程序启动类,启用websocket

使用@enablewebsocket注解

?
1
2
3
4
5
6
7
8
9
@springbootapplication
@enablewebsocket
public class application {
 
 public static void main(string[] args) {
 springapplication.run(application.class, args);
 }
 
}

4/ 配置spring security

此章节省略。(配置好spring security,用户能正常登录即可)

5/ 配置web socket(结合第7节的js看)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@configuration
@enablewebsocketmessagebroker
@log4j
public class websocketconfig extends abstractwebsocketmessagebrokerconfigurer {
 
 // 此处可注入自己写的service
 
 @override
 public void registerstompendpoints(stompendpointregistry stompendpointregistry) {
 // 客户端与服务器端建立连接的点
 stompendpointregistry.addendpoint("/any-socket").withsockjs();
 }
 
 @override
 public void configuremessagebroker(messagebrokerregistry messagebrokerregistry) {
 // 配置客户端发送信息的路径的前缀
 messagebrokerregistry.setapplicationdestinationprefixes("/app");
 messagebrokerregistry.enablesimplebroker("/topic");
 }
 
 @override
 public void configurewebsockettransport(final websockettransportregistration registration) {
 registration.adddecoratorfactory(new websockethandlerdecoratorfactory() {
  @override
  public websockethandler decorate(final websockethandler handler) {
  return new websockethandlerdecorator(handler) {
   @override
   public void afterconnectionestablished(final websocketsession session) throws exception {
   // 客户端与服务器端建立连接后,此处记录谁上线了
   string username = session.getprincipal().getname();
   log.info("online: " + username);
   super.afterconnectionestablished(session);
   }
 
   @override
   public void afterconnectionclosed(websocketsession session, closestatus closestatus) throws exception {
   // 客户端与服务器端断开连接后,此处记录谁下线了
   string username = session.getprincipal().getname();
   log.info("offline: " + username);
   super.afterconnectionclosed(session, closestatus);
   }
  };
  }
 });
 super.configurewebsockettransport(registration);
 }
}

6/ 点对点消息,群消息

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@controller
@log4j
public class chatcontroller {
 
 @autowired
 private simpmessagingtemplate template;
 
 // 注入其它service
 
 // 群聊天
 @messagemapping("/notice")
 public void notice(principal principal, string message) {
 // 参数说明 principal 当前登录的用户, message 客户端发送过来的内容
 // principal.getname() 可获得当前用户的username
 
 // 发送消息给订阅 "/topic/notice" 且在线的用户
 template.convertandsend("/topic/notice", message);
 }
 
 // 点对点聊天
 @messagemapping("/chat")
 public void chat(principal principal, string message){
 // 参数说明 principal 当前登录的用户, message 客户端发送过来的内容(应该至少包含发送对象touser和消息内容content)
 // principal.getname() 可获得当前用户的username
 
 // 发送消息给订阅 "/user/topic/chat" 且用户名为touser的用户
 template.convertandsendtouser(touser, "/topic/chat", content);
 }
 
}

7/ 客户端与服务器端交互

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
var stompclient = null;
 
function connect() {
 var socket = new sockjs('/any-socket');
 stompclient = stomp.over(socket);
 stompclient.connect({}, function (frame) {
  // 订阅 /topic/notice 实现群聊
  stompclient.subscribe('/topic/notice', function (message) {
   showmessage(json.parse(message.body));
  });
  // 订阅 /user/topic/chat 实现点对点聊
  stompclient.subscribe('/user/topic/chat', function (message) {
   showmessage(json.parse(message.body));
  });
 });
}
 
function showmessage(message) {
 // 处理消息在页面的显示
}
 
$(function () {
 // 建立websocket连接
 connect();
 // 发送消息按钮事件
 $("#send").click(function () {
  if (target == "to_all"){
   // 群发消息
   // 匹配后端chatcontroller中的 @messagemapping("/notice")
   stompclient.send("/app/notice", {}, '消息内容');
  }else{
   // 点对点消息,消息中必须包含对方的username
   // 匹配后端chatcontroller中的 @messagemapping("/chat")
   var content = "{'content':'消息内容','receiver':'anoy'}";
   stompclient.send("/app/chat", {}, content);
  }
 });
});

8/ 效果测试

登录三个用户:anoyi、jock、超级管理员。

群消息测试,超级管理员群发消息:Spring Boot 开发私有即时通信系统(WebSocket)

Spring Boot 开发私有即时通信系统(WebSocket)

Spring Boot 开发私有即时通信系统(WebSocket)

点对点消息测试,anoyi给jock发送消息,只有jock收到消息,anoyi和超级管理员收不到消息:

Spring Boot 开发私有即时通信系统(WebSocket)

Spring Boot 开发私有即时通信系统(WebSocket)

Spring Boot 开发私有即时通信系统(WebSocket)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://www.jianshu.com/p/0f498adb3820