文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:
好好学java
,获取优质学习资源。
WebSocket是客户端和服务器端的一个通信,WebSocket分为客户端和服务端,所以我们两个端都要开发,前端的WebSocket在卖家订单管理界面的js代码里,会进行一个监听,一旦微信点餐的前端对服务端产生一个新的订单,服务端WebSocket就会对含有WebSocket的前端卖家订单管理界面发送消息,收到消息的前端就可以进行一系列的动作,如弹出提醒框、播放音乐等。
后端的开发
第一步 要引入SpringBoot对WebSocket的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
第二步
@Component
public class WebSocketConfig {<!-- -->
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
第三步 在订单业务类的的创建订单方法完成后,后端向前端商家管理系统的订单界面发送WebSocket消息。
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {<!-- -->
@Autowired
private ProductService productService;
@Autowired
private OrderDetailRepository orderDetailRepository;
@Autowired
private WebSocket webSocket;
@Override
@Transactional
public OrderDTO create(OrderDTO orderDTO) {
String orderId= KeyUtil.genUniqueKey();
BigDecimal orderAmount=new BigDecimal(BigInteger.ZERO);
// List<CartDTO> cartDTOList=new ArrayList<>();
//1.查询商品(数量,价格)
for(OrderDetail orderDetail:orderDTO.getOrderDetailList()){
ProductInfo productInfo=productService.findOne(orderDetail.getProductId());
if(productInfo==null){
// throw new SellException(ResultEnum.PRODUCT_NOT_EXIT);
throw new ResponseBankException();
}
//2.计算订单总价
orderAmount=productInfo.getProductPrice()
.multiply(new BigDecimal(orderDetail.getProductQuantity()))
.add(orderAmount);
//订单详情入库
orderDetail.setDetailId(KeyUtil.genUniqueKey());
orderDetail.setOrderId(orderId);
BeanUtils.copyProperties(productInfo,orderDetail);
orderDetailRepository.save(orderDetail);
// CartDTO cartDTO=new CartDTO(orderDetail.getProductId(),orderDetail.getProductQuantity());
// cartDTOList.add(cartDTO);
}
//3,写入订单数据库(orderMaster和orderDetail)
OrderMaster orderMaster=new OrderMaster();
orderDTO.setOrderId(orderId);
BeanUtils.copyProperties(orderDTO,orderMaster);
// orderMaster.setOrderId(orderId);
orderMaster.setOrderAmount(orderAmount);
orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
orderMasterRepository.save(orderMaster);
//4.扣库存
List<CartDTO> cartDTOList=orderDTO.getOrderDetailList().stream().map(e->
new CartDTO(e.getProductId(),e.getProductQuantity()))
.collect(Collectors.toList());
productService.decreaseStock(cartDTOList);
//发送websocket消息(重点)
webSocket.sendMessage(orderDTO.getOrderId());
return orderDTO;
}
这样我们后端WebSocket相关的业务逻辑类已全部完成。
第四步 写一个响应前端WebSocket的后端WebSocket,这也是一个Controller,但比较特殊,是用WS协议进行通信的,我们写在Service包里。
@Component
@ServerEndpoint("/webSocket")
@Slf4j
public class WebSocket {<!-- -->
private Session session;
private static CopyOnWriteArraySet<WebSocket> webSocketSet=new CopyOnWriteArraySet<>();
@OnOpen
public void onOpen(Session session){
this.session=session;
webSocketSet.add(this);
log.info("【websocket消息】 有新的连接,总数:{}",webSocketSet.size());
}
@OnClose
public void onClose(){
webSocketSet.remove(this);
log.info("【websocket消息】 连接断开,总数:{}",webSocketSet.size());
}
@OnMessage
public void onMessage(String message){
log.info("【websocket消息】 收到客户端发来的消息:{}",message);
}
public void sendMessage(String message){
for(WebSocket webSocket:webSocketSet){
log.info("【websocket消息】 广播消息,message={}",message);
try {
webSocket.session.getBasicRemote().sendText(message);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
前端开发
前端卖家商品管理前端界面的WebSocket如下:
<script>
var websocket=null;
if('WebSocket' in window){
websocket=new WebSocket('ws://sqmax.natapp1.cc/sell/webSocket');
}else{
alert('该浏览器不支持websocket');
}
websocket.onopen=function (ev) {<!-- -->
console.log('建立连接');
}
websocket.onclose=function (ev) {<!-- -->
console.log('连接关闭');
}
websocket.onmessage=function (ev) {<!-- -->
console.log('收到消息:'+ev.data);
//弹窗提醒,播放消息
$('#myModal').modal('show');
document.getElementById('notice').play();
}
window.onbeforeunload=function (ev) {<!-- -->
websocket.close();
}
</script>
以下是WebSocket js代码控制HTML。
<div class="modal fade" id="myModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">
提醒
</h4>
</div>
<div class="modal-body">
你有新的订单
</div>
<div class="modal-footer">
<button onclick="javascript:document.getElementById('notice').pause()" type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button onclick="location.reload()" type="button" class="btn btn-primary">查看新的订单</button>
</div>
</div>
</div>
</div>
<#--播放音乐-->
<audio id="notice" loop="loop">
<source src="/sell/mp3/song.mp3" type="audio/mpeg" />
</audio>
当前端收到后端的WebSocket消息后,会弹出一个对话框,并播放音乐。
最后我们来测试一下代码。
我们用Postman这个工具代替前端微信点餐,向指定url发送一个如下的post请求。 在前端的商家管理界面可以看到如下的效果:
出处: