WebSocket入门

介绍

WebSocket 是基于 TCP 的一种新的网络协议 。它实现了浏览器与服务器全双工通信------浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性 的连接, 并进行双向数据传输。

HTTP协议和WebSocket协议对比:

  • HTTP是短连接
  • WebSocket是长连接
  • HTTP通信是单向的,基于请求响应模式
  • WebSocket支持双向通信
  • HTTP和WebSocket底层都是TCP连接

实现步骤:

1). 导入WebSocket的maven坐标

xml 复制代码
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2). 编写WebSocket服务端组件WebSocketServer,用于和客户端通信

java 复制代码
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.PathParam;  
import javax.websocket.server.ServerEndpoint;  
import java.util.Collection;  
import java.util.HashMap;  
import java.util.Map;  
  
/**  
 * WebSocket服务  
 */  
@Component  
@ServerEndpoint("/ws/{sid}")  
public class WebSocketServer {  
  
    //存放会话对象  
    private static Map<String, Session> sessionMap = new HashMap();  
  
    /**  
     * 连接建立成功调用的方法  
     */  
    @OnOpen  
    public void onOpen(Session session, @PathParam("sid") String sid) {  
        System.out.println("客户端:" + sid + "建立连接");  
        sessionMap.put(sid, session);  
    }  
  
    /**  
     * 收到客户端消息后调用的方法  
     *  
     * @param message 客户端发送过来的消息  
     */  
    @OnMessage  
    public void onMessage(String message, @PathParam("sid") String sid) {  
        System.out.println("收到来自客户端:" + sid + "的信息:" + message);  
    }  
  
    /**  
     * 连接关闭调用的方法  
     *  
     * @param sid  
     */  
    @OnClose  
    public void onClose(@PathParam("sid") String sid) {  
        System.out.println("连接断开:" + sid);  
        sessionMap.remove(sid);  
    }  
  
    /**  
     * 群发  
     *  
     * @param message  
     */  
    public void sendToAllClient(String message) {  
        Collection<Session> sessions = sessionMap.values();  
        for (Session session : sessions) {  
            try {  
                //服务器向客户端发送消息  
                session.getBasicRemote().sendText(message);  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
}
  • @Component 注解将此类交由Spring容器管理

  • @ServerEndpoint注解指明前后端请求路径,作用类似http请求的@RequestMapping注解

  • 框架将每一个客户端与服务器的连接都抽象为了一个会话对象session,此处以sid:session的形式将所有session存入本类的静态变量sessionMap中,便于后续使用

  • 带有@OnOpen注解的方法会在建立连接时由框架自动调用,方法参数中如果有路径参数必须使用@PathParam("sid")显式指明。通过在这个方法的方法体中将每次建立的会话存入sessionMap

  • @OnMessage ,@OnClose 分别为收到客户端消息时,连接关闭时调用的方法,可以借@OnClose删除session,确保sessionMap中都是实时存在的有效会话

  • 群发消息:遍历sessionMap得到每个session,来向每一个已连接的客户端发送消息

3). 编写配置类WebSocketConfiguration,启用对Java WebSocket API中@ServerEndpoint注解的支持

java 复制代码
  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.socket.server.standard.ServerEndpointExporter;  
  
/**  
 * WebSocket配置类,用于注册WebSocket的Bean  
 */@Configuration  
public class WebSocketConfiguration {  
  
    @Bean  
    public ServerEndpointExporter serverEndpointExporter() {  
          
        return new ServerEndpointExporter();  
    }  
  
}

代码比较固定,可以直接cv

4). 在业务逻辑中合理调用组件方法

假设如下场景:用户在外卖平台下单后想要催单,这时我们必须保证商家实时收到催单信息,此时就要用到WebSocket了

Service层催单接口如下:

java 复制代码
@Override  
public void reminder(Long id) {  
  
    Orders ordersDB = orderMapper.getById(id);  
  
    // 校验订单是否存在  
    if (ordersDB == null) {  
        throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);  
    }  
  
    Map map = new HashMap();  
    map.put("type", 2);  
    map.put("orderId", id);  
    map.put("content", "订单号:" + ordersDB.getNumber());  
  
    String jsonString = JSON.toJSONString(map);  
    webSocketServer.sendToAllClient(jsonString);  
  
}

业务逻辑如下:

先根据id查询相应数据,接着将数据返回给前端。一般情况下传输的数据都是JSON格式的,因此就可以将数据先保存在map集合中,再通过JSON.toJSONString();方法便捷得到JSON格式的字符串,最后通过调用群发方法将消息发送到商家管理端

相关推荐
sthnyph12 分钟前
Spring Framework 中文官方文档
java·后端·spring
zb2006412022 分钟前
Spring Boot 实战篇(四):实现用户登录与注册功能
java·spring boot·后端
青柠代码录32 分钟前
【MySQL】事务:事务的隔离级别
后端
分享牛36 分钟前
Operaton入门到精通22-Operaton 2.0 升级指南:Spring Boot 4 核心变更详解
java·spring boot·后端
jinanmichael36 分钟前
SpringBoot 如何调用 WebService 接口
java·spring boot·后端
深蓝轨迹37 分钟前
吃透 Spring Boot dataSource与Starter
java·spring boot·笔记·后端
spring29979239 分钟前
springboot和springframework版本依赖关系
java·spring boot·后端
yuhaiqiang43 分钟前
为什么这道初中数学题击溃了所有 AI
前端·后端·面试
面向Google编程1 小时前
从零学习Kafka:副本机制
大数据·后端·kafka
超级大福宝1 小时前
用买火车票的例子讲解Java反射的作用
java·开发语言·后端