WebSocket——相关介绍以及后端配置

一、WebSocket介绍:

        WebSocket是一种在单个TCP连接上进行全双工通信的协议,旨在改进客户端和服务器之间的实时通信。以下是关于WebSocket的详细介绍:

1、定义与标准

  • WebSocket是独立的、创建在TCP上的协议,通过HTTP/1.1协议的101状态码进行握手。
  • WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

2、工作原理

  • WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
  • 在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

3、特点

  1. 实时性:由于协议是全双工的,服务器可以随时主动给客户端下发数据,相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少。
  2. 较少的控制开销:在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。
  3. 保持连接状态:与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。
  4. 更好的二进制支持:Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
  5. 跨域支持:WebSocket协议可以跨域使用,允许不同源的客户端与服务器进行通信。

4、用途

        WebSocket特别适合需要连续数据交换的服务,如网络游戏、实时交易系统、在线聊天应用、实时协作编辑、实时数据展示、在线游戏、实时地图应用、在线投票系统、实时监控系统以及实时消息推送等。

5、帧结构

        WebSocket的通信以帧为单位进行,帧的结构包括RSV1、RSV2、RSV3(默认为0,仅当使用extension扩展时,有扩展决定其值)、opcode(帧的类型)、FIN(表示消息的结尾)以及消息长度等内容。

二、WebSocket后端配置:

step1:首先是依赖下载:

        下面是一般项目的常用依赖:

<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>2.0.25</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.14.0</version>
		</dependency>
		<dependency>
			<groupId>com.auth0</groupId>
			<artifactId>java-jwt</artifactId>
			<version>4.3.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
		</dependency>
		<dependency>
			<groupId>org.dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>2.1.3</version>
		</dependency>

		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.8.10</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web-services</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>3.0.3</version>
		</dependency>

		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter-test</artifactId>
			<version>3.0.3</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.assertj</groupId>
			<artifactId>assertj-core</artifactId>
		</dependency>
	</dependencies>

step2:然后是定义配置类:

        GetHttpSession:

package com.example.cqcrhouduan.config;

import jakarta.servlet.http.HttpSession;
import jakarta.websocket.HandshakeResponse;
import jakarta.websocket.server.HandshakeRequest;
import jakarta.websocket.server.ServerEndpointConfig;

public class GetHttpSession extends ServerEndpointConfig.Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response){
        // 获取httpSession对象
        HttpSession httpSession = (HttpSession) request.getHttpSession();
        // 将httpSession保存起来
        sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
    }
}

        WebsocketConfig:

package com.example.cqcrhouduan.config;

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

@Configuration
public class WebsocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

 step3:然后是定义相关工具和信息类:

        Message:

package com.example.cqcrhouduan.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Message {
    private String toName;
    private String message;
}

         MessageUtil:

package com.example.cqcrhouduan.pojo;

import com.alibaba.fastjson.JSON;

public class MessageUtil {
    public static String getMessage(boolean isSystemMessage,String fromName,Object message){
        ResultMessage result = new ResultMessage();
        result.setSystem(isSystemMessage);
        result.setMessage(message);
        if(fromName != null){
            result.setFormName(fromName);
        }
        return JSON.toJSONString(result);
    }
}

        ChatEndPoint:

package com.example.cqcrhouduan.pojo;

import com.alibaba.fastjson.JSON;
import com.example.cqcrhouduan.config.GetHttpSession;
import jakarta.servlet.http.HttpSession;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/chat",configurator = GetHttpSession.class)
@Component
public class ChatEndPoint {

    private  static final Map<String,Session> onlineUser = new ConcurrentHashMap<>();

    private  HttpSession httpSession;
    @OnOpen
    public void onOpen(Session session, EndpointConfig config){
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        String user = (String) this.httpSession.getAttribute("user");
        // 1、将session进行保存
        onlineUser.put(user,session);
        // 2、广播消息,将所有登录的用户推送给所有的用户
        String message = MessageUtil.getMessage(true,null,getFriends());
        broadcastAllUser(message);
    }
    private void broadcastAllUser(String Message){
        try{
            // 遍历map集合
            Set<Map.Entry<String,Session>> entries = onlineUser.entrySet();
            for(Map.Entry<String,Session> entry : entries){
                // 获取所有用户对应的session对象
                Session session = entry.getValue();
                session.getBasicRemote().sendText(Message);
            }
        }catch (Exception e){
            // 记录日志等等
        }

    }
    public Set getFriends(){
        Set<String> set = onlineUser.keySet();
        return set;
    }


    @OnMessage
    public void opMessage(String message){
        try{
            // 将消息推送给指定的用户:
            Message msg = JSON.parseObject(message,Message.class);
            //获取 消息接收方的名称
            String toNmae = msg.getToName();
            String mes = msg.getMessage();
            Session session = onlineUser.get(toNmae);
            String user = (String) this.httpSession.getAttribute("user");
            String mess = MessageUtil.getMessage(false,user,mes);
            session.getBasicRemote().sendText(mess);
        }catch (Exception e){
            // log
        }



    }



    @OnClose
    public void onClose(Session session){
        String user = (String) this.httpSession.getAttribute("user");
        // 1.从onlinesUser中剔除当前用户
        onlineUser.remove(user);
        // 2.通知其它所有的用户
        String message = MessageUtil.getMessage(true,null,getFriends());
        broadcastAllUser(message);
    }
}

        ResultMessage:

package com.example.cqcrhouduan.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResultMessage {
    private  boolean System;
    private  String formName;
    private  Object Message;
}

 至此关于Socket利用session来获取信息的后端类的配置就全部完成了,后面将会继续提供前端的配置方法。<( ̄︶ ̄)>!

相关推荐

  1. WebSocket——相关介绍以及配置

    2024-05-26 01:16:10       27 阅读
  2. 配置相关字段的前端跨域处理

    2024-05-26 01:16:10       26 阅读
  3. 使用springboot 配置一个websocket客户

    2024-05-26 01:16:10       36 阅读
  4. chatGPT以及openAI介绍相关概念

    2024-05-26 01:16:10       35 阅读
  5. vue实现stompjs+websocket通信(二)

    2024-05-26 01:16:10       34 阅读
  6. Websocket前端与:深度探索与实战应用

    2024-05-26 01:16:10       27 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-26 01:16:10       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-26 01:16:10       101 阅读
  3. 在Django里面运行非项目文件

    2024-05-26 01:16:10       82 阅读
  4. Python语言-面向对象

    2024-05-26 01:16:10       91 阅读

热门阅读

  1. 29. 相似矩阵,若尔当型

    2024-05-26 01:16:10       28 阅读
  2. 14. Tomcat面试题汇总

    2024-05-26 01:16:10       38 阅读
  3. Tomcat 启动闪退问题解决方法

    2024-05-26 01:16:10       29 阅读
  4. CCF-CSP认证考试 202403-3 化学方程式配平 100分题解

    2024-05-26 01:16:10       32 阅读
  5. 什么是vue

    2024-05-26 01:16:10       27 阅读
  6. CentOS常见命令

    2024-05-26 01:16:10       34 阅读
  7. php 使用phpoffice导出导出excel

    2024-05-26 01:16:10       27 阅读
  8. Debian常用命令

    2024-05-26 01:16:10       36 阅读
  9. Mybatis-Plus-Join

    2024-05-26 01:16:10       39 阅读
  10. 前端人员选择组件封装

    2024-05-26 01:16:10       25 阅读
  11. springboot集成mybatis 单元测试

    2024-05-26 01:16:10       35 阅读
  12. 88道测试工具考核高频题整理(附答案背诵版)

    2024-05-26 01:16:10       29 阅读
  13. 第7周 接口重试机制设计与消息队列

    2024-05-26 01:16:10       32 阅读