精华内容
下载资源
问答
  • 前端用 Blob 分割文件,定义好每一段数据的大小,首先要把文件信息,包括文件名、文件大小、校验值、分段大小等信息发给服务器。然后是执行每一段的发送任务,可异步(有待研究,是开多个ws连接还是?????)也可同步...

    阅读原文

    简介

    前端用 Blob 分割文件,定义好每一段数据的大小,首先要把文件信息,包括文件名、文件大小、校验值、分段大小等信息发给服务器。然后是执行每一段的发送任务,可异步(有待研究,是开多个ws连接还是?🤔)也可同步(服务端最好要有回应事件),异步的话需要注意文件段的顺序,最好的话同步异步都用自己定义个格式帧去传输,方便校验。这里是简单版的,直接发送,没有校验! 还有,分段下载也是一样的操作~

    前端

    前端用的是 ant-design-vue upload组件customRequest自定义上传。

    <a-upload
                          name="file"
                          :file-list="fileList"
                          :customRequest="customRequest"
                          @change="handleChange"
                      >
                        <a-button>
                          <a-icon type="upload"/>
                          Click to Upload
                        </a-button>
                      </a-upload>
    

    methods

    customRequest (options) {
          const blob = options.file
          // 每个文件切片大小
          const bytesPerPiece = 40960
    
          let start = 0
          let end
          while (start < blob.size) {
            end = start + bytesPerPiece
            if (end > blob.size) {
              end = blob.size
            }
            // 切割文件
            const chunk = blob.slice(start, end)
            // 发送数据到服务器
            this.$global.ws.send(chunk)
            start = end
          }
          // 表示发送完毕
          this.$global.ws.send(new Blob(['end'], {type: 'text/plain'}))
    
          // 表示已经上传成功 ...
          const reader = new FileReader()
          reader.readAsDataURL(options.file)
          reader.onload = () => {
            options.onSuccess()
          }
        }
    

    效果

    前端发送数据

    在这里插入图片描述

    后台接收数据

    在这里插入图片描述
    后台代码

    package com.xxx.sdk.server;
    
    import com.xxx.sdk.protocol.r2000.upgrade.ReadFile;
    import com.xxx.sdk.util.AsciiUtil;
    import io.netty.buffer.ByteBuf;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
    
    import java.io.ByteArrayInputStream;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * @author Rubin
     * @version v1 2020/12/11 14:19
     */
    public class WsUploadFileHandler extends SimpleChannelInboundHandler<BinaryWebSocketFrame> {
    
        /**
         * 分段数据
         */
        List segmentedData = new ArrayList<>();
    
        /**
         * 文件总字节数
         */
        AtomicInteger fileLength = new AtomicInteger(0);
    
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, BinaryWebSocketFrame msg) {
            ByteBuf content = msg.content();
            int readableBytes = content.readableBytes();
    
            byte[] bytes = new byte[readableBytes];
            content.getBytes(0, bytes);
    
            if (readableBytes == 3) {
                // 文件传输完毕
                if ("end".equals(AsciiUtil.hex2AsciiStr(bytes))) {
    
                    // 拼接分段的数据
                    byte[] file = new byte[fileLength.get()];
                    // 拷贝下标
                    AtomicInteger fileIndex = new AtomicInteger();
                    segmentedData.forEach(fbs -> {
                        int length = ((byte[]) fbs).length;
                        System.arraycopy(fbs, 0, file, fileIndex.get(), length);
                        fileIndex.addAndGet(length);
                    });
                    // 读取完整文件
                    ReadFile.read(new ByteArrayInputStream(file));
                }
    
            } else {
                segmentedData.add(bytes);
                fileLength.addAndGet(bytes.length);
            }
        }
    }
    
    

    楼主的是单机本地程序,所以是理想环境,校验啥的都没有,网络应用的话数据完整性校验可不能少!

    大文件的话还可以做个进度条啥的,哈哈哈😄

    展开全文
  • websocket服务端如何分段发送文件给客户端,网上大部分都是客户端分段发送给服务端
  • 最近项目中开发Java websocket...二进制数据,直接异常 c++使用的是输入流将文件数据获取到,分段发送到服务端,服务端接收就直接抱内部处理非连续帧异常。 不知道该怎么处理,按照一次性发也行。 请问大佬怎么解决?
  • 分块WebSocket传输

    2020-12-24 13:51:49
    小编典典首先,您需要在 浏览器中 区分WebSocket 协议 和WebSocket API 。 __WebSocket协议的帧大小限制为2 ^ 63个八位位组,但是WebSocket消息可以由无限数量的帧组成。浏览器中的WebSocketAPI不会公开基于框架的...

    小编典典

    首先,您需要在 浏览器中 区分WebSocket 协议 和WebSocket API 。 __

    WebSocket协议的帧大小限制为2 ^ 63个八位位组,但是WebSocket消息可以由无限数量的帧组成。

    浏览器中的WebSocket

    API不会公开基于框架的API或流式API,而只会公开基于消息的API。传入消息的有效负载始终会被完全缓冲(在浏览器的WebSocket实现中),然后再将其提供给JavaScript。

    披露:我是高速公路的原始作者,并且为Tavendo工作。

    更多注意事项:

    只要浏览器JS WebSocket API中没有框架/流API,您就只能接收/发送完整的WS消息。

    单个(普通)WebSocket连接无法交错多个消息的有效负载。因此,例如,如果您使用大消息,则这些消息将按顺序传递,并且当大消息仍在运行时,您将无法在两次消息之间发送小消息。

    WebSocket即将推出(扩展是扩展协议的内置机制):WebSocket复用。这允许在单个基础TCP连接上具有多个(逻辑)WebSocket连接,这具有多个优点。

    另请注意:您可以从一个单一的JS / HTML页面打开多个WS连接(在不同的底层技术合作计划),以一台目标服务器 今天 。

    另请注意:您可以在应用程序层中“分块”:以较小的WS消息发送您的内容,然后重新组装。

    我同意,在理想的世界中,您将在浏览器中使用消息/框架/流API以及WebSocket复用。这将提供所有的功能和便利。

    2020-07-07

    展开全文
  • 浏览器麦克风实时录制音频流数据,通过webscoket传输至后台,根据实际业务进行开发
  • php结合websocket是心啊文件的片段上传,并且附带进度条功能,欢迎下载
  • 一、单文件上传实例 ... div class="container"> div class="panel panel-default"> div class="panel-heading">分段读取文件:div> div class="panel-body"> input type="file" id="file

    一、单文件上传实例

    HTML:

    复制代码
    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">分段读取文件:</div>
            <div class="panel-body">
                <input type="file" id="file" /><br />
                <input type="button" value="中止" onclick="stop();" />&empty;
                <input type="button" value="继续" onclick="containue();" />
                <progress id="progressOne" style="width:400px;" max="100" value="0"></progress>
                <blockquote id="Status" style="word-break:break-all;"></blockquote>
            </div>
        </div>
    </div>
    复制代码

    JS:

    复制代码
    /*
        * 测试WebSocket上传
        * 本地浏览器上传速度测试单个文件,上传速度IE>FF>Google(Google浏览器慢相当多)
        */
    var fileBox = document.getElementById('file');
    var reader = null;  //读取操作对象
    var step = 1024 * 256;  //每次读取文件大小 ,字节数
    var cuLoaded = 0; //当前已经读取总数
    var file = null; //当前读取的文件对象
    var enableRead = true;//标识是否可以读取文件
    var total = 0;        //记录当前文件总字节数
    var startTime = null; //标识开始上传时间
    fileBox.onchange = function () {
        //获取文件对象
        file = this.files[0];
        total = file.size;
        console.info("文件大小:" + file.size);
        if (ws == null) {
            if (window.confirm('建立与服务器链接失败,确定重试链接吗')) {
                createSocket(function () {
                    bindReader();
                });
            }
            return;
        }
        bindReader();
    }
    //绑定reader
    function bindReader() {
        cuLoaded = 0;
        startTime = new Date();
        enableRead = true;
        reader = new FileReader();
        //读取一段成功
        reader.onload = function (e) {
            console.info('读取总数:' + e.loaded);
            if (enableRead == false)
                return false;
            //根据当前缓冲区来控制客户端读取速度
            if (ws.bufferedAmount > step * 10) {
                setTimeout(function () {
                    //继续读取
                    console.log('--------------》进入等待');
                    loadSuccess(e.loaded);
                }, 3);
            } else {
                //继续读取
                loadSuccess(e.loaded);
            }
        }
        //开始读取
        readBlob();
    }
    //读取文件成功处理
    function loadSuccess(loaded) {
        //将分段数据上传到服务器
        var blob = reader.result;
        //使用WebSocket 服务器发送数据
        if (cuLoaded == 0) //发送文件名
            ws.send(file.name);
        ws.send(blob);
        //如果没有读完,继续
        cuLoaded += loaded;
        if (cuLoaded < total) {
            readBlob();
        } else {
            console.log('总共上传:' + cuLoaded + ',总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);
        }
        //显示结果进度
        var percent = (cuLoaded / total) * 100;
        document.getElementById('Status').innerText = percent;
        document.getElementById('progressOne').value = percent;
    }
    //指定开始位置,分块读取文件
    function readBlob() {
        //指定开始位置和结束位置读取文件
        var blob = file.slice(cuLoaded, cuLoaded + step);
        reader.readAsArrayBuffer(blob);
    }
    //中止
    function stop() {
        //中止读取操作
        console.info('中止,cuLoaded:' + cuLoaded);
        enableRead = false;
        reader.abort();
    }
    //继续
    function containue() {
        console.info('继续,cuLoaded:' + cuLoaded);
        enableRead = true;
        readBlob();
    }
    var ws = null;
    //创建和服务器的WebSocket 链接
    function createSocket(onSuccess) {
        var url = 'ws://localhost:55373/ashx/upload3.ashx';
        ws = new WebSocket(url);
        ws.onopen = function () {
            console.log('connected成功');
            if (onSuccess)
                onSuccess();
        }
        ws.onmessage = function (e) {
            var data = e.data;
            if (isNaN(data) == false) {
                //console.log('当前上传成功:' + data);
            } else {
                console.info(data);
            }
        }
        ws.onclose = function (e) {
            //中止客户端读取
            stop();
            console.log('链接断开');
        }
        ws.onerror = function (e) {
            //中止客户端读取
            stop();
            console.info(e);
            console.log('传输中发生异常');
        }
    }
    //页面加载完建立链接
    createSocket();
    复制代码
    服务器后台处理:
    复制代码
        public void ProcessRequest(HttpContext context)
        {
            //处理WebSocket 请求
            context.AcceptWebSocketRequest(DoWork);
        }
        /// <summary>
        /// 委托处理函数定义
        /// </summary>
        /// <param name="context">当前WebSocket上下文</param>
        /// <returns></returns>
        public async Task DoWork(AspNetWebSocketContext context)
        {
            //1.获取当前WebSocket 对象
            WebSocket socket = context.WebSocket;
            string filename = "";
            //2.监视相应
            while (true)
            {
                /*
                    * 此处缓存数组指定读取客户端数据的长度
                    * 如果客户端发送数据超过当前缓存区,则会读取多次
                    */
                ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024 * 256]);
                //接收客户端信息
                CancellationToken token;
                WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, token);
                if (socket.State == WebSocketState.Open)
                {
                    //判断是否已经到了最后
                    int curLength = Math.Min(buffer.Array.Length, result.Count);
                    //判断用户传入的类型进行处理
                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        string msg = Encoding.UTF8.GetString(buffer.Array, 0, curLength);
                        filename = msg;
                        buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes("接收文件名成功:" + filename));
                        await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                    }
                    else if (result.MessageType == WebSocketMessageType.Binary)
                    {
                        //创建并保存文件,如果上传成功,返回当前接收到的文件大小
                        string msg = SaveFile(filename, buffer, curLength);
                        buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(curLength.ToString()));
                        await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                    }
                }
                else { break; }
            }
        }
        /// <summary>
        /// 追加二进制数据到文件
        /// </summary>
        public string SaveFile(string file, ArraySegment<byte> buffer, int Length)
        {
            //去除文件名中的前后空格
            file = file.Trim();
            string fullname = @"F:\JavaScript_Solution\H5Solition\UploadWebForm\content\" + file;
            try
            {
                FileStream fs = new FileStream(fullname, FileMode.Append, FileAccess.Write);
                try
                {
                    byte[] result = buffer.ToArray();
                    fs.Write(result, 0, Length);
                }
                finally
                {
                    fs.Close();
                }
                return "保存文件成功";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
    复制代码
    展开全文
  • 在上篇文章中,我们了解了WebSocket的基本功能及相关概念。本篇文章中我们以具体的实例来演示,在Spring Boot中整合WebSocket,同时实现一个场景的业务场景功能。 针对在Spring Boot中使用合WebSocket通常有两种形式...

    在上篇文章中,我们了解了WebSocket的基本功能及相关概念。本篇文章中我们以具体的实例来演示,在Spring Boot中整合WebSocket,同时实现一个场景的业务场景功能。

    针对在Spring Boot中使用合WebSocket通常有两种形式:直接基于WebSocket协议进行集成和基于STOMP协议进行集成。本篇文章我们基于WebSocket协议来完成相应功能。

    业务场景

    实例的基本业务场景如下:

    在某官方网站上,提供用户匿名在线技术交流功能。用户点击网页,即可为用户生成一个匿名,用户可以看到当前在线人的昵称信息,随后可以在群里发送消息进行交流。

    Spring Boot集成WebSocket

    引入依赖文件:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifa
    展开全文
  • 包含了spingBoot服务器代码以及android客户端,客户端基于Websocket协议以及Okhttp框架实现的语音是半吊子的Kotlin,支持文字语音图片发送,
  • package main import ( "fmt" "golang.org/x/net/websocket" "log" "net/http" "os" "time" ) var ( dirPath string test byte lenFile int ) func check(e error) { if e != n...
  • JS实时麦克风录音并通过WebSocket将pcm传到后台并处理 文章目录JS实时麦克风录音并通过WebSocket将pcm传到后台并处理前端后端websoket接收主要思路 前端 <html> <head> <meta charset="UTF-8"> ...
  • jmeter应用WebDriver Sampler验证大文件分片上传 文章目录jmeter应用WebDriver Sampler验证大文件分片上传一、背景二、插件安装三、WebDriver Sampler应用1.添加WebDriver Sampler取样器:2.添加并配置Chrome Driver...
  • 该库目前处于实验状态,但提供普通和安全 WebSocket 的功能、支持分段的消息级 API、数据帧级 API 以及扩展和自定义行为的能力。安装要将crates.io 中的库发布版本添加到 Cargo 项目,请将其添加到 Cargo.toml 的...
  • 将设备接入的系统中只能通过webSocket 。 在对接人员批量上传的时候由于人像是base64字符串类型,所以上传人员的时候数据包有100多kb 。通过websocket 向设备下发时,每次都失败。考虑到是不是数据包的问题,经过...
  • 然后借助websocket发开发送,然后在客户端(注意不是服务端)将文件合并。有人说websocket可以直接发,但是他的大小受到限制,比如发200M的东西,就会出问题。而我的方案就不会存在问题.最主要的是在发送文件的同时...
  • 支持未分段分段的二进制和文本框架。 基于回调,易于使用且延迟低。 该模块自动组合片段帧,默认情况下处于启用状态,可以在应用程序需要自行处理片段的情况下将其关闭。 内置处理控制帧(ping,断开连接)。 ...
  • WebSocket协议

    2021-08-31 16:31:14
    WebSocket是一种独立的基于TCP协议的协议,它是一种全双工的通信协议,可以在支持websocket的机器之间进行双向通信。设计的目的便是为了弥补http协议的不足之处。http是严格的单向协议,任何服务器的数据传送都需要...
  • Netty案例介绍(websocket服务)

    千次阅读 2019-12-30 23:13:04
      本文我们来实现一个基于WebSocket协议的案例。 WebSocket案例 1.需求分析   Http协议是无状态的, 浏览器和服务器间的请求响应一次,下一次会重新创建连接.所有在有些情况下并不是太适用。这时websocket就是...
  • 依赖webSocket、mybatis的演示项目,其中有账号登录模块、数据处理模块(增删改查),json格式数据交互,数据分段发送处理,dao层使用mybatis框架。
  • WebSocket作为一种解决web应用双向通信的协议由HTML5规范引出,是一种建立在TCP协议基础上的全双工通信的协议。它是一个应用层协议,它出现是为了解决HTTP的痛点,希望在服务器与浏览器之间建立一条不受限制的双向...
  • (1)HTML5 WebSocket、异常重连、心跳检测; (2)SockJS、Stomp、RabbitMQ Stomp消息代理; (3)分别用Nginx和Spring Cloud Gateway实现多实例... (6)Websocket拦截器结合 Spring security、jwt token认证授权。
  • 一、WebSocket 原理 关于控件的源码下载见《Delphi 的Websocket Server 控件实现(四、WebSocket Demo程序使用说明)》 WebSocket 标准使用 UTF8编码通信,切记! 关于WebSocket 的原理,主要是RFC 6455标准,该...
  • } } 请求处理 @ServerEndpoint(value = "/ws/{key}", decoders = {ObjectDecoder.class} , encoders = {ObjectEncoder.class}) @Component public class WebSocketServer { private static Logger log = ...
  • protoo.WebSocket

    2021-10-17 11:12:05
    目录protoo.WebSocketprotoo消息protoo requestprotoo responseprotoo ...protoo.WebSocket protoo是用于多方实时通信应用程序的极简且可扩展的 Node.js 信号框架。它提供了服务器端 Node.js 模块和客户端
  • 文件上传的步骤: 打开websocket--连接websocket服务器--在浏览器里选择文件--将文件读入到内存中(以arraybuffer的形式)--在socket里发送文件--完毕!服务器端:先配置好websocket的服务器, 这里用一个java的开源...
  • Sec-WebSocket-Extensions:permessage-deflate Sec-WebSocket-Accept:q9g5u1WfIWaAjNgMmjlTQTqkS/k= 将Sec-WebSocket-Key的值进行一定的运算和该值进行比较来判断是否是目标服务器响应了WebSocket请求。...
  • websocket与socket.io比较与分析

    千次阅读 2020-04-07 20:30:01
    大家参与的项目里多少都会有web server与browser需要长连接互联的场景,当然我也是,之前没有进行太多方案的调研(比如深入理解通信协议和通用的一些解决方案),所以websocket就不假思索地直接用了,包括去年写的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,057
精华内容 822
关键字:

websocket分段