parent
17cbf7a390
commit
1ca0755341
@ -0,0 +1,22 @@
|
||||
package cc.yunxi.config;
|
||||
|
||||
import cc.yunxi.utils.WsSocketHandler;
|
||||
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;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
@Resource
|
||||
private WsSocketHandler wsSocketHandler;
|
||||
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(wsSocketHandler, "/webSocketServer").setAllowedOrigins("*");
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cc.yunxi.domain.vo.socket;
|
||||
|
||||
public enum MessageTypeEnum {
|
||||
BOOKING("新订单"),
|
||||
TAKEN("已接单"),
|
||||
FINISH("已完成"),
|
||||
CANCEL("已取消");
|
||||
private final String status;
|
||||
|
||||
MessageTypeEnum(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getStatus();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package cc.yunxi.domain.vo.socket;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ApiModel("socket消息体")
|
||||
|
||||
public class SocketMessage {
|
||||
@ApiModelProperty("消息类型")
|
||||
private MessageTypeEnum messageType;
|
||||
@ApiModelProperty("订单号")
|
||||
private String orderNo;
|
||||
@ApiModelProperty("订单状态")
|
||||
private String orderStatus;
|
||||
@ApiModelProperty("商品类型")
|
||||
private String goodsType;
|
||||
@ApiModelProperty("预约时间")
|
||||
private String orderTime;
|
||||
@ApiModelProperty("预约人号码")
|
||||
private String orderPhone;
|
||||
@ApiModelProperty("预约地址")
|
||||
private String orderAddress;
|
||||
@ApiModelProperty("预计重量")
|
||||
private String orderWeight;
|
||||
@ApiModelProperty("接单人")
|
||||
private String takeOrderUser;
|
||||
@ApiModelProperty("接单时间")
|
||||
private String takeOrderTime;
|
||||
@ApiModelProperty("接单人电话")
|
||||
private String takeUserPhone;
|
||||
@ApiModelProperty("完成时间")
|
||||
private String finishTime;
|
||||
@ApiModelProperty("实际金额")
|
||||
private String realMoney;
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cc.yunxi.domain.vo.vxmessage;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@ApiModel("值模板")
|
||||
public class ValueTemplate {
|
||||
@ApiModelProperty("值")
|
||||
private String value;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package cc.yunxi.service;
|
||||
|
||||
import cc.yunxi.domain.vo.socket.SocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* ws操作相关服务
|
||||
*/
|
||||
public interface IWsService {
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param userinfo 用户唯一标识
|
||||
* @param message 消息内容
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public void sendMsgToUser(String userinfo, SocketMessage message) throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* 广播消息
|
||||
*
|
||||
* @param text
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public void broadcastMsg(String text);
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package cc.yunxi.service.impl;
|
||||
|
||||
import cc.yunxi.domain.vo.socket.SocketMessage;
|
||||
import cc.yunxi.service.IWsService;
|
||||
import cc.yunxi.utils.WsSessionManager;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class WsServiceImpl implements IWsService {
|
||||
|
||||
@Resource
|
||||
private WsSessionManager sessionManager;
|
||||
|
||||
@Override
|
||||
public void sendMsgToUser(String userinfo, SocketMessage message) throws IOException {
|
||||
String text = JSONUtil.toJsonStr(message);
|
||||
WebSocketSession userSession = sessionManager.getUserSession(userinfo);
|
||||
if (userSession != null && userSession.isOpen()) {
|
||||
userSession.sendMessage(new TextMessage(text));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastMsg(String text) {
|
||||
ConcurrentHashMap<String, WebSocketSession> allSession = sessionManager.getAllSession();
|
||||
if (null != allSession && allSession.size() > 0) {
|
||||
for (WebSocketSession session : allSession.values()) {
|
||||
try {
|
||||
if (null != session && session.isOpen()) {
|
||||
session.sendMessage(new TextMessage(text));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package cc.yunxi.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WsSessionManager {
|
||||
/**
|
||||
* 保存连接 session 的地方
|
||||
*/
|
||||
private static ConcurrentHashMap<String, WebSocketSession> SESSION_POOL = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, WebSocketSession> USER_SESSION_POOL = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 添加 session
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public void add(String key, WebSocketSession session) {
|
||||
// 添加 session
|
||||
SESSION_POOL.put(key, session);
|
||||
}
|
||||
|
||||
public void addUserSession(String key, WebSocketSession session) {
|
||||
//获取旧session
|
||||
WebSocketSession oldSession = USER_SESSION_POOL.get(key);
|
||||
if (null == oldSession //没有
|
||||
|| !oldSession.getId().equals(session.getId()) //id不同
|
||||
|| !oldSession.isOpen()) { //旧session已关闭
|
||||
USER_SESSION_POOL.put(key, session); //则将新的session添加到池中
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 session,会返回删除的 session
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public WebSocketSession remove(String key) {
|
||||
// 删除 session
|
||||
USER_SESSION_POOL.remove(key);
|
||||
return SESSION_POOL.remove(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除并同步关闭连接
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public void removeAndClose(String key) {
|
||||
WebSocketSession session = remove(key);
|
||||
if (session != null) {
|
||||
try {
|
||||
// 关闭连接
|
||||
session.close();
|
||||
} catch (IOException e) {
|
||||
// todo: 关闭出现异常处理
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 session
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public WebSocketSession getUserSession(String key) {
|
||||
// 获得 session
|
||||
return USER_SESSION_POOL.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 session
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public WebSocketSession getSession(String key) {
|
||||
// 获得 session
|
||||
return USER_SESSION_POOL.get(key);
|
||||
}
|
||||
|
||||
//获取所有链接
|
||||
public ConcurrentHashMap<String, WebSocketSession> getAllSession() {
|
||||
return SESSION_POOL;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
package cc.yunxi.utils;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.BinaryMessage;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* ws消息处理类
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class WsSocketHandler extends AbstractWebSocketHandler {
|
||||
|
||||
@Resource
|
||||
private WsSessionManager SESSION_MANAGER;
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
log.info("建立ws连接");
|
||||
SESSION_MANAGER.add(session.getId(), session);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
|
||||
log.info("发送文本消息");
|
||||
// 获得客户端传来的消息
|
||||
String payload = message.getPayload();
|
||||
log.info("server 接收到消息 " + payload);
|
||||
JSONObject json = JSONUtil.parseObj(payload);
|
||||
String userId = json.getStr("userId");
|
||||
SESSION_MANAGER.addUserSession(userId, session);
|
||||
session.sendMessage(new TextMessage("server 发送给的消息 " + payload + ",发送时间:" + LocalDateTime.now().toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
|
||||
log.info("发送二进制消息");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
||||
log.error("异常处理");
|
||||
SESSION_MANAGER.removeAndClose(session.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||
log.info("关闭ws连接");
|
||||
SESSION_MANAGER.removeAndClose(session.getId());
|
||||
}
|
||||
}
|
Loading…
Reference in new issue