参考:http://blog.youkuaiyun.com/ouyang111222/article/details/50545411
http://blog.youkuaiyun.com/gisredevelopment/article/details/38392629/
1.导入:
公司erp中有个好玩的功能,就是当销售在保存客户的时候,一旦库中有这个客户,这个时候就会给这个客户的创建人发送一个类似站内信的小弹窗,提示他这个客户刚刚被查看过,看了一下代码发现用的是websocket,这两天于是顺带看了一点websocket、长连接短连接以及轮询相关的定义,关于这部分我写了一个简单的介绍:
2.代码:
2.1.maven中pom依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>4.0.1.RELEASE</version>
</dependency>
关于这一块,公司代码里面使用了jdk1.8,同时还加入了javax.websocket和tomcat-embed-websocket等依赖,我觉得没有必要,也可能是有其他用途,等我后续研究再说;
2.2.在spring的配置文件中假如websocket的dtd约束:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd"
default-autowire="byName">
我的项目是ssm的,东西有点多,具体看标蓝部分即可;
2.3.新建WebsocketEndPoint类和HandshakeInterceptor类
WebsocketEndPoint
public class WebsocketEndPoint extends TextWebSocketHandler {
private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>();
private static final Logger logger = LoggerFactory
.getLogger(WebsocketEndPoint.class);
/**
* after connection establish
*/
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
logger.info("connect success...");
users.add(session);
}
@Override
protected void handleTextMessage(WebSocketSession session,
TextMessage message) throws Exception {
super.handleTextMessage(session, message);
TextMessage returnMessage = new TextMessage(message.getPayload()
+ " received at server");
session.sendMessage(returnMessage);
}
@Override
public void handleTransportError(WebSocketSession webSocketSession,
Throwable throwable) throws Exception {
if (webSocketSession.isOpen()) {
webSocketSession.close();
}
logger.info("connenction error,close the connection...");
users.remove(webSocketSession);
}
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession,
CloseStatus closeStatus) throws Exception {
logger.info("close the connenction..." + closeStatus.toString());
users.remove(webSocketSession);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
@Override
public void handleMessage(WebSocketSession webSocketSession,
WebSocketMessage<?> webSocketMessage) throws Exception {
sendMessageToUsers(new TextMessage(webSocketMessage.getPayload()
+ "hello"));
}
/**
* 给所有在线用户发送消息
*
* @param message
*/
public void sendMessageToUsers(TextMessage message) {
for (WebSocketSession user : users) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
HandshakeInterceptor
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor{
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
System.out.println("Before Handshake");
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
System.out.println("After Handshake");
super.afterHandshake(request, response, wsHandler, ex);
}
}
2.4:注册到spring中:
<!-- 处理类和握手协议的spring配置 -->
<bean id="websocket" class="com.lujx.websocket.WebsocketEndPoint" />
<websocket:handlers>
<websocket:mapping path="/websocket" handler="websocket" />
<websocket:handshake-interceptors>
<bean class="com.lujx.websocket.HandshakeInterceptor" />
</websocket:handshake-interceptors>
</websocket:handlers>
2.5.编写前端页面,新建websocket.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<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="http://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="http://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="http://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://localhost:8080/springDemo/websocket"); //标蓝为自己项目名称
} else if ('MozWebSocket' in window) {
alert("MozWebSocket");
websocket = new MozWebSocket("ws://echo");
} else {
alert("SockJS");
websocket = new SockJS("http://localhost:8080/springDemo/sockjs/websocket");//自己项目名称
}
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 -->
</body>
</html>
最终结果:浏览器访问:http://localhost:8080/springDemo/websocket.jsp 出现链接服务器成功;发送消息后,有消息返回到上面