springBootWebSocket

​ 今天使用springboot的websocket是发现其中有许多细节问题,所以决定记录下来,希望下次使用能够借鉴这次的心得体会,这里就不在描述什么是websocket了,对了随便提一句,websocket是http长连接在http1.1提出的。http是应用层的协议

服务端依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

加入以上依赖即可

服务端配置

关于websocket的配置

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
@Configuration

@EnableWebSocketMessageBroker

public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Override

public void registerStompEndpoints(StompEndpointRegistry registry) {

registry.addEndpoint("webSocketServer") //这里指明父地址

.setAllowedOrigins("*") //允许所有源访问

.withSockJS();

}



@Override

public void configureMessageBroker(MessageBrokerRegistry registry) {

// super.configureMessageBroker(registry);

// 以下说明若不理解 请保留疑问,继续往下阅读

// 订阅名称 注意这里参数表示客户端订阅的地址前缀,

registry.enableSimpleBroker("/user1","/topic");

// 全局使用消息前缀 客户端发送消息前缀

registry.setApplicationDestinationPrefixes("/app");

// 点对点使用的订阅前缀 不设置默认为 /user 该字符一定要在订阅名称中出现

registry.setUserDestinationPrefix("/user1");

}

创建消息对象

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ClientMessage {

private String msg;

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}

}

编写controller

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
@Controller

public class WebSocketController {

//这里为广播模式 类似消息群发

@MessageMapping("/sendTest") //请求路径

@SendTo("/topic/sub1") //表示返回消息到订阅了该url的所有客户端

public ServiceMessage send(ClientMessage client){

System.out.println("接收到的消息" + client.getMsg());

return new ServiceMessage("我收的你发的" + client.getMsg());

}



@Autowired
private SimpMessagingTemplate simpMessagingTemplate; //用于服务器主动发送消息

//这里为单点模式 类似于私聊
@MessageMapping("/dan")
// 发送的订阅路径为/user1/{userId}/{message}这里的user1是不是有点熟悉呢 请参考关于websocket的配置
// /user/路径是默认的一个,如果想要改变,必须在config 中setUserDestinationPrefix
public void dan(ClientMessage msg){
System.out.println("你要发送到哪里呢" + msg.getMsg());
// 下面三个参数依次为 {userId},{message},与发送数据
simpMessagingTemplate.convertAndSendToUser("123456","/message",msg.getMsg());
}

}

客户端

客户端一

实现了广播发送与私信发送

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>

<meta charset="UTF-8"/>

<title>广播式WebSocket</title>

<script type="text/javascript" src="js/jquery-1.9.1.js"></script>

<script src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>

<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>

</head>

<body onload="disconnect()">

<noscript><h2 style="color: #e80b0a;">Sorry,浏览器不支持WebSocket</h2></noscript>

<div>

<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>
<button id="sendName" onclick="sendName1();">1对1 发送</button>
<p id="response"></p>
</div>

</div>

<script type="text/javascript">

var stompClient = null;

function setConnected(connected) {

document.getElementById("connect").disabled = connected;

document.getElementById("disconnect").disabled = !connected;

document.getElementById("conversationDiv").style.visibility = connected ? 'visible' : 'hidden';

// $("#connect").disabled = connected;

// $("#disconnect").disabled = !connected;

$("#response").html();

}









//-----------------------------------华丽分割线--------------------------------------

function connect() {

//注意到这里的webSocketServer了吗 这里的就是在关于websocket的配置 中进行的配置 前面是进入项目地址

var socket = new SockJS('http://127.0.0.1:8080/springboot/webSocketServer');

stompClient = Stomp.over(socket);

stompClient.connect({}, function (frame) {

setConnected(true);

console.log('Connected:' + frame);

//注意到下面的/topic/sub1 该url与@SendTo("/topic/sub")中的相同表示 订阅了这一url 即加入 //群聊

stompClient.subscribe('/topic/sub1', function (response) {

//response.body 返回字符串

showResponse(JSON.parse(response.body).msg);

})

});

}

function disconnect() {

if (stompClient != null) {

stompClient.disconnect();

}

setConnected(false);

console.log('Disconnected');

}

//发送群发消息

function sendName() {

var name = $('#name').val();

console.log('name:' + name);

// /app/sendTest 这里的app为所有发送消息前缀 在关于websocket的配置中配置

// sendTest则为@MessageMapping("/sendTest")

stompClient.send("/app/sendTest", {}, JSON.stringify({'msg': name}));

}

//发送私聊消息

function sendName1() {

var name = $('#name').val();

console.log('name:' + name);

//同上

stompClient.send("/app/dan", {}, JSON.stringify({'msg': name}));

}

function showResponse(message) {

$("#response").html(message);

}

</script>

</body>

</html>

客户端二

实现广播 与 私信接收

这里就只写华丽分割线之后的内容

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


function connect() {
var socket = new SockJS('http://127.0.0.1:8080/springboot/webSocketServer');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected:' + frame);
stompClient.subscribe('/topic/sub1', function (response) {
showResponse(JSON.parse(response.body).msg);
});

// 主要是这里

// 这里实现了自己独有的url订阅路径 user1在哪里设置呢 我相信你们应该知道了
// 123456则表示uerId, message表示{message}
// 结合控制器的写法 我相信应该可以明白的
stompClient.subscribe('/user1/123456/message', function (response) {
showResponse(response.body);
})
},
function errorCallBack(error) {
// 连接失败时(服务器响应 ERROR 帧)的回调方法
alert("连接失败");
}
);
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log('Disconnected');
}
function sendName() {
var name = $('#name').val();
console.log('name:' + name);
stompClient.send("/app/sendTest", {}, JSON.stringify({'msg': name}));
}
function showResponse(message) {
$("#response").html(message);
}

这里加入了连接中断的处理

文章目录
  1. 1. 服务端依赖
  2. 2. 服务端配置
    1. 2.1. 关于websocket的配置
    2. 2.2. 创建消息对象
    3. 2.3. 编写controller
  3. 3. 客户端
    1. 3.1. 客户端一
    2. 3.2. 客户端二
,