天天玩微信,Spring Boot 开发私有即时通信系统了解一下

1/ 概述

利用Spring Boot作为基础框架,Spring Security作为安全框架,WebSocket作为通信框架,实现点对点聊天和群聊天。

2/ 所需依赖

Spring Boot 版本 1.5.3,使用MongoDB存储数据(非必须),Maven依赖如下:

<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>

配置文件内容:

server:
  port: 80

# 若使用MongoDB则配置如下参数
spring:
  data:
    mongodb:
      uri: mongodb://username:[email protected]:27017
      authentication-database: admin
      database: chat

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

程序结构

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

使用@EnableWebSocket注解

@SpringBootApplication
@EnableWebSocket
public class Application {

 public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
 }

}

4/ 配置Spring Security

此章节省略。(配置好Spring Security,用户能正常登录即可)
可以参考:Spring Boot 全栈开发:用户安全

5/ 配置Web Socket(结合第7节的JS看)

@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/ 点对点消息,群消息

@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/ 客户端与服务器端交互

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、超级管理员。
群消息测试,超级管理员群发消息:

超级管理员

Anoyi

Jock

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

Jock

超级管理员

Anoyi

9/ 轻量级DEMO(完整可运行代码)

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

10/ 参考文献

  • spring-mongodb 官方文档
  • Spring Framework 官方文档
  • Spring Guide - stomp websocket

? 著作权归作者所有,转载或内容合作请联系作者

有任何问题,请留言告诉我们哈。

Spring Boot 定制 parent 快速构建应用

Spring Boot 容器化部署 - Docker

SpringBot中教你手把手配置 https

Spring Boot 日志处理你还在用Logback?

【双11狂欢的背后】微服务注册中心如何承载大型系统的千万级访问?

Spring Boot 新一代监控你该这么玩

Spring Boot 异常处理

Spring Boot 配置 - 配置信息加密

拒绝黑盒应用-Spring Boot 应用可视化监控

并发Bug之源有三,请睁大眼睛看清它们

本文由博客一文多发平台 OpenWrite 发布!

原文地址:https://www.cnblogs.com/springforall/p/11826798.html

时间: 2024-10-08 10:17:39

天天玩微信,Spring Boot 开发私有即时通信系统了解一下的相关文章

Spring Boot 开发微信公众号后台

Hello 各位小伙伴,松哥今天要和大家聊一个有意思的话题,就是使用 Spring Boot 开发微信公众号后台. 很多小伙伴可能注意到松哥的个人网站(http://www.javaboy.org)前一阵子上线了一个公众号内回复口令解锁网站文章的功能,还有之前就有的公众号内回复口令获取超 2TB 免费视频教程的功能(免费视频教程),这两个都是松哥基于 Spring Boot 来做的,最近松哥打算通过一个系列的文章,来向小伙伴们介绍下如何通过 Spring Boot 来开发公众号后台. 1. 缘起

玩转spring boot——websocket

前言 QQ这类即时通讯工具多数是以桌面应用的方式存在.在没有websocket出现之前,如果开发一个网页版的即时通讯应用,则需要定时刷新页面或定时调用ajax请求,这无疑会加大服务器的负载和增加了客户端的流量.而websocket的出现,则完美的解决了这些问题. spring boot对websocket进行了封装,这对实现一个websocket网页即时通讯应用来说,变得非常简单. 一.准备工作 pom.xml引入 <dependency> <groupId>org.springf

玩转spring boot——开篇

很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我个人认为是非常一般.如果单纯从技术来说,其实有工作3年的工作经验的人技术就已经很好了,后面工作时间是为了增加经验和对编程的理解.随着工作时间的增加,就会对一个技术有更深层次的理解,反而发现自己需要学更多的新.并觉得自己什么都不会.什么都不懂,还需要不停的学习和提高,并觉得时间更本不够用.自己唯一的收

玩转spring boot——properties配置

前言 在以往的java开发中,程序员最怕大量的配置,是因为配置一多就不好统一管理,经常出现找不到配置的情况.而项目中,从开发测试环境到生产环境,往往需要切换不同的配置,如测试数据库连接换成生产数据库连接,若有一处配错或遗漏,就会带来不可挽回的损失.正因为这样,spring boot给出了非常理想的解决方案——application.properties.见application-properties的官方文档:http://docs.spring.io/spring-boot/docs/curr

玩转spring boot——war部署

前言 之前部署spring boot应用是通过直接输入命令“java -jar”来实现的.而有些情况,由于部署环境的制约,只能把项目从jar转换成war才能部署,如新浪云sae的java环境容器.那怎样转换成war项目呢? 其实非常简单,只需要App类继承SpringBootServletInitializer,并重写“protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)” 方法即可 pack

玩转spring boot——结合AngularJs和JDBC

参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `t_order` -- ---------------------------- DROP TABLE IF EXISTS `t_order`; CREAT

天天芒果微信农场平台开发

天天芒果微信农场平台开发,开发系统找:陈经理136-4273-5391 天天芒果农场系统,天天芒果农场模式,天天芒果农场平台开发,天天芒果开发系统,天天芒果软件开发.本文章是做系统开发咨询的,并非官方平台运营商,玩平台者勿扰!谢谢配合! 你是否还记得QQ农场半夜偷菜的情景?是否还想重温插上稻草人吓小鸟.养只狗狗看菜园的乐趣?也是否想再看看鱼池里五彩七色的鱼儿自由游弋?不需要你卖任何产品,也没有物流的烦恼,也没有保质期,更不会影响你的正常工作:每天24小时随时都可以在家里网上操作. 盈利模式.利润

Spring Boot 开发系列一 开发环境的一些九九

从今天开始写这个Spring Boot 开发系列,我是第二周学习JAVA的,公司号称springboot把JAVA的开发提升到填空的能力,本人是NET转JAVA的,想看看这个填空的东西到底有多强.废话不多说,强不强,撸段代码试试吧. 写过NET的人第一次看到JAVA这个工程文件的目录,有没有想死的感觉,一入JAVA深似海,N个展开就是找不到代码,我去,其实在这里可以设置成后面这种xx.xx.xx包的模式显示,机关在这里. 意思是  隐藏  空的中间过渡包,勾上后就成后后面这种舒服的感觉. 2.代

使用Spring boot开发RestFul 风格项目PUT/DELETE方法不起作用

在使用Spring boot 开发restful 风格的项目,put.delete方法不起作用,解决办法. 实体类Student @Data public class Student { private String id; private String name; private int age; private String sex; @Override public String toString() { return ToStringBuilder.reflectionToString(