IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> WebSocket一懂(01) -> 正文阅读

[网络协议]WebSocket一懂(01)

WebSocket使用场景介绍

实现两个系统之间的数据交互,A系统中的echarts图需要在B系统的固定位置进行展示,用到了WebSocket,A系统点击发送按钮,会把echarts图的数据传输给B系统,B系统获取到数据,进行echarts展示 这里为什么没有使用socket:原因是:传统的socket,是一个长连接,客户端连接服务端,如果客户端和服务端都没有发送数据,就会造成资源浪费。 使用了WebSocket,WebSocket他是一种长连接,通过一次请求来初始化连接,然后所有的请求和响应都是通过这个TCP连接进行通讯,它是一种基于事件驱动,异步的消息机制。原理和TCP一样,只需要一个握手动作,就可以形成一条快速通道。

什么是WebSocket?

WebSocket是一种在单个TCP(传输控制协议:是面向连接的、可靠的、基于字节流之间的传输层通信协议)连接上进行全双工通信的协议。

全双工和单工的区别:
全双工:可在信号载波的两个方向同时传输
单工:一方固定为发送端,一方固定为接收端,信息只能从一条传输线朝一个方向传播

WebSocket通信的客户端是浏览器,客户端操作的API是HTML5新增的API,使用这些API可以让客户端(浏览器)和服务端(服务器)进行全双工通讯。

WebSocket图解:

在这里插入图片描述

客户端代码

<!DOCTYPE HTML>
<html>
<head>
    <title>My WebSocket</title>
</head>

<body>
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</body>

<script type="text/javascript">
    var websocket = null;

    //判断当前浏览器是否支持WebSocket, 主要此处要更换为自己的地址
    if ('WebSocket' in window) {
        //创建websocket实例
        websocket = new WebSocket("ws://localhost:8080/websocketss");
    } else {
        alert('Not support websocket')
    }

    //连接成功自动建立的回调方法
    websocket.onopen = function(event) {
        //setMessageInnerHTML("open");
    }


    //连接发生错误的回调方法
    websocket.onerror = function() {
        setMessageInnerHTML("error");
    };



    //接收到消息的回调方法 监听消息onmessage事件提供了一个data属性,它包含消息的body部分
    websocket.onmessage = function(event) {
        setMessageInnerHTML("前端展示" + event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function() {
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function() {
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket() {
        websocket.close();
    }

    //发送消息
    function send() {
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

客户端代码图解

在这里插入图片描述

服务端代码

首先是WebSocket配置类:

@Configuration
public class WebSocketConfig {

    /**
     * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
package com.hjjc.common.utils;

import com.alibaba.fastjson.JSON;
import com.hjjc.information.domain.MyMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 前后端交互的类实现消息的接收推送(自己发送给另一个人)
 *
 * @ServerEndpoint(value = "/websocketss") 前端通过此URI 和后端交互,建立连接
 */
@Slf4j
@ServerEndpoint(value ="/websocketss")
@Component
//@Scope("prototype")
public class MyWebSocket {

    /** 记录当前在线连接数 */
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    /** 存放所有在线的客户端 */
    private static Map<String, Session> clients = new ConcurrentHashMap<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        onlineCount.incrementAndGet(); // 在线数加1
        clients.put(session.getId(), session);
        //log.info("有新连接加入:{},当前在线人数为:{}", session.getId(), onlineCount.get());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        onlineCount.decrementAndGet(); // 在线数减1
        clients.remove(session.getId());
//        log.info("有一连接关闭:{},当前在线人数为:{}", session.getId(), onlineCount.get());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     *            客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
//        log.info("服务端收到客户端[{}]的消息[{}]", session.getId(), message);
        try {
            Model myMessage = JSON.parseObject(message, Model.class);
            if (myMessage != null) {
                //写遍历clients
                for (Map.Entry<String, Session> entry:clients.entrySet( )){
                    if (entry.getValue() != null) {
                        this.sendMessage(message, entry.getValue());
                    }
                }
            }
        } catch (Exception e) {
            //log.error("解析失败:{}", e);
        }
    }
    /**
     * 服务端发送消息给客户端
     */
    private void sendMessage(String message, Session toSession) {
        try {
//            log.info("服务端给客户端[{}]发送消息[{}]", toSession.getId(), message);
            toSession.getBasicRemote().sendText(message);
        } catch (Exception e) {
//           log.error("服务端发送消息给客户端失败:{}", e);
        }
    }

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

    

}
package com.hjjc.information.domain;

import lombok.Data;

@Data
public class MyMessage {

    /**
     * 用户标识符
     */
    private String userId;

    /**
     * 消息
     */
    private String message;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

服务端发送给客户端数据实例:

@RequestMapping("/send")
public void send10(String sendData){
    Map maps = (Map) JSON.parse(sendData);
    maps.put("type","pie");
    String sendData10F = JSONObject.toJSONString(maps);
    MyWebSocket.onMessage(sendData10F,null);
}

客户端这边接收到的数据是json类型,使用到echarts上需要先转为map类型,然后获取map中的数据,进行填充echarts

websocket.onmessage = function(event) {
            /*setMessageInnerHTML("SHOW------------" + event.data);*/
            objToStrMap(JSON.parse(event.data));
        }
        function objToStrMap(obj){
            let strMap = new Map();
            for (let k of Object.keys(obj)) {
                strMap.set(k,obj[k]);
            }
            let type = strMap.get("type");
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:44:23  更:2021-10-18 17:45:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年9日历 -2024/9/21 9:17:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码