Spring WebSocket前后台推送入门

项目结构如下:

依赖文件:pom.xml

<?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/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>

  <name>WebSocketPro</name>
  <groupId>org.example</groupId>
  <artifactId>WebSocketPro</artifactId>
  <version>1.0-SNAPSHOT</version>

  <build>
    <plugins>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.7</version>
        <configuration>
          <connectors>
            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
              <port>8888</port>
              <maxIdleTime>30000</maxIdleTime>
            </connector>
          </connectors>
          <webAppSourceDirectory>${project.build.directory}/${pom.artifactId}-${pom.version}</webAppSourceDirectory>
          <contextPath>/</contextPath>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.1.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

    <!-- spring websocket -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-messaging</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>javax.websocket</groupId>
      <artifactId>javax.websocket-api</artifactId>
      <version>1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

</project>

spring-websoket.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">


    <context:component-scan base-package="com.ithnhe.websocket"></context:component-scan>
    <!--静态资源不被过滤-->
    <mvc:default-servlet-handler/>

</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-websoket.xml</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>
        

 

websocket配置类:

package com.ithnhe.websocket;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class MyWebsocketConfig implements WebSocketConfigurer {


    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketHandler(),"/websocket")
                .addInterceptors(new MyHandshakeInterceptor()).setAllowedOrigins("*");

        registry.addHandler(webSocketHandler(),"/sockjs/websocket")
                .addInterceptors(new MyHandshakeInterceptor()).withSockJS();
    }

    /**
     * websocket处理类
     * @return
     */
    @Bean
    public MyWebsocketHandler webSocketHandler(){
        return new MyWebsocketHandler();
    }

}

 

  • registerWebSocketHandlers:这个方法是向spring容器注册一个handler地址,websocket的建立连接的地址就是xxxx/websocket
  • addInterceptors:拦截器,当建立websocket连接的时候,我们可以通过继承spring的HttpSessionHandshakeInterceptor来做一些处理
  • setAllowedOrigins:跨域设置,*表示所有域名都可以,不限制, 域包括ip:port, 指定*可以是任意的域名,不加的话默认localhost+本服务端口
  • withSockJS: 这个是应对浏览器不支持websocket协议的时候降级为轮询的处理。

 创建拦截器:

package com.ithnhe.websocket;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import java.util.Map;

public class MyHandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        System.out.println("beforeHandshake websoket.. ");
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
        System.out.println("afterHandshake websoket...");
        super.afterHandshake(request, response, wsHandler, ex);
    }
}

Handler类:

package com.ithnhe.websocket;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;


/**
 * websoket 业务处理
 */
public class MyWebsocketHandler extends AbstractWebSocketHandler {

    public MyWebsocketHandler() {
    }

    /**
     * 连接成功后会执行该方法 会触发页面上的onopen方法
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {

        System.out.println("建立websoket连接!");
    }

    /**
     *
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {

        String msg = message.getPayload().toString();
        System.out.println("服务器接收到信息="+msg);

        //处理其他业务
        //推送消息
        MessageThread messageThread = new MessageThread(session);
        Thread thread = new Thread(messageThread);
        thread.start();
    }

    @Override //关闭连接时触发该方法
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {

        System.out.println("关闭websoket连接!");
    }


}

MessageThread类:

package com.ithnhe.websocket;


import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;

public class MessageThread implements Runnable{

    public WebSocketSession session;
    public MessageThread(WebSocketSession session){
        this.session = session;

    }

    public void run() {

        if (session.isOpen()) {
            TextMessage textMessage = new TextMessage("good!");
            try {
                session.sendMessage(textMessage);

            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("socket数据推送成功!");

        } else {
            System.out.println("socket连接已经断开!");
        }

    }

}

index.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Charles-WebSocket</title>

    <script type="text/javascript">

        var websocket = null;
        var target = "ws://localhost:8080/WebSocketPro/websocket";

        function buildConnection() {

            if('WebSocket' in window) {
                websocket = new WebSocket(target);
            } else if('MozWebSocket' in window) {
                websocket = MozWebSocket(target);
            } else {
                window.alert("浏览器不支持WebSocket");
            }
        }

        // 往后台服务器发送消息.
        function sendMessage() {

            var sendmsg = document.getElementById("sendMsg").value;
            console.log("发送的消息:" + sendmsg);

            // 发送至后台服务器中.
            websocket.send(sendmsg);

            //获取后台推送的数据
            websocket.onmessage = function (e) {
                console.log("接收的消息:" + e.data);
            };


        }



    </script>
</head>
<body>

<button onclick="buildConnection();">开始建立链接</button>
<hr>
<input id="sendMsg" /> <button onclick="sendMessage();">消息发送</button>

</body>
</html>

测试结果如下:

        点击建立连接

 

        点击发送消息

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Spring Boot应用中使用WebSocket推送信息,可以使用SpringWebSocket支持,它提供了一个WebSocketHandler来处理WebSocket连接和消息。 以下是一个简单的示例代码,用于向所有已连接的WebSocket客户端推送时间: 1. 首先,需要在POM文件中添加Spring WebSocket的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建一个WebSocketHandler类,处理WebSocket连接和消息: ```java import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @Component public class MyWebSocketHandler extends TextWebSocketHandler { private final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 添加新连接 sessions.add(session); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { // 移除已关闭的连接 sessions.remove(session); } public void pushMessage(String message) { // 向所有已连接的客户端推送消息 for (WebSocketSession session : sessions) { session.sendMessage(new TextMessage(message)); } } } ``` 在上面的代码中,我们继承了TextWebSocketHandler,并实现了afterConnectionEstablished()和afterConnectionClosed()方法来处理连接的打开和关闭事件。我们还添加了一个pushMessage()方法,用于向所有已连接的客户端推送消息。 3. 在Controller中注入MyWebSocketHandler,并在需要推送消息的时候调用它的pushMessage()方法: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class MyController { @Autowired private MyWebSocketHandler webSocketHandler; @GetMapping("/push") public String push() { webSocketHandler.pushMessage("Current time: " + LocalDateTime.now()); return "OK"; } } ``` 在上面的代码中,我们注入了MyWebSocketHandler,并在/push接口中调用它的pushMessage()方法,向所有已连接的WebSocket客户端推送时间。 4. 在端页面中,使用JavaScript连接WebSocket,并监听来自服务器的消息: ```javascript var socket = new WebSocket("ws://" + window.location.host + "/websocket"); socket.onmessage = function(event) { console.log(event.data); }; ``` 在上面的代码中,我们使用WebSocket连接到服务器上的/websocket路径,并监听来自服务器的消息。当服务器向客户端推送消息时,onmessage事件会被触发,我们在这里打印出收到的消息。 这样,当我们访问/push接口时,服务器会向所有已连接的WebSocket客户端推送时间。在端页面中,我们可以监听这些推送的消息,并实时更新页面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值