Swoole从入门到入土(19)——WebSocket服务器[文件传输]
要利用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服务器[文件传输]的更多相关文章
- Linux入门(五)linux服务器文件远程管理
1 使用filezila远程管理linux服务器文件 filezila下载地址:https://filezilla-project.org/ filezila默认只能登录普通用户,如果想要root用 ...
- QT从入门到入土(三)——文件的读写操作
引言 文件的读写是很多应用程序具有的功能,甚至某些应用程序就是围绕着某一种格式文件的处 理而开发的,所以文件读写是应用程序开发的一个基本功能. Qt 提供了两种读写纯文本文件的基本方法: 用 QFi ...
- Web服务器文件传输程序客户端程序实现
1. 客户端程序--主函数 客户端主程序的流程图如下: 主程序主要是分析输入的命令,根据不同命令调用不同的函数处理或者进行出错处理,函数代码如下: #include "common.h&qu ...
- Swoole学习(五)Swoole之简单WebSocket服务器的创建
环境:Centos6.4,PHP环境:PHP7 服务端代码 <?php //创建websocket服务器 $host = '0.0.0.0'; $port = ; $ws = new swool ...
- swoole创建websocket服务器
目录 1 安装准备 1.1 安装swoole前必须保证系统已经安装了下列软件 1.2 下载并解压 1.3 编译安装成功后,修改php.ini 2 构建Swoole基本实例 2.1 tcp服务器实例 2 ...
- 04.swoole学习笔记--webSocket服务器
<?php //创建webSocket服务器 $serv=); //获取请求 //on //open 建立连接 $serv:服务器 $request:客户端信息 $serv->on('op ...
- Erlang cowboy websocket 服务器
Erlang cowboy websocket 服务器 原文见于: http://marcelog.github.io/articles/erlang_websocket_server_cowboy_ ...
- 用C语言实现websocket服务器
Websocket Echo Server Demo 背景 嵌入式设备的应用开发大都依靠C语言来完成,我去研究如何用c语言实现websocket服务器也是为了在嵌入式设备中实现一个ip camera的 ...
- Hexo结合Stun静态博客搭建从入门到入土
摘要 安装npm,安装hexo相关依赖,安装主题stun 修改hexo配置,修改stun配置,部署到github,gitee实现静态访问 给博客加上全局搜索,访问量统计 hexo博客编写模板 tips ...
- WebSocket服务器
//创建websocket 服务器 ws_server.php //https://wiki.swoole.com/wiki/page/479.html //创建websocket服务器对象,监听0 ...
随机推荐
- http-长连接
1. 短链接 http1.0 -- 1个请求-响应过程会创建且1个新的连接 2. 长连接 http1.1 -- 同域下可以创建1个tcp连接,多个请求在同一个tcp上串行处理请求 http2.0 -- ...
- [转帖]NUMA导致的Oracle性能问题
https://www.cnblogs.com/realcp1018/p/6903721.html 背景简介: Oracle版本:11.2.0.4 OS 版本:OEL5.8 在一次Oracle的Dat ...
- [转帖]oracle 11g 分区表创建(自动按年、月、日分区)
https://www.cnblogs.com/yuxiaole/p/9809294.html 前言:工作中有一张表一年会增长100多万的数据,量虽然不大,可是表字段多,所以一年下来也会达到 1G ...
- Python学习之二:不同数据库相同表是否相同的比较方法
摘要 昨天学习了使用python进行数据库主键异常的查看. 当时想我们有跨数据库的数据同步场景. 对应的我可以对不同数据库的相同表的核心字段进行对比. 这样的话能够极大的提高工作效率. 我之前写过很长 ...
- [转帖]shell 实现行转列、列转行的几种方法
目录 shell 实现行转列.列转行的几种方法 awk 行转列 xargs 行转列 tr 列转行 参考资料 shell 实现行转列.列转行的几种方法 awk 行转列 以空格为分隔符 awk -F &q ...
- [转帖] Linux文本命令技巧(下)
https://www.cnblogs.com/codelogs/p/16060108.html 简介# 前一篇介绍了Linux中一些基本的文本命令与使用技巧,但是结合场景过少,本篇结合工作中一些常见 ...
- 物联网浏览器(IoTBrowser)-Web串口自定义开发
物联网浏览器(IoTBrowser)-Web串口自定义开发 工控系统中绝大部分硬件使用串口通讯,不论是原始串口通讯协议还是基于串口的Modbus-RTU协议,在代码成面都是使用System.IO.Po ...
- XJTU少年班+自动化钱学森班+电气工程辅修专业课笔记合集
通过百度网盘分享的文件:笔记整理链接:https://pan.baidu.com/s/1BrHQ1EqvlQlbWqpD5h_6Sg?pwd=shsg 提取码:shsg复制这段内容打开「百度网盘APP ...
- 【图论,网络流】CF1525F Goblins And Gnomes
Problem Link 你在打怪.你有一个 \(n\) 个点 \(m\) 条边的 DAG,接下来会有 \(k\) 波怪来袭,第 \(i\) 波怪有 \(i\) 个,它们会各自选择走一条路径,要求它们 ...
- 【计数,DP】CF1081G Mergesort Strikes Back
Problem Link 现有一归并排序算法,但是算法很天才,设了个递归深度上限,如果递归深度到达 \(k\) 则立即返回.其它部分都和正常归并排序一样,递归中点是 \(\lfloor (l+r)/2 ...