WebSocket在线通信

一.为什么要有WebSocket

servlet,tomcat底层核心思路都是Socket

HTML页面在刚刚开始出现的时候是静态的,不能够进行交互,后来有了JavaScript,在一
定程度上解决了这个问题,但是JavaScript刚出现的时候并不能和服务端进行交互,直到Ajax的出现。
Ajax有效的解决了页面和服务端进行交互的问题,不过Ajax有一个问题,就是所有的请求都必须由客户
端发起,服务端进行响应,如果服务端有最新的消息,难以即时的发送到客户端去,在WebSocket技术
出现之前,为了让客户端能够即时的获取服务端的数据,一般采用如下三种方案

1.1 轮询

最简单的一种解决方案, 就是客户端在固定的时间间隔下(一般是1秒)不停的向服务器端发送请求,查看服务端是否有最新的数据,服务端如果有最新的数据则返回给客户端,服务端如果没有则返回一个空的json或者xml文档,这种方式的实现起来简单,但是弊端也很明显,就是会有大量的无效请求,服务端的资源被大大的浪费了

1.2 长轮询

长连接有点类似于轮询,不同的是服务端不是每次都会响应客户端的请求,只有在服务端有最新数据的时候才会响应客户端的请求,这种方式很明显会节省网络资源和服务端资源,但是也存在一些问题,比如:

1.如果浏览器在服务器响应之前有新数据要发送就只能创建一个新的并发请求,或者先尝试断掉当前请求然后再创建新的请求。
2.TCP和HTTP规范中都有连接超时一说,所以所谓的长连接并不能一直持续,服务端和客户端的连接需要定期的连接和关闭再连接,当然也有一些技术能够延长每次连接的时间,这是题外话。

1.3Applet和Flash

Applet和Flash都已经是明日黄花了,不过这两个技术在当年除了以让我们的HTML页面更加绚丽之外,还可以解决消息推送问题Ajax这种技术去实现全双工通信已经陷入困境的时候,开发者图Apple和Flash来模拟全双工通信,开发者可以创建一个只有像素点大的普通透明的Applet或者Flash,然后将之内嵌在页中, 然后这Apple或者Flash中的代码创建出一个Socket连接种连接方式消除了HTT协议中的各种限制,当服务器有消息发到客户端的时候,开发者以在Applet或者Flash中调用JavaScript函数,并将服务器传来的消传递给JavaScript函数,然后更新页面,当浏览器有数据要发送给务器的时候,也一样,通过Applet或者Flash来传递。这种方式真正实现了全双工通信,不过也有问题,如下:

1.浏览器必须能够运行Java或者Flash
2.无论是Applet还是Flash都存在安全问题
3.随着HTML5在标准在浏览器中广泛支持,Flash下架已经被提上日程

1.4WebSocket的特点

在这里插入图片描述

所有的HTTP客户端(浏览器、移动端等)都可以在请求头中包Connection:Upgrade,这个表示客户端希望升级请求协议,那么希望升级成什么样的协议呢?我们需要在Upgrade头中指定一个或多个协议的列表,当然这些协议必须兼容HTTP/1.1协议。服务器收到请求之后,如果接受升级请求,那么将会返回一个101的状态码表示转换请求协议,同时在响应的Upgrade头中使用单个值,这个个值就是请求协议列表中服务器支持的第一个协议(即请求头Upgrade字段中列出来的协议列表中服务器支持的第一个协议)。HTTP升级最大的好处是最终使我们可以使用任意的协议,在升握手完成之后,它就不再使用HTTP连接了,我们甚至可以在升级握手完成之后建立一个Socket连接,理论上我们可以使用HTTP升在两个端点之间使用任何自己设计的协议,进而创建出各种各样TCP通信,当然浏览器不会让开发者随意去这么做,而是要指定某些协议,WebSocket应运而生!

1.5 WebSocket的用途

说了这么多那么WebSocket协议到底可以用在哪些地方呢?事实上,WebSocket协议的用途几乎是没有限制的,比如

1.网页上的在线聊天
2.多人在线游戏
3.在线股票网站
4.在线即时新闻网站
5.高清视频流
6.应用集群之间的通信
7.远程系统/软件的状态和性能的实时监控

五子棋小游戏
在线聊天

1.6 WebSocket的优势

1.由于WebSocket连接在端口80(ws)或者443(wss)上创建,HTTP使用的端口相同,这样,基本上所有的防火墙都不会阻塞WebSocket连接
2.WebSocket使用HTTP协议进行握手,因此它可以自然而然的成到网络浏览器和HTTP服务器中
3.心跳消息(ping和pong)将被反复的发送,进而保持WebSocket连接几乎一直处于活跃状态。一般来说是这样,一个节点周期性的一个小数据包到另外一个节点(ping),而另一个节点则使用了包含相同数据的数据包作为应(pong),这样两个节点都将处于连接状态
4.使用该协议,当消息启动或者到达的时候,服务端和客户端都以知道
5.WebSocket连接关闭时将发送一个特殊的关闭消息
6.WebSocket支持跨域,可以避免Ajax的限制
7.HTTP规范要求浏览器将并发连接数限制为每个主机名两个接是当我们使用WebSocket的时候,当握手完成之后该限制就不在了因为此时的连接已经不再是HTTP连接了

二. WebSocket的实际案例

2.1 加入依赖

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

2.2实体类

package com.huang.vhr.framework.web.entity;

public class Chat {
    private String from;
    private String to;
    private String msg;

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

2.3 配置类WebSocketConfig

package com.huang.vhr.framework.comments.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
//开启消息代理
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    /**
     * 配置 websocket 连接地址
     * @param registry
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/myws/ep")
                //设置允许的域
                .setAllowedOrigins("http://localhost:8080")
                //支持前端使用 SockJS
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/queue");
    }
}

2.4controller层调用底层方法

package com.huang.vhr.controller.system.basic;


import com.huang.vhr.framework.web.entity.Chat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

import java.security.Principal;

@Controller
public class ChatController {

    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;

    /**
     *
     * @param chat
     * @param principal 这个就是当前登录用户对象
     */
    @MessageMapping("/myws/chat")
    public void chat(Chat chat, Principal principal) {
        chat.setFrom(principal.getName());
        //发送一条消息
        simpMessagingTemplate.convertAndSendToUser(chat.getTo(), "/queue/chat", chat);
    }
}

2.5 前端–vue

不会前端。。
留着先吧

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebSocket是一种在客户端和服务器之间实现双向通信的网络协议。它通过在客户端和服务器之间建立持久连接,允许双方实时地发送消息和数据。 与传统的HTTP协议相比,WebSocket协议具有以下特点: 1. 双向通信WebSocket允许客户端和服务器之间进行实时的双向通信,而不需要客户端发起请求,服务器返回响应的模式。 2. 低延迟:WebSocket建立的连接是持久的,可以在连接保持的时间内随时发送消息,减少了每次请求的开销,从而降低了通信的延迟。 3. 较小的数据传输量:由于WebSocket建立的连接是持久的,只需要在连接建立时进行一次握手,之后的通信只需要发送少量的控制数据和实际的数据,减少了额外的数据传输量。 4. 跨域支持:WebSocket支持跨域通信,可以在不同域名或端口之间进行通信。 5. 适应性强:WebSocket协议可以与HTTP协议共享同一端口,可以通过HTTP代理或反向代理进行部署。 在使用WebSocket进行双向通信时,客户端和服务器需要通过WebSocket API进行交互。客户端可以使用JavaScript中的WebSocket对象进行连接和消息发送,而服务器端需要实现WebSocket协议的处理逻辑来接收和处理客户端发送的消息。 总的来说,WebSocket提供了一种高效、实时的双向通信方式,适用于需要实时数据传输和实时交互的应用场景,如实时聊天、实时数据监控等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值