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