1.需要用到的jar包
spring-websocket-4.0.5.RELEASE.jar
2.配置config文件:
spring-websocket.xml
内容:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket.xsd">
<bean id="websocket" class="com.xiangya.web.filter.WebSocketHandler"/>
<websocket:handlers>
<websocket:mapping path="/websocket" handler="websocket"/>
<websocket:handshake-interceptors>
<bean class="com.xiangya.web.filter.HandShakeInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>
<websocket:handlers>
<websocket:mapping path="/socket" handler="websocket"/>
<websocket:handshake-interceptors>
<bean class="com.xiangya.web.filter.HandShakeInterceptor"/>
</websocket:handshake-interceptors>
<websocket:sockjs/>
</websocket:handlers>
</beans>
3.配置web.xml
在web.xml中添加
<servlet>
<servlet-name>websocket</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/config/spring-websocket.xml</param-value>
</init-param>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>websocket</servlet-name>
<url-pattern>/websocket</url-pattern>
<url-pattern>/socketjs/*</url-pattern>
</servlet-mapping>
另外在<filter></filter>中添加 <async-supported>true</async-supported>
4.创建握手处理的类,和消息处理的类
握手处理的类:
public class HandShakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
//握手前
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
// 标记用户
Integer id = (Integer) session.getAttribute("id");
if(id!=null){
attributes.put("id", id);
}else{
return false;
}
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
//握手后
super.afterHandshake(request, response, wsHandler, ex);
}
}
消息处理的类
public class WebSocketHandler extends TextWebSocketHandler {
public static Map<Integer,WebSocketSession> DOCTORONLINE=new HashMap<Integer,WebSocketSession>();
@Override
protected void handleTextMessage(WebSocketSession session,TextMessage message) throws Exception {
super.handleTextMessage(session, message);
Integer userId=null;
if(message.getPayload()!=null&&message.getPayload()!=""){
userId=Integer.parseInt(message.getPayload());
}
if(DOCTORONLINE.get(userId)==null){
DOCTORONLINE.put(userId, session);
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("Websocket:" + session.getId() + "已经关闭");
Iterator<Entry<Integer, WebSocketSession>> it = DOCTORONLINE.entrySet().iterator();
// 移除Socket会话
while (it.hasNext()) {
Entry<Integer, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
DOCTORONLINE.remove(entry.getKey());
System.out.println("Socket会话已经移除:用户ID" + entry.getKey());
break;
}
}
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// TODO Auto-generated method stub
super.afterConnectionEstablished(session);
Integer id=(Integer)session.getAttributes().get("id");
//将消息推送给这个专家
if(DOCTORONLINE.get(id)==null){
DOCTORONLINE.put(id, session);
}
}
@Override
protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
// TODO Auto-generated method stub
super.handlePongMessage(session, message);
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
// TODO Auto-generated method stub
super.handleTransportError(session, exception);
//信息传输时出错的处理
if (session.isOpen()) {
session.close();
}
Iterator<Entry<Integer, WebSocketSession>> it = DOCTORONLINE.entrySet().iterator();
// 移除Socket会话
while (it.hasNext()) {
Entry<Integer, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
DOCTORONLINE.remove(entry.getKey());
System.out.println("Socket会话已经移除:用户ID" + entry.getKey());
break;
}
}
}
@Override
public boolean supportsPartialMessages() {
// TODO Auto-generated method stub
return false;
}
//发送信息给专家
public void sendMessageToDoctor(Integer doctorId, Integer id) throws Exception{
//消息编号必须存在
if(id!=null&&id>=0){
//找到指定的专家doctorId
WebSocketSession session=DOCTORONLINE.get(doctorId);
if(session!=null&&session.isOpen()){
TextMessage textMessage=new TextMessage(String.valueOf(id));
//将消息推送给这个专家
session.sendMessage(textMessage);
}
}
}
}
5.controller中
将id 保存在session中
在index.jsp页面 websocket的使用
var connectCount=0;
var socketFlg=0;
function connect() {
if (window.location.protocol == 'http:') {
url = 'ws://' + window.location.host+urlPath;
} else {
url = 'wss://' + window.location.host + urlPath;
}
if ('WebSocket' in window) {
ws = new WebSocket(url);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket(url);
} else {
ws = new SockJS("http://"+window.location.host+urlPath1);
socketFlg=1;
}
ws.onopen = function () {
if(socketFlg==1){
ws.send(userId);
}
};
ws.onmessage = function (event) {
省略无关代码
};
ws.onclose = function (event) {
socketFlg=0;
if(connectCount<20){
setTimeout("connect()",5000);
connectCount++;
}else{
window.location.href="index.html";
}
};
ws.onerror = function (event) {
window.location.href="index.html";
};
}
var ws = null;
var url = "";
var urlPath="";
var urlPath1="";
var connectCount=0;
var socketFlg=0;
if(window.location.pathname.indexOf("xiangya")>-1){
urlPath="/xiangya"+"/websocket";
urlPath1="/xiangya"+"/socketjs/socket";
}else{
urlPath="/websocket";
urlPath1="/socketjs/socket";
}
connect();
6.补充说明websokect的原理
http://blog.csdn.net/yinqingwang/article/details/52565133
http://blog.csdn.net/frank_good/article/details/50856585