转载:https://blog.csdn.net/rola0418/article/details/79315607
简单发布一个基于springMVC的websocket的实现配置,springMVC的搭建过程这里就不说明了 。只实现H5的websocket,js实现没有考虑
springMVC的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket-4.3.xsd">
<!-- 连接处理的句柄,用于接收消息,推送消息,根据自己来实现需求 -->
<bean id="systemWebSocketHandler" class="com.golden.socket.handler.SystemWebSocketHandler"/>
<!-- allowed-origins="*" 声明支持跨域 -->
<websocket:handlers allowed-origins="*">
<!-- path属性就是声明websocket的服务连接点。如:访问时HTTP://ip:端口/web名称/servers.do-->
<websocket:mapping path="/servers" handler="systemWebSocketHandler"/>
<websocket:handshake-interceptors>
<!-- 连接拦截器,用于连接之前 ,之后做下业务处理-->
<bean class="com.golden.socket.interceptor.WebSocketInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>
</beans>
WebSocketInterceptor类,配置文件中的拦截器
package com.golden.socket.interceptor;
import java.util.Map;
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 org.springframework.web.socket.server.HandshakeInterceptor;
import com.golden.socket.consts.SocketConst;
/**
* 连接成功,会调用这个拦截器
*/
public class WebSocketInterceptor implements HandshakeInterceptor{
/**
* 连接后会调用这个方法
*/
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler webSocketHandler, Exception e) {
System.out.println("WebSocketInterceptor 执行");
}
/**
* 第一次连接会调用这个方法
* 参数params 会自动添加到 WebSocketSession
* loginKey 登录socket-web的标识,用于区分登录身份
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler webSocketHandler,
Map<String, Object> params) throws Exception {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
String loginKey = (String)servletRequest.getServletRequest().getParameter(SocketConst.LOGIN_KEY);
params.put(SocketConst.LOGIN_KEY, loginKey);
return true;
}
}
SystemWebSocketHandler类, 配置文件中的systemWebSocketHandler
package com.golden.socket.handler;
import java.util.Map;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import com.golden.socket.consts.SocketConst;
import com.golden.socket.users.SocketUser;
/**
* 消息服务类
*/
public class SystemWebSocketHandler implements WebSocketHandler {
/**
* 拦截器拦截第一次连接后会调用这个方法
* 业务实现:登录后,将用户存入缓存
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
Map<String, Object> param = session.getAttributes();
String loginKey = param.get(SocketConst.LOGIN_KEY).toString();
SocketUser.put(loginKey, session);
}
/**
* 连接的用户,通过这个方法发送消息会调用这个方法
*/
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
//页面发送的消息,会传到该方法中。
}
/**
* 心跳检测发现连接不上会调用这个方法,之后会调用连接关闭的方法
* 业务实现:删除session
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
Map<String, Object> param = session.getAttributes();
String loginKey = param.get(SocketConst.LOGIN_KEY).toString();
SocketUser.remove(loginKey, session);
}
/**
* 关闭连接会调用这个方法 ,这个关闭会由两个地方触发,一个是浏览器主动退出,还有一个是心跳检测发现连接不上也会调用这个方法。
* 业务实现:发送XX退出消息
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
js 端
var MyWebSocket = function (){
var websocket;
if ('WebSocket' in window) {
websocket = new WebSocket("ws://IP:端口/socket-web/servers?loginKey=sss");
} else if ('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://IP:端口/socket-web/servers");
}else {
return
}
websocket.onopen = function (event) {
//messageFactory.receiveMessage(JSON.parse(event.data))
};
websocket.onmessage = function (event) {
$("#sysContent").html(event.data);
if(!$("#sysMessage").is(":hidden")){
$("#sysMessage").slideUp(1500)
}
$("#sysMessage").slideDown(1500);
};
websocket.onerror = function (event) {
};
websocket.onclose = function (event) {
alert("您已被踢下线");
};
return websocket;
}
$(function (){
var ws = new MyWebSocket();
ws.send("这是我发送的方法");//这个内容会发送到 SystemWebSocketHandler类的 handleMessage方法中
})
WebSocketSession 类说明
这个类可以被看做是传统的web服务器的session。每次连接都会创建一个session,关闭页面就是断开了连接。再连接就会是全新的session。所以再实现功能时,要管理好自己的session.
以上是简单的通讯。具体逻辑和复杂场景需要参考很多知识点,真实场景可能要考虑消息格式的约定,可能需要登录队列,考虑线程,负载等问题。这个只是demo,用于初学者学习