springboot整合stomp,并实现动态订阅

springboot整合stomp,并实现动态订阅

官方示例:https://spring.io/guides/gs/messaging-stomp-websocket/

  1. xml文件
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
        <version>2.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>webjars-locator-core</artifactId>
        <version>0.52</version>
    </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.1-1</version>
    </dependency>
</dependencies>

  1. webSocket配置类
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // 注册一个Stomp端点
        // 连接前缀
        registry.addEndpoint("/fs-demo")
                // 跨越处理
                .setAllowedOriginPatterns("*")
                // 支持socketJs
                .withSockJS();
    }

    /**
     * 配置一个简单基于内存的消息代理
     *
     * @param registry registry
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // 通过topic开头的主题可以进行订阅
        registry.enableSimpleBroker("/topic");
        // 添加前缀
        registry.setApplicationDestinationPrefixes("/app");
    }
}
  1. 前端页面

    html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello WebSocket</title>
    <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/main.css" rel="stylesheet">
    <script src="/webjars/jquery/jquery.min.js"></script>
    <script src="/webjars/sockjs-client/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/stomp.min.js"></script>
    <script src="/app.js"></script>
</head>
<body>
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
    enabled. Please enable
    Javascript and reload this page!</h2></noscript>
<div id="main-content" class="container">
    <div class="row">
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="connect">WebSocket connection:</label>
                    <button id="connect" class="btn btn-default" type="submit">Connect</button>
                    <button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect
                    </button>
                </div>
            </form>
        </div>
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="name">What is your name?</label>
                    <input type="text" id="name" class="form-control" placeholder="Your name here...">
                </div>
                <button id="send" class="btn btn-default" type="submit">Send</button>
            </form>
        </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            <table id="conversation" class="table table-striped">
                <thead>
                <tr>
                    <th>Greetings</th>
                </tr>
                </thead>
                <tbody id="greetings">
                </tbody>
            </table>
        </div>
    </div>
    <button id="getRandomAddress" class="btn btn-default" type="submit">获取订阅地址</button>
    <button id="start" class="btn btn-default" type="submit">开始发送消息</button>
    <button id="stop" class="btn btn-default" type="submit">停止发送消息</button>
    <div class="row">
        <div class="col-md-6">
            <table id="topicListTable1" class="table table-striped">
                <thead>
                    <tr>
                        <th>订阅列表</th>
                    </tr>
                </thead>
                <tbody id="topicList">
                </tbody>
            </table>
        </div>

        <div class="col-md-6">
            <table id="topicListTable2" class="table table-striped">
                <thead>
                    <tr>
                        <th>收到消息</th>
                    </tr>
                </thead>
                <tbody id="msg">
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>

​ js

var stompClient = null;

function setConnected(connected) {
  $("#connect").prop("disabled", connected);
  $("#disconnect").prop("disabled", !connected);
  if (connected) {
    $("#conversation").show();
  } else {
    $("#conversation").hide();
  }
  $("#greetings").html("");
}

function connect() {
  var socket = new SockJS("/fs-demo");
  stompClient = Stomp.over(socket);
  stompClient.connect({}, function (frame) {
    setConnected(true);
    console.log("Connected: " + frame);
    stompClient.subscribe("/topic/hello", function (greeting) {
      showGreeting(JSON.parse(greeting.body).body);
    });
    stompClient.subscribe("/topic/getRandomAddress", function (resp) {
      let address = JSON.parse(resp.body).body;
      stompClient.subscribe(address, function (respReal) {
        console.log("收到真正的消息:", respReal);
        showMsg(JSON.parse(respReal.body));
      });
      showList(address);
      console.log("动态订阅地址:", address);
    });
  });
}

function disconnect() {
  if (stompClient !== null) {
    stompClient.disconnect();
  }
  setConnected(false);
  console.log("Disconnected");
}

function sendName() {
  stompClient.send(
    "/app/hello",
    {},
    JSON.stringify({ name: $("#name").val() })
  );
}

function showGreeting(message) {
  $("#greetings").append("<tr><td>" + message + "</td></tr>");
}

var date = Date.now();
function getRandomAddress() {
  stompClient.send("/app/getRandomAddress", {}, (date = Date.now()));
}

function showList(message) {
  $("#topicList").append("<tr><td>" + message + "</td></tr>");
}

function showMsg(message) {
  $("#msg").append("<tr><td>" + message + "</td></tr>");
}

function startSendData() {
  stompClient.send("/app/start");
}

function stopSendData() {
  stompClient.send("/app/stop");
}

$(function () {
  $("form").on("submit", function (e) {
    e.preventDefault();
  });
  $("#connect").click(function () {
    connect();
  });
  $("#disconnect").click(function () {
    disconnect();
  });
  $("#send").click(function () {
    sendName();
  });
  $("#getRandomAddress").click(function () {
    getRandomAddress();
  });
  $("#start").click(function () {
    startSendData();
  });
  $("#stop").click(function () {
    stopSendData();
  });
});

​ css

body {
    background-color: #f5f5f5;
}

#main-content {
    max-width: 940px;
    padding: 2em 3em;
    margin: 0 auto 20px;
    background-color: #fff;
    border: 1px solid #e5e5e5;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}
  1. 测试
@RestController
public class StompDemoController {

    @Resource
    private SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/hello")
    @SendTo("/topic/hello")
    public ResponseEntity<?> hello(String name) throws InterruptedException {
        Thread.sleep(1000L);
        String msg = "Hello, " + name + "!";
        return ResponseEntity.ok(msg);
    }


    public static final Map<String, List<String>> MAP = new ConcurrentHashMap<String, List<String>>();

    public static final String ADDRESS_PREFIX = "/topic/send/";

    public static Boolean SEND = Boolean.TRUE;

    /**
     * 根据前端的条件订阅不同的地址
     */
    @MessageMapping("/getRandomAddress")
    @SendTo("/topic/getRandomAddress")
    public ResponseEntity<?> hello2(String id, StompHeaderAccessor stompHeaderAccessor) {
        Random random = new Random();
        String num = String.valueOf(random.nextInt());
        String sessionId = stompHeaderAccessor.getSessionId();
        if (MAP.containsKey(sessionId)) {
            MAP.get(sessionId).add(num);
        } else {
            MAP.put(sessionId, Stream.of(num).collect(Collectors.toList()));
        }
        return ResponseEntity.ok(ADDRESS_PREFIX + num);
    }

    @MessageMapping("/start")
    public void start() {
        SEND = Boolean.TRUE;
        new Thread(() -> {
            try {
                sendTo();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    @MessageMapping("/stop")
    public void stop() {
        SEND = Boolean.FALSE;
    }

    public void sendTo() throws InterruptedException {
        while (SEND) {
            Thread.sleep(2000L);
            boolean empty = MAP.isEmpty();
            System.out.println("准备发送消息");
            if (!empty) {
                MAP.forEach((key, value) -> value.forEach(item -> {
                    simpMessagingTemplate.convertAndSend(
                            ADDRESS_PREFIX + item, System.currentTimeMillis());
                }));
            }
        }

    }
}
  1. 实现效果

项目启动,访问:http://localhost:8080/index.html

点击connect,请求连接stomp,连接成功后,点击获取订阅接口,进入@MessageMapping(“/getRandomAddress”)方法,订阅/topic/getRandomAddress,获取到真正的订阅地址,开始订阅消息。

参考地址:https://github.com/spring-guides/gs-messaging-stomp-websocket

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值