java使用websocket前后端通信实现
文章有不當(dāng)之處,歡迎指正,如果喜歡微信閱讀,你也可以關(guān)注我的微信公眾號(hào):好好學(xué)java,獲取優(yōu)質(zhì)學(xué)習(xí)資源。
WebSocket是客戶端和服務(wù)器端的一個(gè)通信,WebSocket分為客戶端和服務(wù)端,所以我們兩個(gè)端都要開發(fā),前端的WebSocket在賣家訂單管理界面的js代碼里,會(huì)進(jìn)行一個(gè)監(jiān)聽,一旦微信點(diǎn)餐的前端對(duì)服務(wù)端產(chǎn)生一個(gè)新的訂單,服務(wù)端WebSocket就會(huì)對(duì)含有WebSocket的前端賣家訂單管理界面發(fā)送消息,收到消息的前端就可以進(jìn)行一系列的動(dòng)作,如彈出提醒框、播放音樂等。
后端的開發(fā)
第一步 要引入SpringBoot對(duì)WebSocket的依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>第二步
@Component public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();} }第三步 在訂單業(yè)務(wù)類的的創(chuàng)建訂單方法完成后,后端向前端商家管理系統(tǒng)的訂單界面發(fā)送WebSocket消息。
@Service @Slf4j public class OrderServiceImpl implements OrderService {@Autowiredprivate ProductService productService;@Autowiredprivate OrderDetailRepository orderDetailRepository;@Autowiredprivate WebSocket webSocket;@Override@Transactionalpublic OrderDTO create(OrderDTO orderDTO) {String orderId= KeyUtil.genUniqueKey();BigDecimal orderAmount=new BigDecimal(BigInteger.ZERO); // List<CartDTO> cartDTOList=new ArrayList<>();//1.查詢商品(數(shù)量,價(jià)格)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.計(jì)算訂單總價(jià)orderAmount=productInfo.getProductPrice().multiply(new BigDecimal(orderDetail.getProductQuantity())).add(orderAmount);//訂單詳情入庫(kù)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,寫入訂單數(shù)據(jù)庫(kù)(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.扣庫(kù)存List<CartDTO> cartDTOList=orderDTO.getOrderDetailList().stream().map(e->new CartDTO(e.getProductId(),e.getProductQuantity())).collect(Collectors.toList());productService.decreaseStock(cartDTOList);//發(fā)送websocket消息(重點(diǎn))webSocket.sendMessage(orderDTO.getOrderId());return orderDTO;}這樣我們后端WebSocket相關(guān)的業(yè)務(wù)邏輯類已全部完成。
第四步 寫一個(gè)響應(yīng)前端WebSocket的后端WebSocket,這也是一個(gè)Controller,但比較特殊,是用WS協(xié)議進(jìn)行通信的,我們寫在Service包里。
@Component @ServerEndpoint("/webSocket") @Slf4j public class WebSocket {private Session session;private static CopyOnWriteArraySet<WebSocket> webSocketSet=new CopyOnWriteArraySet<>();@OnOpenpublic void onOpen(Session session){this.session=session;webSocketSet.add(this);log.info("【websocket消息】 有新的連接,總數(shù):{}",webSocketSet.size());}@OnClosepublic void onClose(){webSocketSet.remove(this);log.info("【websocket消息】 連接斷開,總數(shù):{}",webSocketSet.size());}@OnMessagepublic void onMessage(String message){log.info("【websocket消息】 收到客戶端發(fā)來(lái)的消息:{}",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();}}}}前端開發(fā)
前端賣家商品管理前端界面的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('連接關(guān)閉');}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">關(guān)閉</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>當(dāng)前端收到后端的WebSocket消息后,會(huì)彈出一個(gè)對(duì)話框,并播放音樂。
最后我們來(lái)測(cè)試一下代碼。
我們用Postman這個(gè)工具代替前端微信點(diǎn)餐,向指定url發(fā)送一個(gè)如下的post請(qǐng)求。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-DYvSqyU8-1626146041349)(https://raw.githubusercontent.com/sqmax/springboot-project/blog/pic/12.PNG)]
在前端的商家管理界面可以看到如下的效果:
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-vlenmDZg-1626146041351)(https://raw.githubusercontent.com/sqmax/springboot-project/blog/pic/11.PNG)]
出處:https://github.com/sqmax/springboot-project/wiki/WebSocket%E6%B6%88%E6%81%AF%E6%8E%A8%E9%80%81
總結(jié)
以上是生活随笔為你收集整理的java使用websocket前后端通信实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: spring Aop实现身份验证和spr
- 下一篇: 微信公众号授权步骤详细步骤介绍和整合sp