使用spring websocket 和stomp实现消息功能

实现一个消息驱动pojo

public class MarcHandler extends AbstractWebSocketHandler{
    private Logger LOGGER = LoggerFactory.getLogger(MarcHandler.class);

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
       LOGGER.info("received Message :"+ message.getPayload());
        Thread.sleep(2000);
        session.sendMessage(new TextMessage("Polo!"));
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
       LOGGER.info("session closed!");
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        LOGGER.info("session established!");
    }
}

配置websocket handler 和js demo

原生websocket配置

 <websocket:handlers >
        <websocket:mapping path="/marco" handler="marcHandler"/>
        <!--<websocket:sockjs/>-->
    </websocket:handlers>
js demo:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
    <title>Home</title>
    <spring:url value="/webjars/jquery/2.0.3/jquery.min.js" var="jQueryCore"/>
    <script src="${jQueryCore}"></script>
    <spring:url value="/webjars/sockjs-client/0.3.4/sockjs.min.js" var="sockJs"/>
    <script src="${sockJs}"></script>
</head>
<body>
<button id="stop">Stop</button>

<script style="text/javascript">
   $(function () {
       var wsUrl = "ws://"+window.location.host+"/japi-rest/marco"
       var sock = new WebSocket(wsUrl);


//       var SockJSUrl = "http://"+window.location.host+"/japi-rest/marco"
//       var sock = new SockJS(SockJSUrl);

       sock.onopen = function() {
           console.log('Opening');
           sayMarco();
       }

       sock.onmessage = function(e) {
           console.log('Received message: ', e.data);
           $('#output').append('Received "' + e.data + '"<br/>');
           setTimeout(function(){sayMarco()}, 2000);
       }

       sock.onclose = function() {
           console.log('Closing');
       }

       function sayMarco() {
           console.log('Sending Marco!');
           $('#output').append('Sending "Marco!"<br/>');
           sock.send("Marco!");
       }

       $('#stop').click(function() {sock.close()});
   })
</script>

<div id="output"></div>
</body>
</html>
PS: 1)如果打开  <websocket:sockjs/> 会报错:
WebSocket connection to 'ws://localhost:8080/japi-rest/marco' failed: Error during WebSocket handshake: Unexpected response code: 200

利用SockJs解决部分浏览器不支持websocket

<websocket:handlers>
    <websocket:mapping path="/marco" handler="marcHandler"/>
    <websocket:sockjs/>
</websocket:handlers>

JS Demo:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
    <title>Home</title>
    <spring:url value="/webjars/jquery/2.0.3/jquery.min.js" var="jQueryCore"/>
    <script src="${jQueryCore}"></script>
    <spring:url value="/webjars/sockjs-client/0.3.4/sockjs.min.js" var="sockJs"/>
    <script src="${sockJs}"></script>
</head>
<body>
<button id="stop">Stop</button>

<script style="text/javascript">
   $(function () {
//       var wsUrl = "ws://"+window.location.host+"/japi-rest/marco"
//       var sock = new WebSocket(wsUrl);


       var SockJSUrl = "http://"+window.location.host+"/japi-rest/marco"
       var sock = new SockJS(SockJSUrl);

       sock.onopen = function() {
           console.log('Opening');
           sayMarco();
       }

       sock.onmessage = function(e) {
           console.log('Received message: ', e.data);
           $('#output').append('Received "' + e.data + '"<br/>');
           setTimeout(function(){sayMarco()}, 2000);
       }

       sock.onclose = function() {
           console.log('Closing');
       }

       function sayMarco() {
           console.log('Sending Marco!');
           $('#output').append('Sending "Marco!"<br/>');
           sock.send("Marco!");
       }

       $('#stop').click(function() {sock.close()});
   })
</script>

<div id="output"></div>
</body>
</html>

使用STOMP 消息

如果直接用websocket 编写web应用 类似与直接使用tcp套接字, stomp 相当于基于websocket之上的一个高层级的线路协议),
 xml配置:
<!--   stomp and message broker config  start -->
    <websocket:message-broker application-destination-prefix="/app">
        <!--   websocket 底层连接地址 -->
        <websocket:stomp-endpoint path="/marcopolo" >
            <websocket:sockjs/>
        </websocket:stomp-endpoint>
         <websocket:simple-broker prefix="/topic,/queue" />
    </websocket:message-broker>
    <!--   stomp and message broker config  end-->

编写一个消息处理controller:
@Controller
public class MarcoController {
private final static Logger logger = LoggerFactory.getLogger(MarcoController.class);

    @MessageMapping("/marco")
    public Shout handleShout(Shout incoming) {
        logger.info("Received message: " + incoming.getMessage());

        try { Thread.sleep(2000); } catch (InterruptedException e) {}

        Shout outgoing = new Shout();
        outgoing.setMessage("Polo!");

        return outgoing;
    }
}
js 编写测试客户端:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
    <title>Home</title>
    <spring:url value="/webjars/jquery/2.0.3/jquery.min.js" var="jQueryCore"/>
    <script src="${jQueryCore}"></script>
    <spring:url value="/webjars/sockjs-client/0.3.4/sockjs.min.js" var="sockJs"/>
    <script src="${sockJs}"></script>
    <spring:url value="/webjars/stomp-websocket/2.3.4/lib/stomp.min.js" var="stomp"/>
    <script src="${stomp}"></script>
    <spring:url value="/" var="context"/>
</head>
<body>
<button id="stop">Stop</button>

<script th:inline="javascript">
    var sock = new SockJS("${context}"+"/marcopolo");
    var stomp = Stomp.over(sock);

    stomp.connect('guest', 'guest', function(frame) {
        console.log('*****  Connected  *****');
        stomp.subscribe("/topic/marco", handlePolo);
        sayMarco();
    });

    function handleOneTime(message) {
        console.log('Received: ', message);
    }

    function handlePolo(message) {
        console.log('Received: ', message);
        $('#output').append("<b>Received: " +
                JSON.parse(message.body).message + "</b><br/>")
        if (JSON.parse(message.body).message === 'Polo!') {
            setTimeout(function(){sayMarco()}, 2000);
        }
    }

    function handleErrors(message) {
        console.log('RECEIVED ERROR: ', message);
        $('#output').append("<b>GOT AN ERROR!!!: " +
                JSON.parse(message.body).message + "</b><br/>")
    }

    function sayMarco() {
        console.log('Sending Marco!');
        stomp.send("/app/marco", {},
                JSON.stringify({ 'message': 'Marco!' }));
//        stomp.send("/topic/marco", {},
//                JSON.stringify({ 'message': 'Marco!' }));
        $('#output').append("<b>Send: Marco!</b><br/>")
    }

    $('#stop').click(function() {sock.close()});
</script>

<div id="output"></div>
</body>
</html>
PS:
0) stomap 消息道理数据流程图:

1) <websocket:stomp-endpoint path="/marcopolo" >
 这个配置终端 表明底层的websocket url

2) application-destination-prefix="/app" 是 controller处理的path 前缀
3)  <websocket:simple-broker prefix="/topic,/queue" /> 配置了两个代理的目的地
4)  @MessageMapping("/marco") 这个注解的方法返回的数据写到哪个代理目的地呢?因为没有配置@SendTo 所以默认写到/topic +"/marco" ,见下图调试:






  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值