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

文章摘要

由于项目功能需求,要在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代码

{{response}}

页面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启动,直接在标签内添加以下代码


  org.springframework.boot
  spring-boot-starter-websocket

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

war


  org.springframework.boot
    spring-boot-starter-web
    
    
      
        org.springframework.boot
        spring-boot-starter-tomcat
      
    



  org.springframework.boot
    spring-boot-starter-tomcat
    
    provided

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



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.2.0.RELEASE
         
    
    com.example
    demo
    0.0.1-SNAPSHOT
    demo
    Demo project for Spring Boot

    
    war

    
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter-web
            
            
            
                
                    org.springframework.boot
                    spring-boot-starter-tomcat
                
            
        

        
        
            org.springframework.boot
            spring-boot-starter-tomcat
            
            provided
        

        
        
            org.springframework.boot
            spring-boot-starter-websocket
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


在基于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通信)