springboot整合Websocket

1. 应用场景

(1)浏览器打开的支付页面需要知道订单的支付状态
    当用户扫码后,微信首先知道订单已经支付完成,微信可以通过下单时提交的回调接口,通知商户该订单的支付状态
    商户需要实现一个接口用于接受微信的通知
    在这个接口中,需要根据微信传来的订单编号,寻找到打开的支付页面的浏览器,并主动通知该浏览器订单支付成功了。
   
(2)投票结果展示页面,需要每隔3秒钟自动显示最新的投票结果

2. Websocket原理

(1)浏览器与后端服务器建立长连接,除非某一方主动关闭连接,否则该连接一致存在。
(2)该长连接是双向的,即允许浏览器主动给服务器发消息,也允许服务器主动给浏览器发消息(推送)。

3. Springboot实现Websocket

(1)POM文件中添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

(2)WebSocket配置类

package com.qf.fmall.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * 向IOC容器中添加ServerEndpointExporter类型的bean
 * 作用:可以识别到我们编写websocket类上的@serverEndpoing 注解
 */

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter endpointExporter(){
        return new ServerEndpointExporter();
    }

}

(3)WebSocket后端接口

package com.qf.fmall.websocket;

import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Component
@ServerEndpoint("/test")
public class MyWebSocketServer {

    /**
     * 当某个浏览器跟我们的服务器建立连接时,需要做的事情,写在这个方法里
     *
     * @param session 这个对象就是浏览器与服务器建立好的websocket长连接对象
     * @throws IOException
     */
    @OnOpen
    public void onOpen(Session session) throws IOException, InterruptedException {
        System.out.println("服务器端接收到了连接请求......");
        //发送消息给浏览器
        session.getBasicRemote().sendText("hello from server " + new Date().toLocaleString());

        String line1 = "告白气球";
        String line2 = "塞纳河畔左岸的咖啡";
        String line3 = "我手一杯,品尝你的美";
        String line4 = "留下唇印的嘴";

        List<String> list = Arrays.asList(line1, line2, line3, line4);
        for (String line : list) {
            Thread.sleep(1000);
            session.getBasicRemote().sendText(line);
        }


    }

    /**
     * 当浏览器发送消息给服务器时,需要做的事情,写在这个方法里
     *
     * @param session 这个对象就是浏览器与服务器建立好的websocket长连接对象
     * @param msg     浏览器发送的消息的内容
     */
    @OnMessage
    public void onMessage(Session session, String msg) throws IOException {
        System.out.println("接收到浏览器发送的消息内容为:" + msg);
        //给浏览器发送一个消息
        String serverMsg = "来自服务器端的响应:" + msg;
        session.getBasicRemote().sendText(serverMsg);

    }


    /**
     * 当浏览器关闭连接时,要做的事情写在这个方法里
     *
     * @param session
     * @throws IOException
     */
    @OnClose
    public void onClose(Session session) throws IOException {
        System.out.println("浏览器断开连接,断开的session对象为:" + session.getId());
        session.close();
    }


}

(4) 在线测试websocket接口

http://www.websocket-test.com/

 4.websocket实现订单管理的微信支付的回调方法

在微信支付成功以后,微信发送一个请求给后端,告诉后端我完成支付了,后端收到这个请求以后会,修改数据库,然后把这个成功标志,通过websocket发送给前端,前端收到这个信息,判断为成功,然后修改页面html显示成功!!!

(1)配置类和上面一样,这里只写实现

package com.qf.fmall.websocket;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;

import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;

@Component
@ServerEndpoint("/order/{orderid}")
public class OrderWebSocketServer {

    public static HashMap<String,Session>  sessionMap= new HashMap<>();

    public static void pushMsg(String orderId, String msg) throws IOException {
        Session session = sessionMap.get(orderId);
        session.getBasicRemote().sendText(msg);
    }


    @OnOpen
    public void onOpen(@PathParam("orderid") String orderid, Session session){
        System.out.println("接收到浏览器的连接请求,orderid="+orderid);
        //如何保存与该浏览器建立的session对象呢?
        sessionMap.put(orderid,session);

    }

    @OnClose
    public void onCloss(@PathParam("orderid") String orderid, Session session) throws IOException {

        sessionMap.remove(orderid);
        session.close();

    }

}

(2)在OrderController里写一个回调接口

    @GetMapping("/test/{orderid}")
    public ResultVo testWebSocket(@PathVariable("orderid") String orderid) throws IOException {
        //给该orderid打开的浏览器页面,主动推送一个消息
        OrderWebSocketServer.pushMsg(orderid,"1");
        return ResultVo.vo(FmallConstants.SUCCESS_CODE,FmallConstants.SUCCESS_MSG,"OK");
    }

展示一下静态方法

    /**
     * 发送成功回调函数给前端
     * @param orderId 订单编号
     * @param msg 成功的信息
     * @throws IOException
     */
    public static void pushMsg(String orderId, String msg) throws IOException {
        
        //修改数据库
        
        
        
        Session session = sessionMap.get(orderId);
        session.getBasicRemote().sendText(msg);
    }

5.前端怎么发送websocket请求

//前端发送websocket连接请求
var webSocketUrl = "ws://127.0.0.1:8080/webSocket/订单编号";
var websocket = new WebSocket( webSocketUrl );
//只要后端通过websocket向此连接发消息就会触发onmessage事件
websocket.onmessage = function(event){
	var msg = event.data;
	if(msg=="1"){
		$("#div1").html("<label style='font-size:20px; color:green'>订单支付完成!</label>");
	}
}

    websocket.onmessage = function(event) 这行代码是为WebSocket对象的 onmessage 事件设置一个事件处理程序。 当WebSocket连接从服务器接收到消息时,将触发 onmessage 事件。通过为 websocket.onmessage 赋予一个函数,您定义了在接收到消息时应采取的操作。 在提供的代码片段中, (event) 是当接收到消息时将执行的事件处理程序。您可以通过 event.data 在此函数中访问接收到的消息,并根据接收到的消息执行任何所需的操作或处理。 例如,您可以更新用户界面、显示接收到的消息,或者基于接收到的消息内容触发其他函数。 

         要通过WebSocket从前端向服务器发送消息,您需要建立WebSocket连接,然后使用 `send()` 方法将消息发送到服务器。以下是使用JavaScript实现的示例:

// 建立WebSocket连接
const socket = new WebSocket('ws://your-server-url');

// 连接打开时的事件监听器
socket.addEventListener('open', function (event) {
    // 向服务器发送消息
    socket.send('你好,服务器!');
});

// 来自服务器的消息的事件监听器
socket.addEventListener('message', function (event) {
    // 处理从服务器接收到的消息
    console.log('来自服务器的消息:', event.data);
});


         在这个示例中,通过将服务器URL传递给构造函数创建了一个新的WebSocket对象。一旦连接打开,您可以使用 `send()` 方法向服务器发送消息。此外,您可以使用 `message` 事件监听器监听来自服务器的消息,并根据需要进行处理。

       请确保将 `'ws://your-server-url'` 替换为实际的WebSocket服务器URL,以便连接到您希望连接的WebSocket服务器。

var websocket = new WebSocket( webSocketUrl );//连接服务器

socket.send('你好,服务器');//向服务器发送消息

socket.close('关闭服务器连接')//关闭与服务器的连接

socket.onmessage = function(event){
    var msg = event.data;
    if(msg=="1"){
        $("#div1").html("<label style='font-size:20px; color:green'>订单支付完成!</label>");
    }
}//服务器向前端发送消息的时候,触发的监听事件。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值