美文网首页
springboot 与 微信小程序实现 WebSocket通信

springboot 与 微信小程序实现 WebSocket通信

作者: 这是个懒得不想动脑的昵称 | 来源:发表于2019-11-07 10:46 被阅读0次

    文章摘要

    由于项目功能需求,要在springboot与微信小程序之间实现WebSocket连接,Google了一天虽然底层还不明白,但至少能跑起来能用不是么。
    此文章将记录从新建项目开始的大多数操作,如哪里有错误请诸位看到的大佬指点下,谢谢
    spring版本:2.2.0
    java版本:1.8
    Tomcat版本:9.0.27
    maven版本:3.5.4
    微信小程序开发工具版本:Stable V1.02.1910120
    微信小程序开发工具基础调试库版本:2.9.2
    这些一路默认各位大佬已经配置好了,如果没有配置好,emm,不怪我,别找我

    tomcat配置SSL后可以直接用wss连接,不需要做额外的配置。也就是https能正常连接,那么wss也可以正常连接

    微信小程序WebSocket实现

    先写一下微信小程序的吧,因为spring实现WebSocket有三种方式,我会写下其中两种。微信小程序的WebSocket实现就这一种(我只是根据官方文档来的,也许会有多种),要看spring的直接往下滑吧。代码就不过多解释了,请参考官方文档,肯定比我了解的详细多了

    wechatdevtools_3tl0dh9EDM.png

    页面wxml代码

    <text>{{response}}</text>
    

    页面js代码

    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        response:""
      },
    
      /**
       * 生命周期函数--监听页面显示
       */
      onShow: function () {
        var that = this
    
        // 创建一个 WebSocket 连接
        wx.connectSocket({
          url: 'ws://127.0.0.1:8088/WebSocketDemo_war/websocketapi',
        })
        /////////////////////////
    
        // 监听 WebSocket 连接打开事件
        wx.onSocketOpen(function (res){
    
          // 通过 WebSocket 连接发送数据
          wx.sendSocketMessage({
            data: "Hello Spring WebSocket",
            success(){
              console.log("数据发送成功")
    
              // 监听 WebSocket 接受到服务器的消息事件
              wx.onSocketMessage(function(re){
                that.setData({ response: re.data})
                console.log("SocketMessage: "+re.data)
              })
              //////////////////////////////////////
    
            },
            fail(){
              console.log("数据发送失败")
            }
          })
          /////////////////////////////
    
        })
        ///////////////////////////////
      },
      
    })
    

    SpringBoot WebSocket实现

    新建springboot项目
    新建项目,选Spring Initializr,next 想调的可以随便调,这里我作为演示就不动了,一律默认,next 这里再Spring Web打上勾,next 项目名字可以更改,这里我改了下,Finish

    接下来就让代码跑一会儿,等创建完成

    创建完就是这个样子了,记得把右下角的Enable Auto-Import点了

    springboot内置了tomcat,所以可以有两种方式启动,一种使用spring内置的Tomcat启动,一种用外置Tomcat启动。使用mvn命令打包后第一种生成Jar包,第二种生成War包。我就两个都写一下吧。
    下面是pom.xml文件配置

    使用spring内置Tomcat启动,直接在<dependencies>标签内添加以下代码

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    

    使用外置Tomcat启动需要额外做一些修改,额外添加以下代码

    <packaging>war</packaging>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <!-- 移除嵌入式tomcat插件 -->
        <exclusions>
          <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
          </exclusion>
        </exclusions>
    </dependency>
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <!--打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。
            相当于compile,但是打包阶段做了exclude操作-->
        <scope>provided</scope>
    </dependency>
    

    下面是我的完整的pom.xml文件配置,因为要打包成war包,也就是使用外置Tomcat启动。所以各位根据自己需要看着改吧。其实都可以添加到pom里。在idea里不影响,两种都能启动。如果需要使用mvn命令打包的话还是改改吧。

    <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>demo</name>
        <description>Demo project for Spring Boot</description>
    
        <!--    打包成war包,添加第18行代码-->
        <packaging>war</packaging>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <!-- 在这里添加 29-35行代码-->
                <!-- 移除嵌入式tomcat插件 -->
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-tomcat</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <!-- 在这里添加 39-45行代码-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <!--打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。
                    相当于compile,但是打包阶段做了exclude操作-->
                <scope>provided</scope>
            </dependency>
    
            <!-- 添加 48-51行代码-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    在基于Spring的应用中使用WebSocket一般可以有以下三种方式(也许会有多总,我这里只写前两种):

    1. 使用Java提供的@ServerEndpoint注解实现
    2. 使用Spring提供的低层级WebSocket API实现
    3. 使用STOMP消息实现
    使用@ServerEndpoint注解实现

    在com.example.demo下新建Controller包,在Controller包里新建WebSocketServerEndpoint类,在WebSocketServerEndpoint类添加代码。

    类名不一样的注意修改

    代码:

    @ServerEndpoint("/websocketapi")
    public class WebSocketServerEndpoint {
        @OnMessage
        public void handleMessage(Session session, String message) throws IOException {
            System.out.println("服务器接收到的消息:"+message);
            session.getBasicRemote().sendText("服务器回复的消息: " + "Hello,Are you OK?");
        }
    }
    
    使用外置Tomcat启动
    添加tomcat,会使用外置的tomcat来运行,注意URL和端口号,我这里改了下
    添加时右下角会有一个Fix报错,点他选第一个
    使用spring内置Tomcat启动

    Jar包启动需要额外配置一下,在Controller包里新建WebSocketServerEndpointConfig类,添加代码


    @Configuration
    @EnableWebSocket
    public class WebSocketServerEndpointConfig {
    
        @Bean
        public WebSocketServerEndpoint reverseWebSocketEndpoint() {
            return new WebSocketServerEndpoint();
        }
    
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    

    配置完成后,直接点右上角启动DemoApplication。
    如果要以外置Tomcat启动,请把WebSocketServerEndpointConfig注释掉,否则会报错

    添加完后点击运行就OK了。
    然后在微信小程序的js文件里填入WebSocketURL:
    使用外置Tomcat启动URL:ws://127.0.0.1:8088/WebSocketDemo_war/websocketapi
    使用spring内置Tomcat启动URL:ws://127.0.0.1:8088/websocketapi
    (注:因为在application.properties配置了端口使用8088,所以这里不是8080,如果application.properties没有配置,默认使用8080)

    可以看到微信小程序连接成功。我这里用外置Tomcat启动的,使用spring内置Tomcat启动请修改URL,
    服务器也连接成功

    使用Spring提供的低层级WebSocket API实现

    在Controller包里新建类WebSocketConfig,添加代码。
    "websocketapi"为ws的URL路径,可自行修改。
    因为spring默认不接受跨域访问,设置setAllowedOrigins("*")允许接收跨域访问。


    @Configuration
    @EnableWebSocket
    public class WebSocketConfig implements WebSocketConfigurer {
    
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            registry.addHandler(handler(), "websocketapi").setAllowedOrigins("*");
        }
        
        @Bean
        public CustomizeWebSocketHandler handler() {
            return new CustomizeWebSocketHandler();
        }
    }
    

    在Controller包里新建类CustomizeWebSocketHandler ,添加代码


    public class CustomizeWebSocketHandler extends TextWebSocketHandler {
    
        @Override
        protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
            String payload = message.getPayload();
            System.out.println("服务器接收到的数据:"+payload);
            session.sendMessage(new TextMessage("服务器回复的消息: " + "Hello,Are you OK?"));
        }
    }
    
    Jar包启动

    代码添加完成后,直接点右上角选择DemoApplication启动。

    war包启动

    在Controller包里新建类WebSocketInitializer,添加代码。一开始启动后提示404,后来搜到了某位大佬的解决方法

    public class WebSocketInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        @Override
        protected Class<?>[] getRootConfigClasses() { return null; }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[] {WebSocketConfig.class};
        }
    
        @Override
        protected String[] getServletMappings() { return new String[] {"/"}; }
    }
    

    启动结果参考“使用@ServerEndpoint注解实现”的启动结果,URL也请参考上面的。这里一摸一样,就不再放了。Jar包启动时请把WebSocketInitializer注释掉(不注释也可以正常使用,个人觉得注释掉吧,以防止产生多余的bug)。

    相关文章

      网友评论

          本文标题:springboot 与 微信小程序实现 WebSocket通信

          本文链接:https://www.haomeiwen.com/subject/lvtpbctx.html