要利用WebSocket进行文件传输,我们需要讨论两种情况,分别是:发送方可以是客户端,和 发送方是服务端。

1、发送方是客户端 

1)服务端接收

$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
switch ($frame->opcode)
{
case 0x09:
$pongFrame = new Swoole\WebSocket\Frame;
$pongFrame->opcode = WEBSOCKET_OPCODE_PONG;
$server->push($frame->fd, $pongFrame);
echo "pone\n";
break;
case 0x08:
echo "Close frame received: Code {$frame->code} Reason {$frame->reason}\n";
break;
case 0x01:
echo "Text string\n";
break;
case 0x02:
echo "Binary data\n";
//服务端在这里接收,$frame->data即是客户端发过来的文件二进制数据
$server->push($frame->fd,$frame->data,WEBSOCKET_OPCODE_BINARY);
break;
default:
$server->push($frame->fd, $frame->data);
break;
}
});

2) 客户端(Javascript)发送

 form.on('submit(fileSend)',function(data){
var jqFile=$("#file"); try
{
var file=jqFile.get(0).files[0];
var filesize=file.size;
var reader=new FileReader();
//reader.readAsBinaryString(file);
//这里可以通过slice函数,对文件进行分割,多次传送
var blob=file.slice(0,filesize);
reader.readAsArrayBuffer(blob); reader.onload=function(e){
var arrBuf=e.target.result;
oWs.send(arrBuf);
};
}catch(e){
layer.msg("文件异常");
} return false;
});

到这里,有一点需要进行强调,利用slice对文件进行分割发送,多次send将文件内容多次传输到接收端,websocket协议会保证先发的先到达,后发的后达到,不会存在乱序问题。

2、发送方是服务端

1) 服务端发送

上面的例子已经提到,利用服务端的push可以将文件二进制数据推送到客户端。

$server->push($frame->fd,$frame->data,WEBSOCKET_OPCODE_BINARY);

2)客户端接收

这一部分,就有比较多的讨论内容。首先,服务端将文件数据以二进制的形式传递到客户端,客户端可以选择以blob或arraybuffer方式接收。

下面我们指定以arraybuffer方式接收:

oWs=new WebSocket(url);
oWs.binaryType="arraybuffer";

接下来,如果arraybuffer存储的是字符串数据,我们面临的就是要判断这些二进制数是是GBK还是UTF-8,并转成对应的string。

//传入arraybuffer,判断是否utf8
function IsTextUtf8(inputStream)
{
var byteArray=new Uint8Array(inputStream); var encodingBytesCount = 0;
var allTextsAreASCIIChars = true ; for ( var i = 0; i < byteArray.length; i++)
{
var current = byteArray[i]; if ((current & 0x80) == 0x80) allTextsAreASCIIChars = false ; if (encodingBytesCount == 0)
{
if ((current & 0x80) == 0) continue ; if ((current & 0xC0) == 0xC0)
{
encodingBytesCount = 1;
current <<= 2; while ((current & 0x80) == 0x80)
{
current <<= 1;
encodingBytesCount++;
}
}
else
{
// Invalid bits structure for UTF8 encoding rule.
return false ;
}
}
else
{
if ((current & 0xC0) == 0x80)
{
encodingBytesCount--;
}
else
{
return false ;
}
}
} if (encodingBytesCount != 0) return false ; return !allTextsAreASCIIChars;
}
//传入arraybuffer,判断是否GBK
function IsTextGbk(inputStream)
{
var byteArray=new Uint8Array(inputStream);
var nBytes = 0;//GBK可用1-2个字bai节编码,中文两个 ,英文一个
var chr = byteArray[0];
var bAllAscii = true; //如果全部都是ASCII,
for (var i = 0; i<byteArray.length; i++)
{
chr = byteArray[i];
if ((chr & 0x80) != 0 && nBytes == 0) // 判断是否ASCII编码,如果不是,说明有可能是GBK
{
bAllAscii = false;
}
if (nBytes == 0)
{
if (chr >= 0x80)
{
if (chr >= 0x81 && chr <= 0xFE)
{
nBytes = +2;
}
else
{
return false;
} nBytes--;
}
}
else
{
if (chr < 0x40 || chr>0xFE) return false;
nBytes--;
}//else end
} if (nBytes != 0) return false; if (bAllAscii) return true; return true;
}
/*
以对应字符集读出arraybuffer的内容并转为字符串
u:arraybuffer
f:回调函数,参数为string
encoding:可选gbk和utf-8
*/
function ab2str(u,f,encoding) {
var b = new Blob([u]);
var r = new FileReader();
r.readAsText(b, encoding);
r.onload = function (){if(f)f.call(null,r.result)}
}
oWs.onmessage=function(e){
var d;

if(typeof e.data=="object")
{
if(IsTextUtf8(e.data))
{
ab2str(e.data,function(str){
d="接收UTF-8:"+str;
},"utf-8");
return;
}
else if(IsTextGbk(e.data))
{
ab2str(e.data,function(str){
d="接收GBK:"+str;
},"gbk");
return;
}
else
{
var arr=new Uint8Array(e.data);
var str='';
for(var i=0;i<arr.length;i++)
{
str+=String.fromCharCode(arr[i]);
}
d="接收对象埂进制数据:"+str;
}
}
else d="接收文本数据:"+e.data; };

以上,就是关于文件传输的基本操作。我们可以设定自己的机制,连续传输图片数据,不断画到canvas上,造成小电影即视感;或者采用对传输的二进制数据进行base64编码方法进行传递。办法有很多,期待大家多多练习。本章到此结束。

完整的代码,大家可以看这里:传送门

---------------------------  我是可爱的分割线  ----------------------------

最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同学点击链接,联系我吧。

Swoole从入门到入土(19)——WebSocket服务器[文件传输]的更多相关文章

  1. Linux入门(五)linux服务器文件远程管理

     1 使用filezila远程管理linux服务器文件 filezila下载地址:https://filezilla-project.org/ filezila默认只能登录普通用户,如果想要root用 ...

  2. QT从入门到入土(三)——文件的读写操作

     引言 文件的读写是很多应用程序具有的功能,甚至某些应用程序就是围绕着某一种格式文件的处 理而开发的,所以文件读写是应用程序开发的一个基本功能. Qt 提供了两种读写纯文本文件的基本方法: 用 QFi ...

  3. Web服务器文件传输程序客户端程序实现

    1. 客户端程序--主函数 客户端主程序的流程图如下: 主程序主要是分析输入的命令,根据不同命令调用不同的函数处理或者进行出错处理,函数代码如下: #include "common.h&qu ...

  4. Swoole学习(五)Swoole之简单WebSocket服务器的创建

    环境:Centos6.4,PHP环境:PHP7 服务端代码 <?php //创建websocket服务器 $host = '0.0.0.0'; $port = ; $ws = new swool ...

  5. swoole创建websocket服务器

    目录 1 安装准备 1.1 安装swoole前必须保证系统已经安装了下列软件 1.2 下载并解压 1.3 编译安装成功后,修改php.ini 2 构建Swoole基本实例 2.1 tcp服务器实例 2 ...

  6. 04.swoole学习笔记--webSocket服务器

    <?php //创建webSocket服务器 $serv=); //获取请求 //on //open 建立连接 $serv:服务器 $request:客户端信息 $serv->on('op ...

  7. Erlang cowboy websocket 服务器

    Erlang cowboy websocket 服务器 原文见于: http://marcelog.github.io/articles/erlang_websocket_server_cowboy_ ...

  8. 用C语言实现websocket服务器

    Websocket Echo Server Demo 背景 嵌入式设备的应用开发大都依靠C语言来完成,我去研究如何用c语言实现websocket服务器也是为了在嵌入式设备中实现一个ip camera的 ...

  9. Hexo结合Stun静态博客搭建从入门到入土

    摘要 安装npm,安装hexo相关依赖,安装主题stun 修改hexo配置,修改stun配置,部署到github,gitee实现静态访问 给博客加上全局搜索,访问量统计 hexo博客编写模板 tips ...

  10. WebSocket服务器

    //创建websocket 服务器  ws_server.php //https://wiki.swoole.com/wiki/page/479.html //创建websocket服务器对象,监听0 ...

随机推荐

  1. Redis之入门概括与指令

    Redis特点(AP模型,优先保证可用,不会管数据丢失): 快的原因: 基于内存操作,操作不需要跟磁盘交互 k-v结构,类似与hashMap,所以查询速度非常快,接近O(1). 底层数据结构是有如:跳 ...

  2. [转帖](1.2)sql server for linux 开启代理服务(SQL AGENT),使用T-SQL新建作业

    https://www.cnblogs.com/gered/p/12518090.html 回到顶部 [1]启用SQL Server代理 sudo /opt/mssql/bin/mssql-conf ...

  3. [转帖]TiDB-unsafe recover(三台tikv宕机两台)

    一.背景 名称 数量 tikv 3 副本 3 1.故障: 因为某些原因,两台tikv不可连接,出现region不能访问的故障 2.几条理论: 2.1.多副本原则 存在一半以上的副本则集群访问不受影响( ...

  4. 【转帖】Ethernet 与 Infiniband的网络特性对比

    一.两者定位 以太网(Ethernet): 应用最广泛,是最成熟的网络互联技术,也是整个互联网络大厦的基石,兼容性非常好,可实现不同的系统之间的互连互通 IB(Infiniband): 领域很专,作为 ...

  5. [转帖]python库Paramiko

    https://zhuanlan.zhihu.com/p/456447145 测试过程中经常会遇到需要将本地的文件上传到远程服务器上,或者需要将服务器上的文件拉到本地进行操作,以前安静经常会用到xft ...

  6. 袋鼠云数栈产品中 AI+ 实现原理剖析

    生产力工具 + AI 是不可逆转的趋势,慢慢的大模型能力通过 AI Agent 落地的工程化能力也开始趋于成熟.作为大数据产品的数栈也必然是需要借助 AI 能力提升产品竞争力. 去年 12 月,我们在 ...

  7. ElasticSearch必知必会-基础篇

    商业发展与职能技术部-体验保障研发组 康睿 姚再毅 李振 刘斌 王北永 说明:以下全部均基于eslaticsearch 8.1 版本 一.索引的定义 官网文档地址:https://www.elasti ...

  8. 震惊p div 标签 可以编辑高度随内容的编辑而发生变化

    震惊p标签可以编辑高度随内容的编辑而发生变化### 1==>只可编辑,粘贴复制字段长度不正常 <p contenteditable="true" >这是一个可编辑 ...

  9. linux root用户密码输入正确还是提示access denied

    问题:之前用远程工具连接一直都是好的,第二天上班找开远程工具要输root的密码了,输入用户密码后还是无效,可以确定用户密码是对的,其中有一个远程工具一直是连着的就没有问题. 排查问题: 1.相接用pa ...

  10. 菜鸟教程-所有软件教学都有【python、java、c、c++、html、sql、css、jquery、bootstrap、vue、c#、go】

    软件教学[python.java.c.c++.html.sql.css.jquery.bootstrap.vue.c#.go] 首页 https://www.runoob.com/  资料很全 1.p ...