SPRING BOOT -- WEBSOCKET配置

websocket为浏览器为服务器提供了双工异步通信的功能,即浏览器可以向服务器发送消息,服务器也可以向浏览器发送消息。websocket需要浏览器的支持(ie10+、chrome 13+、firefox 6+)。

  websocket是通过一个socket来实现双工异步通信功能,但是直接使用websocket会比较麻烦,我们使用它的子协议stomp,它是一个更高级的协议,stomp使用一个基于帧的格式来定义消息,与http的request和response类似。

  实战(新建spring boot项目,选择thymeleaf和websocket)

  1、广播式

  广播式即服务端有消息时,会将消息发给所有连接了当前endpoint的浏览器。

  ① 配置websocket,需要再配置类上使用@EnableWebSocketMessageBroker开启websocket,并通过AbstractWebSocketMessageBrokerConfigurer类。

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package  com.example.demo;
 
import  org.springframework.context.annotation.Configuration;
import  org.springframework.messaging.simp.config.MessageBrokerRegistry;
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.config.annotation.WebSocketMessageBrokerConfigurer;
 
/**
  * Created by xingzhuipingye on 2017/5/25.
  */
 
@Configuration
//开启stomp协议来传输基于代理message broker的消息
@EnableWebSocketMessageBroker
public  class  WebSocketConfig  extends  AbstractWebSocketMessageBrokerConfigurer {
     @Override
     //注册stomp协议节点 endpoint
     public  void  registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
         //注册一个endpoint 并指定是哟个socketjs
         stompEndpointRegistry.addEndpoint( "/endpointWisely" ).withSockJS();
     }
 
     @Override
     //配置消息代理
     public  void  configureMessageBroker(MessageBrokerRegistry registry) {
         //广播式配置一个topic的消息代理
         registry.enableSimpleBroker( "/topic" );
     }
}

  ② 浏览器向服务器发送的类

  

1
2
3
4
5
6
7
8
9
10
11
12
13
package  com.example.demo;
 
/**
  * Created by xingzhuipingye on 2017/5/25.
  */
//浏览器向服务器发送消息用此类接受
public  class  WiselyMessage {
     private  String name;
 
     public  String getName() {
         return  name;
     }
}

  ③ 服务器向浏览器发送此类的消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package  com.example.demo;
 
/**
  * Created by xingzhuipingye on 2017/5/25.
  */
public  class  WiselyResponse {
     private  String responseMessage;
 
     public  WiselyResponse(String responseMessage) {
         this .responseMessage = responseMessage;
     }
 
     public  String getResponseMessage() {
         return  responseMessage;
     }
}

  ④ 控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package  com.example.demo;
 
import  org.springframework.messaging.handler.annotation.MessageMapping;
import  org.springframework.messaging.handler.annotation.SendTo;
import  org.springframework.stereotype.Controller;
 
/**
  * Created by xingzhuipingye on 2017/5/25.
  */
@Controller
public  class  WsController {
     //当浏览器向服务器发送请求的时候通过@MessageMapping 映射/welcome 这个地址 类似 RequestMapping
     @MessageMapping ( "/welcome" )
     //当服务器有消息的时候,会对订阅了@SendTo中的路径浏览器发送消息
     @SendTo ( "/topic/getResponse" )
     public  WiselyResponse say(WiselyMessage wiselyMessage)  throws  InterruptedException {
         Thread.sleep( 3000 );
         return  new  WiselyResponse( "Welcome,"  + wiselyMessage.getName());
     }
}

  ⑤ 页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<! DOCTYPE  html>
< html  lang="cn" xml:th="http://www.thymeleaf.org" xmlns:link="http://www.w3.org/1999/xhtml"
       xmlns:th="http://www.w3.org/1999/xhtml">
< head >
     < meta  charset="UTF-8"/>
     < title >Title</ title >
     < script  src="http://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></ script >
     < script  src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></ script >
     < script  src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></ script >
</ head >
< body  onload="disconnect()">
 
     < div >
         < button  id="connect" onclick="connect()">连接</ button >
         < button  id="disconnect" disabled="disabled" onclick="disconnect()">断开连接</ button >
 
     </ div >
 
     < div  id="conversationDiv">
         < label >输入你的名字</ label >
         < input  type="text" id="name"/>
         < button  id="sendName" onclick="sendName()">发送</ button >
         < p  id="response"></ p >
     </ div >
 
</ body >
< script >
     var stompClient = null;
     function  setConnected(connected) {
         document.getElementById("connect").disabled = connected;
         document.getElementById('disconnect').disabled = !connected;
         document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
         $('#response').html();
     }
 
     function  connect() {
         var socket = new SockJS('/endpointWisely');
         stompClient = Stomp.over(socket);
         stompClient.connect({},function (frame) {
             setConnected(true);
             console.log('connected'+ frame);
             stompClient.subscribe('/topic/getResponse',function (response) {
                 showResponse(JSON.parse(response.body).responseMessage);
             });
         });
     }
 
     function disconnect() {
         if(stompClient!=null){
             stompClient.disconnect();
         }
         setConnected(false);
         console.log('disconnected')
     }
 
 
     function  sendName() {
         var name = $('#name').val();
         stompClient.send('/welcome',{},JSON.stringify({'name':name}));
     }
     function  showResponse(message) {
         var response = $('#response');
         response.html(message);
     }
 
</ script >
</ html >

  打开三个浏览器分别输入名字测试

  

当一个浏览器发送一个消息到服务器端的时候,其他浏览器也能收到从服务器端发送来的消息。

猜你喜欢

转载自blog.csdn.net/xinzi11243094/article/details/80326938