1.一般通信
用WPF实现了一下服务端,和一般的TCP通信一样。
最早以前实现过Unity(Webgl平台)里面用WebSocket连接C#的TCP服务端的功能。
网页中的WebSocket是浏览器本身支持的功能。
本来担心cors问题,结果发现:“webSocket本身不存在跨域问题,所以我们可以利用webSocket来进行非同源之间的通信。”
Unity里面的WebSocket直接使用BestHttp插件里面的场景测试。
打包到网页(webgl)中也没问题。
发现有个socket.io:
socket.io是对websocket的分装。因为不是所有的浏览器都可以支持websocket。如果浏览器支持websocket,那么socket.io就等同于websocket。socket.io还用到了其它的技术来模拟websocket,所以当你是用socket.io的时候,不管浏览器是否支持websocket,你都可以实现异步操作。当然如果你的客户端是用了socket.io,server端也必须对应使用。
2.获取图片、视频
H5Stream里面的ws的地址:
ws://localhost:8085/api/v1/h5swsapi?token=token1&profile=main&session=c1782caf-b670-42d8-ba90-2244d0b0ee83
用该地址在上面的网页中测试,结果:
收到一串的object Blob对象(evt.data)。
改造上面的简单发送字符串的服务端,添加发送图片和视频,本质上都是发送byte[]。
发现,发送的bytes内容不会被分开,发送、接收都是一个块。
接收图片,参考:Image Transmission between a HTML5 WebSocket Server and a Web Client
function drawImage(data){
var imageWidth = 883, imageHeight = 549; // hardcoded width & height.
var byteArray = new Uint8Array(data);
var canvas = document.createElement('canvas');
canvas.height = imageWidth;
canvas.width = imageHeight;
var ctx = canvas.getContext('2d');
var imageData = ctx.getImageData(0, 0, imageWidth, imageHeight); // total size: imageWidth * imageHeight * 4; color format BGRA
var dataLen = imageData.data.length;
for (var i = 0; i < dataLen; i++)
{
imageData.data[i] = byteArray[i];
}
ctx.putImageData(imageData, 0, 0);
// create a new element and add it to div
var image = document.createElement('img');
image.width = imageWidth;
image.height = imageHeight;
image.src = canvas.toDataURL();
var div = document.getElementById('imgDev1');
div.appendChild(image);
}
1.获取数据大小
使用上面参考的代码,不行
var byteArray = new Uint8Array(evt.data);
length=byteArray.length;
这个length是0。????
在其他地方(https://oomake.com/question/3732628)看到个data.size,再打印一下,发现evt.data就是个Blob对象。
2.读取Blob内容
if(data instanceof Blob){ //[object Blob]
length=data.size;
var reader = new FileReader();
reader.onload = () => {
console.log("Result length: " + reader.result.length);
console.log("Result content: " + reader.result);
};
reader.readAsText(data);
}
通过FileReader的readAsText()读取,能够看出这是一个png图片和一个H.264视频文件。
改为前面的H5Stream的ws地址,结果
前面3次收到的数据量都是31,24,723,第4次是6w多,后面都是1w多。
改成readAsArrayBuffer
if(data instanceof Blob){ //[object Blob]
length=data.size;
var reader = new FileReader();
reader.onload = () => {
console.log(reader);
console.log(reader.result);
console.log("Result length: " + reader.result.byteLength);
console.log("Result content: " + reader.result);
console.log(reader.result[0]);//读不出来
var byteArray = new Uint8Array(reader.result);
console.log(byteArray);
console.log(byteArray[0]);
//drawImage(reader.result);//转换成图像
};
reader.readAsArrayBuffer(data);
//reader.readAsArrayBuffer(data);
}
3.转换图片
经过FileReader.readAsArrayBuffer能够和上面的drawImage接上了,但是,结果不如意。
本来怀疑是长宽和图片一样,结果还是不行。总之,这个作者(Image Transmission between a HTML5 WebSocket Server and a Web Client)写的代码可能有问题,可能以前那时是可以的吧。
用他评论里面的代码测试了一下,可以。
function drawImage(data){
var bytes = new Uint8Array(data);
var binary= "";
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] )
}
var img = document.getElementById("img1");
img.src = "https://img-blog.csdnimg.cn/2022010705184285717.png"+window.btoa( binary );//png,jpg都没有关系
}
<body>
<form id="sendForm">
<input id="sendText" placeholder="Text to send" />
</form>
<pre id="incomming"></pre>
<div>
<div id="imgDev1"></div>
</div>
<img src="" id="img1"/>
</body>
另外查到一段代码
<img src="" id="img"/>
<script>
ws = new WebSocket("ws://192.168.0.171:1235");
ws.onopen = function () {
alert("连接成功");
ws.send('tom');
alert("给服务端发送一个字符串:tom");
}
ws.onmessage = function (e) {
document.getElementById('img').src = 'data:image/gif;'+e.data;
}
</script>
结果不行
我的代码是
ws.onmessage = function (evt) {
count=count+1;
if(count>10){
console.log('close!!:'+count);
ws.close();
}
//console.log(evt);
var data=evt.data;
console.log(data);
var length=data.length;
if(data instanceof Blob){ //[object Blob]
length=data.size;
document.getElementById('img1').src = 'data:image/png;'+data;
}
inc.innerHTML += "receive:"+data
+' type:'+typeof(data)
+' length:'+length
+ '<br/>';
};
整理一下,下面的代码就行一个下午的成果。学习以一下websocket,从Blob中读取图片。
ws.onmessage = function (evt) {
count=count+1;
if(count>10){
console.log('close!!:'+count);
ws.close();
}
//console.log(evt);
var data=evt.data;
console.log(data);
var length=data.length;
if(data instanceof Blob){ //[object Blob]
length=data.size;
loadImage('img1',data);
}
inc.innerHTML += "receive:"+data
+' type:'+typeof(data)
+' length:'+length
+ '<br/>';
};
function getImageString(arrayBuffer){
var bytes = new Uint8Array(arrayBuffer);
var binary= "";
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] )
}
var src="https://img-blog.csdnimg.cn/2022010705184285717.png"+window.btoa( binary );//png,jpg都没有关系
return src;
}
function loadImage(imgId,data){
var reader = new FileReader();
reader.onload = () => {
var img = document.getElementById(imgId);
img.src = getImageString(reader.result);
};
reader.readAsArrayBuffer(data);
}
-----------------------------------------------------------------------------------------
前面的Image Transmission between a HTML5 WebSocket Server and a Web Client没看仔细,少了一段代码
ws.binaryType = "arraybuffer";
改一下,兼容设置和不设置binaryType。
//To receive the image as ArrayBuffer on the client side, you have to specify the binaryType after creating a WebSocket:
ws.binaryType = "arraybuffer";//有了这个,就不用FileReader读取Blob的内容了。
// when data is comming from the server, this metod is called
ws.onmessage = function (evt) {
count=count+1;
if(count>10){
console.log('close!!:'+count);
ws.close();
}
//console.log(evt);
var data=evt.data;
console.log(data);
var length=data.length;
if(data instanceof Blob){ //[object Blob]
length=data.size;
loadImage('img1',data);
} else if(data instanceof ArrayBuffer){ //加上ws.binaryType = "arraybuffer";
length=data.byteLength;
var img = document.getElementById('img1');
img.src = getImageString(data);
}
inc.innerHTML += "receive:"+data
+' type:'+typeof(data)
+' length:'+length
+ '<br/>';
};