看到spring4的介绍上说已经支持websocket了,尝试了一下之后各种坑,不如servlet简单,写篇文章来讲解一下自己遇到的坑。
环境:tomcat8+spring4.1.6+jdk8+nginx1.8.0
先是看了下网络上的人的实现,千奇百怪,干脆直接在spring的官方文档上观望了一下,看了下他们官方的实现,然而我用的是springmvc,总是失败,报的错误翻译过来大致是找不到请求,所有的页面请求都找不到,找到原因是WebSocketConfig在继承AbstractWebSocketMessageBrokerConfigurer的时候注解上需要加上对springMVC的支持,即@EnableWebMvc,和你在spring配置文件里配置包扫描一个用处。废话不多说,先上代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
org.springframework.context.annotation.Configuration;
import
org.springframework.messaging.simp.config.MessageBrokerRegistry;
import
org.springframework.web.servlet.config.annotation.EnableWebMvc;
import
org.springframework.web.socket.config.annotation.*;
@Configuration
@EnableWebMvc
@EnableWebSocketMessageBroker
public
class
WebSocketConfig
extends
AbstractWebSocketMessageBrokerConfigurer {
@Override
public
void
configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker(
"/tweet"
);
config.setApplicationDestinationPrefixes(
"/websocket"
);
}
public
void
registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint(
"/hello"
).withSockJS();
}
}
|
以上是websocket配置类,下面是请求。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
com.yuorfei.bean.ResultData;
import
org.apache.commons.logging.Log;
import
org.apache.commons.logging.LogFactory;
import
org.springframework.messaging.handler.annotation.MessageMapping;
import
org.springframework.messaging.handler.annotation.SendTo;
import
org.springframework.stereotype.Controller;
@Controller
(
"chat"
)
public
class
ChatAction {
private
static
final
Log log = LogFactory.getLog(MessageAction.
class
);
@MessageMapping
(
"/hello"
)
@SendTo
(
"/tweet/fuck"
)
public
ResultData chat(String message)
throws
Exception {
long
time = System.currentTimeMillis();
log.info(time+
":"
+message);
return
new
ResultData(time,
true
,message);
}
}
|
请求类准备好了之后写前端代码:
前端代码需要引入的js有sockjs-1.0.3.min.js,stomp.min.js两个,去官网下最新的就行,我目前用的是最新的。
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
|
<!
DOCTYPE
html>
<
html
>
<
head
>
<
meta
charset
=
"utf-8"
>
<
meta
http-equiv
=
"X-UA-Compatible"
content
=
"IE=edge"
>
<
script
src
=
"/dest/js/fun/chat/sockjs-1.0.3.min.js"
></
script
>
<
script
src
=
"/dest/js/fun/chat/stomp.min.js"
></
script
>
<!-- 为了方便起见,js我就直接这么放这儿了 -->
<
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';
document.getElementById('response').innerHTML = '';
}
function connect() {
var socket = new SockJS('/hello');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/tweet/fuck', function(greeting){
showGreeting(JSON.parse(greeting.body).code+" : "+
JSON.parse(greeting.body).message);
});
});
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendMessage() {
var message = document.getElementById('message').value;
stompClient.send("/websocket/hello", {}, JSON.stringify({ 'message': message }));
}
function showGreeting(message) {
var response = document.getElementById('response');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(message));
response.appendChild(p);
}
</
script
>
</
head
>
<
body
onload
=
"disconnect()"
>
<
noscript
>
<
h2
style
=
"color: #ff0000"
>不支持的浏览器版本,丫的是不是用IE了,你这简直是摧残程序员的生命</
h2
>
</
noscript
>
<
a
href
=
"${homeUrl!"
/"}"><
h5
>返回与或非网站首页</
h5
></
a
>
<
hr
/>
<
p
>这只是一个SpringMVC的websocket例子</
p
>
<
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
=
"message"
/>
<
button
id
=
"sendMessage"
onclick
=
"sendMessage();"
>发送</
button
>
<
p
id
=
"response"
></
p
>
</
div
>
</
div
>
<
hr
/>
</
body
>
</
html
>
|
到了这里就ok了,但是运行却发现会报错,错误信息翻译过来大致意思是:没有引入jackson2的包 或者 socket消息转换没有配置。
猛然一想我的确没有引入jackson2,赶紧maven把jackson2的依赖加进来,很久以前用过jackson,然而不知道2里头只引入core的jar包是不行的,还需要
jackson-databind和jackson-annotations,为了方便我索性全加入进来了(真是够大的,不如fastjson清爽)。
这样就ok了,配置好了之后发送消息,正常接收,处理,ok,控制台不报烦人的错了