配置信息

package com.ssyouxia.config;

import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

@Configuration
@EnableWebSocketMessageBroker
//@ServerEnd
public class AppWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        //这句话表示在topic和user这两个域上可以向客户端发消息。
//        config.enableSimpleBroker("","/topic");
        config.enableSimpleBroker("/queue","/user","/topic");
        //表示客户单向服务器端发送时的主题上面需要加"/calcApp"作为前缀
        config.setApplicationDestinationPrefixes("/calcApp");
        //表示给指定用户发送一对一的主题前缀是"/user"
        config.setUserDestinationPrefix("/user");
        //What the UserDestinationResolver makes is removing '/user' prefix. Then in the non-working case the destination remianed was '/search/{'user'+userSessionId}', but '/search' is filtered out, because there was not simpleBroker is enabled there.
//		config.set
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // TODO Auto-generated method stub
        //指定socket连接url
        registry.addEndpoint("/liyh").setHandshakeHandler(new DefaultHandshakeHandler() {

            public boolean beforeHandshake(
                    ServerHttpRequest request,
                    ServerHttpResponse response,
                    WebSocketHandler wsHandler,
                    Map attributes) throws Exception {

                if (request instanceof ServletServerHttpRequest) {
                    ServletServerHttpRequest servletRequest
                            = (ServletServerHttpRequest) request;
                    HttpSession session = servletRequest
                            .getServletRequest().getSession();
                    attributes.put("sessionId", session.getId());
                }
                return true;
            }
        }).setAllowedOrigins("*").withSockJS();
//		registry.set
    }


}

controller

package com.ssyouxia.controller;


import com.ssyouxia.vo.CalcInput;
import com.ssyouxia.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class AppWebSocketController {

    @Autowired
    private SimpMessagingTemplate template;

    @MessageMapping("/add")
    @SendTo("/topic/showResult")
    public Result addNum(CalcInput input) throws Exception {
        Thread.sleep(2000);
        Result result = new Result(input.getNum1() + "+" + input.getNum2() + "=" + (input.getNum1() + input.getNum2()));
        return result;
    }

    @RequestMapping("/start")
    public String start() {
        return "/start";
    }

	/*@MessageMapping("/sendToOne")
	@SendToUser()
	public Object sendToUser(){
		Map<String, Object> map = new HashedMap();
		map.put("name", "liyuhang");
		return map;
	}*/

    @MessageMapping("/search")
    @SendToUser // <- maps to "/user/queue/search"
    public String search(@Payload String xxx) {
        return "TEST1234";
    }

    @GetMapping("/sendToUser")
    public void sendToUser(){
//		this.template.convertAndSendToUser("123", "/event", "Hello");
        this.template.convertAndSendToUser("123","/message","后台具体用户消息");
    }

    public SimpMessagingTemplate getTemplate() {
        return template;
    }

    public void setTemplate(SimpMessagingTemplate template) {
        this.template = template;
    }
}

操作界面

<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Calculator App Using Spring 4 WebSocket</title>
    <script type="text/javascript">
        var baseSocketPath='<%=request.getAttribute("baseSocketPath")%>';
        var basePath='<%=request.getAttribute("basePath")%>';
    </script>
    <script src="<%=request.getAttribute("basePath")%>js/sockjs-0.3.4.js"></script>
    <%--<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>--%>
    <script src="<%=request.getAttribute("basePath")%>js/stomp.js"></script>
    <script type="text/javascript">
        var stompClient = null;
        function setConnected(connected) {
            document.getElementById('connect').disabled = connected;
            document.getElementById('disconnect').disabled = !connected;
            document.getElementById('calculationDiv').style.visibility = connected ? 'visible'
                : 'hidden';
            document.getElementById('calResponse').innerHTML = '';
        }
        function connect() {
        	var socket = new SockJS('/liyh');
            //var socket = new WebSocket("ws:/localhost:8080/wsocketdemo/ss");
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function(frame) {
                setConnected(true);
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/showResult', function(calResult) {
                    showResult(JSON.parse(calResult.body).result);
                });

                stompClient.subscribe('/user/queue/search', function(data){
                    alert(data.body);
                });

                stompClient.subscribe('/user/' + 123 + '/message', function(message){
                    console.log("收到session消息:"+message.body);//body中为具体消息内容
                });
            });
        }
        function disconnect() {
            stompClient.disconnect();
            setConnected(false);
            console.log("Disconnected");
        }
        function sendNum() {
            var num1 = document.getElementById('num1').value;
            var num2 = document.getElementById('num2').value;
            stompClient.send("/calcApp/add", {}, JSON.stringify({
                'num1' : num1,
                'num2' : num2
            }));
        }
        function showResult(message) {
            var response = document.getElementById('calResponse');
            var p = document.createElement('p');
            p.style.wordWrap = 'break-word';
            p.appendChild(document.createTextNode(message));
            response.appendChild(p);
        }

        function send123() {
            stompClient.send("/calcApp/search", {}, "test");
        }
    </script>
</head>
<body>
<noscript>
    <h2>Enable Java script and reload this page to run Websocket Demo</h2>
</noscript>
<h1>Calculator App Using Spring 4 WebSocket</h1>
<div>
    <div>
        <button id="connect" onclick="connect();">Connect</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
        <br />
        <br />
    </div>
    <div id="calculationDiv">
        <label>Number One:</label><input type="text" id="num1" /><br /> <label>Number
        Two:</label><input type="text" id="num2" /><br />
        <br />
        <button id="sendNum" onclick="sendNum();">Send to Add</button>
        <p id="calResponse"></p>
    </div>
    <button id="send" onclick="send123();">send</button>
</div>
</body>
</html>

操作演示

广播

spring stomp websocket demo-LMLPHP

响应给当前用户

点击 send 按钮

spring stomp websocket demo-LMLPHP

向指定订阅频道推送信息

spring stomp websocket demo-LMLPHP

代码下载地址

https://gitee.com/liyuhang712/wsocketdemo

02-11 14:48