java使用websocket前后端通信实现

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> java使用websocket前后端通信实现

文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号: 好好学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&lt;CartDTO&gt; cartDTOList=new ArrayList&lt;&gt;();

        //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&lt;CartDTO&gt; cartDTOList=orderDTO.getOrderDetailList().stream().map(e-&gt;
                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&lt;WebSocket&gt; webSocketSet=new CopyOnWriteArraySet&lt;&gt;();

    @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如下:


&lt;script&gt;
    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();
    }
&lt;/script&gt;

以下是WebSocket js代码控制HTML。


&lt;div class="modal fade" id="myModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"&gt;
    &lt;div class="modal-dialog"&gt;
        &lt;div class="modal-content"&gt;
            &lt;div class="modal-header"&gt;
                &lt;button type="button" class="close" data-dismiss="modal" aria-hidden="true"&gt;×&lt;/button&gt;
                &lt;h4 class="modal-title" id="myModalLabel"&gt;
                    提醒
                &lt;/h4&gt;
            &lt;/div&gt;
            &lt;div class="modal-body"&gt;
                你有新的订单
            &lt;/div&gt;
            &lt;div class="modal-footer"&gt;
                &lt;button onclick="javascript:document.getElementById('notice').pause()" type="button" class="btn btn-default" data-dismiss="modal"&gt;关闭&lt;/button&gt;
                &lt;button onclick="location.reload()" type="button" class="btn btn-primary"&gt;查看新的订单&lt;/button&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;#--播放音乐--&gt;
&lt;audio id="notice" loop="loop"&gt;
    &lt;source src="/sell/mp3/song.mp3" type="audio/mpeg" /&gt;
&lt;/audio&gt;

当前端收到后端的WebSocket消息后,会弹出一个对话框,并播放音乐。

最后我们来测试一下代码。

我们用Postman这个工具代替前端微信点餐,向指定url发送一个如下的post请求。 这里写图片描述 在前端的商家管理界面可以看到如下的效果: 这里写图片描述

出处:

原文地址:https://sihai.blog.csdn.net/article/details/80924937

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> java使用websocket前后端通信实现


 上一篇
微信用户扫码登录和登录退出的业务逻辑实现(java版) 微信用户扫码登录和登录退出的业务逻辑实现(java版)
文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号: 好好学java,获取优质学习资源。 一、微信用户扫码登录业务逻辑微信用户登录的时候,每次都会带着 openid(用户唯一标志),因此当用户第一次登录的时候,我
2021-04-04
下一篇 
微信公众号授权步骤详细步骤介绍和整合springboot开发(java版) 微信公众号授权步骤详细步骤介绍和整合springboot开发(java版)
文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号: 好好学java,获取优质学习资源。 一、微信公众号授权步骤首先到微信公众平台注册账号,可以看到有四种类型(服务号,订阅号,小程序,企业微信),用到服务号,而且
2021-04-04