WebSocket总结

1.WebSocket

1.1.什么是WebSocket?

WebSocket是HTML5一种新的协议,它实现了浏览器与服务器全双工通信(full-duplex),一开始的握手需要借助HTTP请求完成。WebSocket是真正实现了全双工通信的服务器向客户端推的互联网技术,它是一种在单个TCP连接上进行全双工通讯协议。

1.2.Http与Websocket的区别

1.http:http协议是短连接,因为请求之后,都会关闭连接,下次重新请求数据,需要再次打开连接
在这里插入图片描述
2.WebSocket:WebSocket是一种长连接,只需要通过一次请求初始化链接,然后所有的请求和响应都是通过这个TCP连接进行通讯
在这里插入图片描述

1.3.服务器和客户端对WebSocket的支持情况

在这里插入图片描述
查看:https://caniuse.com/#search=websocket

服务器支持情况:Tomcat 7.0.47+以上才支持

1.4.WebSocket的Demo

1.4.1.创建WebSocket的Demo工程

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.fechin.websocket</groupId>
    <artifactId>demo-websoket</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--spring boot的支持-->
    <!--    <parent>-->
    <!--        <groupId>org.springframework.boot</groupId>-->
    <!--        <artifactId>spring-boot-starter-parent</artifactId>-->
    <!--        <version>2.1.0.RELEASE</version>-->
    <!--    </parent>-->

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <!--        <dependency>-->
        <!--            <groupId>org.springframework.boot</groupId>-->
        <!--            <artifactId>spring-boot-starter-websocket</artifactId>-->
        <!--        </dependency>-->
    </dependencies>

    <build>
        <plugins>
            <!-- java编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!-- 配置Tomcat插件 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8082</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

1.4.2.WebSocket的相关注解说明

  • @ServerEndpoint("/websoket"/{uid})
    • 声明这是一个websocket服务
    • 需要制定访问该服务的地址,在地址中可以指定参数,需要通过{}进行站位
  • @OnOpen
    • 用法:public void onopen(Session session,@PathParam(“uid”)String uid) throws IOException{}
    • 该方法将在建立连接后执行,会传入session对象,就是客户端与服务端建立的长连接通道
    • 通过@PathParam获取url申明中的参数
  • @OnClose
    • 用法:public void onClose(){}
    • 该方法是在连接关闭后执行
  • @OnMessage
    • 用法:public void onMessage(String message,Session session)throws IOException{}
    • 该方法用于接收客户端发来的消息
    • message:发来的消息数据
    • session:会话对象(也是通道)
  • 发送消息到客户端
    • 用法:session.getBasicRemote().sendText(“你好”);
    • 通过session进行发送

1.4.3.实现WebSocket服务

package org.fechin.websocket;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**
 * @Author:朱国庆
 * @Date:2020/2/16 12:28
 * @Desription: haoke-manage
 * @Version: 1.0
 */
@ServerEndpoint("/websocket/{uid}")
public class MyWebSocket {

    @OnOpen
    public void onOpen(Session session,@PathParam(value = "uid") String uid) throws IOException {
        System.out.println("WebSocket已经连接," + session);
        //给客户端响应,欢迎连接系统
        session.getBasicRemote().sendText(uid+",你好,欢迎登陆系统");
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("WebSocket已经关闭," + session);
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        System.out.println("收到客户端的消息:" + message);
        session.getBasicRemote().sendText("消息已经收到");
    }

    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

}

1.4.4.测试

我们可以安装Chrome插件,Simple Websocket Client
在这里插入图片描述

1.4.5.编写JS客户端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    const socket = new WebSocket("ws://localhost:8082/websocket/1");
    socket.onopen = (ws) => {
        console.log("建立连接", ws);
    };
    socket.onmessage = (ws) => {
        console.log("接收到消息 >> ", ws.data);
    };
    socket.onclose = (ws) => {
        console.log("连接已断开!", ws);
    };
    socket.onerror = (ws) => {
        console.log("发送错误!", ws);
    };

    // 2秒后向服务端发送消息
    setTimeout(() => {
        socket.send("发送一条消息试试");
    }, 2000);

    // 5秒后断开连接
    setTimeout(() => {
        socket.close();
    }, 5000);
</script>
</html>

访问页面进行测试

chrome的console显示:
在这里插入图片描述
后端console显示:
在这里插入图片描述

1.5.SpringBoot整合WebSocket

1.5.1.导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.fechin.websocket</groupId>
    <artifactId>demo-websoket</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <!--spring boot的支持-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

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

    <build>
        <plugins>
            <!-- java编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!-- 配置Tomcat插件 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8082</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

1.5.2.编写WebSocketHandler

package org.fechin.websocket.springboot;

import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

@Component
public class MyHandler extends TextWebSocketHandler {

    /**
     * 服务端接收到消息的时候
     * @param session
     * @param message
     * @throws IOException
     */
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message)
            throws IOException {
        System.out.println("获取到消息 >> " + message.getPayload());
        //人工智能代码!!!!!!!!(哈哈)
        String question = message.getPayload();
        question = question.replace("吗","");
        question = question.replace("我","我也");
        question = question.replace("?","!");
        question = question.replace("你","你才");
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        session.sendMessage(new TextMessage("回复:"+question));

    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws
            Exception {
        Integer uid = (Integer) session.getAttributes().get("uid");
        session.sendMessage(new TextMessage(uid+", 你好!欢迎连接到ws服务"));
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status)
            throws Exception {
        System.out.println("断开连接!");
    }
}

1.5.3.编写拦截器

package org.fechin.websocket.springboot;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.util.Map;

/**
 * 我们可以在建立连接之前写一些业务逻辑,比如校验登陆等(拦截器可写可不写)
 */
@Component
public class MyHandshakeInterceptor implements HandshakeInterceptor {

    /**
     * 握手之前,若返回false,则不建立链接
     *
     * @param request
     * @param response
     * @param wsHandler
     * @param attributes
     * @return
     * @throws Exception
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse
            response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws
            Exception {
        //将用户id放入socket处理器的会话(WebSocketSession)中
        //这样我们就可以在WebSocketHandle中通过'Integer uid = (Integer) session.getAttributes().get("uid");'来获取到uid.
        attributes.put("uid", 1001);
        System.out.println("开始握手。。。。。。。");
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse
            response, WebSocketHandler wsHandler, Exception exception) {
        System.out.println("握手成功啦。。。。。。");
    }
}

1.5.4.编写配置类

package org.fechin.websocket.springboot;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Autowired
    private MyHandler myHandler;

    @Autowired
    private MyHandshakeInterceptor myHandshakeInterceptor;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(this.myHandler, "/ws")
                //允许跨域
                .setAllowedOrigins("*")
                .addInterceptors(this.myHandshakeInterceptor);
    }
}

1.5.5.测试

我们需要再编写一个SpringBoot的启动类,启动服务。
在这里插入图片描述

WebSocket的代码是根据具体的情况而定的。在上述示例中,我们可以看到WebSocket连接的打开、消息接收、连接关闭和错误处理的代码。具体的WebSocket代码主要涉及以下几个方面: 1. 创建WebSocket连接: const socket = new WebSocket('ws://localhost:8080'); 这里的URL可以根据实际情况进行修改,确保与要连接的WebSocket服务器的地址和端口匹配。 2. 发送消息: 使用WebSocket连接的send()方法发送消息到服务器。 socket.send('Hello WebSocket!'); 3. 接收消息: 使用WebSocket连接的message事件监听器来接收来自服务器的消息。 socket.addEventListener('message', event => { console.log('接收到消息:', event.data); }); 4. 关闭连接: 使用WebSocket连接的close事件监听器来处理连接关闭的情况。 socket.addEventListener('close', event => { console.log('WebSocket连接已关闭:', event.code, event.reason); }); 5. 错误处理: 使用WebSocket连接的error事件监听器来处理WebSocket发生的错误。 socket.addEventListener('error', error => { console.error('WebSocket发生错误:', error); }); 这些是WebSocket的基本代码示例,可以根据实际需求进行修改和扩展。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [websocket总结和代码介绍](https://blog.csdn.net/weixin_39519297/article/details/130058154)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值