1.实例化
@Configuration
@EnableWebSocket
// 开启websocket
public class SystemWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(echoWebSocketHandler(), "/notice.ws").addInterceptors(new WebSocketHandshakeInterceptor()); // 提供符合W3C标准的Websocket数据
registry.addHandler(echoWebSocketHandler(), "/sockjs/notice.ws")
.addInterceptors(new WebSocketHandshakeInterceptor()).withSockJS();// 提供符合SockJS的数据
}
@Bean
public WebSocketHandler echoWebSocketHandler() {
return new SystemWebSocketHandler();
}
@Bean
public WebSocketHandler snakeWebSocketHandler() {
return new SystemWebSocketHandler();
}
// Allow serving HTML files through the default Servlet
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
* {@inheritDoc}
* <p>
* This implementation is empty.
*/
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
// -1 为用不失效
configurer.setDefaultTimeout(-1);
}
}
2.定义处理类
public class SystemWebSocketHandler extends TextWebSocketHandler {
/**
* 日志记录器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(SystemWebSocketHandler.class);
// 连接创建生效以后执行的方法
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
LOGGER.info("Socket 连上了");
String gwID = (String) session.getAttributes().get("gwID");
String amID = (String) session.getAttributes().get("amID");
if (!StringUtils.isEmpty(gwID) || !StringUtils.isEmpty(amID)) {
if (null != gwID) {
if (session.isOpen()) {
SocketMessageUtil.addNewConnector(gwID, session);
}
}
if (null != amID) {
if (session.isOpen()) {
SocketMessageUtil.addNewConnector(amID, session);
}
}
}
}
// 接收客户端发送过来的消息
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
LOGGER.info("Socket 接收客户端发送过来的消息");
String msgContent = message.getPayload().toString();
String gwID = (String) session.getAttributes().get("gwID");
if (!StringUtils.isEmpty(msgContent) && "1".equals(msgContent)) {
TextMessage message1 = new TextMessage("1");
SocketMessageUtil.sendMessageToUser(gwID, message1);
} else {
for (int i = 0; i < 10; i++) {
TextMessage message1 = new TextMessage("2");
SocketMessageUtil.sendMessageToUser(gwID, message1);
}
}
}
// 传输错误时触发
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
exception.printStackTrace();
}
// 连接关闭时触发
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
LOGGER.info("Socket 连接关闭");
String gwID = (String) session.getAttributes().get("gwID");
String amID = (String) session.getAttributes().get("amID");
if (!StringUtils.isEmpty(gwID) || !StringUtils.isEmpty(amID)) {
if (null != gwID) {
SocketMessageUtil.deleteConnector(gwID);
}
if (null != amID) {
SocketMessageUtil.deleteConnector(amID);
}
} else {
SocketMessageUtil.deleteConnector(session);
}
}
/**
* 是否支持分步消息
*/
@Override
public boolean supportsPartialMessages() {
return false;
}
}
public class WebSocketHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
/**
* 日志记录器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketHandshakeInterceptor.class);
@Override
public void afterHandshake(ServerHttpRequest arg0, ServerHttpResponse arg1, WebSocketHandler arg2, Exception arg3) {
LOGGER.info("socket通信后 to do something ");
}
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse arg1, WebSocketHandler handler,
Map<String, Object> attribute) throws Exception {
LOGGER.info("socket通信前 to do something ");
if (request instanceof ServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
GwAccountBean gwInfo = (GwAccountBean) session.getAttribute("gwInfo");
if (null != gwInfo) {
attribute.put("gwID", gwInfo.getId());
}
AdminAccountBean amInfo = (AdminAccountBean) session.getAttribute("amInfo");
if (null != amInfo) {
attribute.put("amID", amInfo.getEmpId());
}
}
return true;
}
}
4.定义util工具类
public class SocketMessageUtil {
/**
* 日志记录器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(SocketMessageUtil.class);
/**
* 存储所有连接用户链接 映射所有的socket 的id 和socket
*/
private static Map<String, WebSocketSession> idSocketMap = new HashMap<String, WebSocketSession>();
/**
* 映射Gw 和 gw的socket链接
*/
private static Map<String, List<String>> gwIdSocketIdMap = new HashMap<String, List<String>>();
/**
* 添加新的链接用户
*
* @param userId
* @param socketSession
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void addNewConnector(String userId, WebSocketSession socketSession) {
if (StringUtils.isNotEmpty(userId) && null != socketSession && socketSession.isOpen()
&& !StringUtils.isEmpty(socketSession.getId())) {
idSocketMap.put(socketSession.getId(), socketSession);
if (StringUtils.isNotEmpty(userId)) {
List<String> socketIdList = gwIdSocketIdMap.get(userId);
if (null == socketIdList) {
socketIdList = new ArrayList<String>();
socketIdList.add(socketSession.getId());
gwIdSocketIdMap.put(userId, socketIdList);
} else {
if (!socketIdList.contains(socketSession.getId())) {
socketIdList.add(socketSession.getId());
gwIdSocketIdMap.put(userId, socketIdList);
}
}
}
}
}
/**
* 注销用户链接
*
* @param userId
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void deleteConnector(String userId) {
if (StringUtils.isNotEmpty(userId)) {
List<String> socketIdList = gwIdSocketIdMap.get(userId);
if (null != socketIdList) {
for (String socketId : socketIdList) {
if (StringUtils.isNotBlank(socketId)) {
idSocketMap.remove(socketId);
}
}
}
gwIdSocketIdMap.remove(userId);
}
}
/**
* 注销用户链接
*
* @param user
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void deleteConnector(WebSocketSession user) {
if (null != user && !StringUtils.isEmpty(user.getId())) {
for (Entry<String, WebSocketSession> entry : idSocketMap.entrySet()) {
if (user.getId().equals(entry.getValue().getId())) {
idSocketMap.remove(entry.getKey());
}
}
}
}
/**
* 给所有在线用户发送消息
*
* @param message
*/
public static void sendMessageToAllUsers(TextMessage message) {
for (WebSocketSession user : idSocketMap.values()) {
try {
if (user.isOpen()) {
user.sendMessage(message);
} else {
}
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
}
}
/**
* 给某个用户发送消息
*
* @param userName
* @param message
*/
public static void sendMessageToUser(String userId, TextMessage message) {
if (StringUtils.isBlank(userId) || null == message) {
return;
} else {
while(true){
List<String> socketIdList = gwIdSocketIdMap.get(userId);
if (null != socketIdList) {
WebSocketSession session;
String socketId;
for (int x = socketIdList.size() - 1; x >= 0; x--) {
socketId = socketIdList.get(x);
if (!StringUtils.isEmpty(socketId)) {
session = idSocketMap.get(socketId);
if (null != session && session.isOpen()) {
try {
session.sendMessage(message);
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
} else {
socketIdList.remove(x);
}
}
}
gwIdSocketIdMap.put(userId, socketIdList);
}
try {
Thread.currentThread().sleep(1000 * 60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
}
}
/**
* 给客户端发消息
*
* @param user
* @param message
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static void sendMessageToSocketClient(WebSocketSession user, TextMessage message) {
if (null != user && user.isOpen() && null != message) {
try {
user.sendMessage(message);
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
}
}
/**
* 查看当前的Websocket 活动连接数
*
* @return
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static int countCurrentActiveClientSize() {
LOGGER.info("xxxxxx 当前Socket连接数 --" + gwIdSocketIdMap.entrySet().size() + " ---------------");
return gwIdSocketIdMap.entrySet().size();
}
}
5.定义js操作
// 通讯
if (window.WebSocket) {
socket = new WebSocket(webSocketUrl);
//为websocket连接服务器异常注册事件
socket.onerror = function(msg) {
//alert("连接服务器异常" + msg.data);
};
//为websocket连接到服务器时注册事件
socket.onopen = function(msg) {
//alert("连接到服务器OK");
};
//处理从服务端发送过来的数据
var i = 0;
socket.onmessage = function(data) {
var $type = i % 3;
var opt = {
tips: '老刘傻逼傻+'+i,
url : '',
type: $type ,
total: i
};
i++;
messageBox(opt);
};
//为websocket注册消息处理事件
socket.onclose = function(msg) {
//alert("注销");
};
}
$('.logo').click(function(){
socket.send('2');
});
完成!