说明
本demo运行的环境是:ssm框架 + tomcat8 + jdk7+,由于只是demo。很简陋。能运行调式通过就行,再在此基础上进行扩展研究。
在网上看了很多列子。对于没有接触过websocket的人来说。真的是看不懂。本文列子应该算是比较简单的。
Spring WebSocket API的核心接口是WebSocketHandler。我把它叫做消息处理中心。
其他的详细解说可以参考别人的博客
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
mvc的url-pattern 配置成 / 应该是拦截所有的访问请求?如果controller中有对应的地址就处理,没有就放行? 这一块不是太明白
pom.xml,版本自行查找。spring4.0+以上,在部署项目的时候。记得把tomcat8加入到jar包库(在eclipse中就是那个build path 中的 libraries )
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
</dependency>
WebSocketConfig 配置
由于之前使用xml配置,和springmvc中的地址冲突(忘记了是什么情况下发生的了,有可能是我访问地址访问错了)。就使用了注解配置类的形式配置
import cn.zymx.webTM.web.controller.HandshakeInterceptor;
import cn.zymx.webTM.web.controller.WebSocketHander;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
/**
* Created by zhuqiang on 2015/6/23 0023.
*/
@Configuration
@EnableWebSocket//开启websocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new WebSocketHander(),"/echo").addInterceptors(new HandshakeInterceptor()); //支持websocket 的访问链接
registry.addHandler(new WebSocketHander(),"/sockjs/echo").addInterceptors(new HandshakeInterceptor()).withSockJS(); //不支持websocket的访问链接
}
}
HandshakeInterceptor 拦截器
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import javax.servlet.http.HttpSession;
import java.util.Map;
/**
* Created by zhuqiang on 2015/6/22 0022.
*/
public class HandshakeInterceptor implements org.springframework.web.socket.server.HandshakeInterceptor {
//进入hander之前的拦截
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
String userName = "xq";
if (session != null) {
//使用userName区分WebSocketHandler,以便定向发送消息
// String userName = (String) session.getAttribute("WEBSOCKET_USERNAME");
map.put("WEBSOCKET_USERNAME",userName);
}
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
}
}
WebSocketHandler 消息处理中心
import org.apache.log4j.Logger;
import org.springframework.web.socket.*;
import java.io.IOException;
import java.util.ArrayList;
/**
* Created by zhuqiang on 2015/6/22 0022.
*/
public class WebSocketHander implements WebSocketHandler {
private static final Logger logger = Logger.getLogger(WebSocketHander.class);
private static final ArrayList<WebSocketSession> users = new ArrayList<>();
//初次链接成功执行
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
logger.debug("链接成功......");
users.add(session);
String userName = (String) session.getAttributes().get("WEBSOCKET_USERNAME");
if(userName!= null){
//查询未读消息
int count = 5;
session.sendMessage(new TextMessage(count + ""));
}
}
//接受消息处理消息
@Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
sendMessageToUsers(new TextMessage(webSocketMessage.getPayload() + ""));
}
@Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
if(webSocketSession.isOpen()){
webSocketSession.close();
}
logger.debug("链接出错,关闭链接......");
users.remove(webSocketSession);
}
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
logger.debug("链接关闭......" + closeStatus.toString());
users.remove(webSocketSession);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* 给所有在线用户发送消息
*
* @param message
*/
public void sendMessageToUsers(TextMessage message) {
for (WebSocketSession user : users) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 给某个用户发送消息
*
* @param userName
* @param message
*/
public void sendMessageToUser(String userName, TextMessage message) {
for (WebSocketSession user : users) {
if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(userName)) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
}
页面
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- 可选的Bootstrap主题文件(一般不用引入) -->
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!--<script type="text/javascript" src="js/jquery-1.7.2.js"></script>-->
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<title>webSocket测试</title>
<script type="text/javascript">
$(function(){
var websocket;
if (‘WebSocket‘ in window) {
alert("WebSocket");
websocket = new WebSocket("ws://127.0.0.1:8080/echo");
} else if (‘MozWebSocket‘ in window) {
alert("MozWebSocket");
websocket = new MozWebSocket("ws://echo");
} else {
alert("SockJS");
websocket = new SockJS("http://127.0.0.1:8080/sockjs/echo");
}
websocket.onopen = function (evnt) {
$("#tou").html("链接服务器成功!")
};
websocket.onmessage = function (evnt) {
$("#msg").html($("#msg").html() + "<br/>" + evnt.data);
};
websocket.onerror = function (evnt) {
};
websocket.onclose = function (evnt) {
$("#tou").html("与服务器断开了链接!")
}
$(‘#send‘).bind(‘click‘, function() {
send();
});
function send(){
if (websocket != null) {
var message = document.getElementById(‘message‘).value;
websocket.send(message);
} else {
alert(‘未与服务器链接.‘);
}
}
});
</script>
</head>
<body>
<div class="page-header" id="tou">
webSocket及时聊天Demo程序
</div>
<div class="well" id="msg">
</div>
<div class="col-lg">
<div class="input-group">
<input type="text" class="form-control" placeholder="发送信息..." id="message">
<span class="input-group-btn">
<button class="btn btn-default" type="button" id="send" >发送</button>
</span>
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div><!-- /.row -->
</body>
</html>
时间: 2024-10-05 11:58:39