我在android客户端通过inputstream读取音频文件,通过websocket发送二进制流,请问服务器端的同样websocket协议的workerman服务端怎么将接受到的数据转化为音频文件呢?
websocket向服务端传输二进制时,需要在js中设置binaryType属性为arraybuffer。这个是浏览器websocket协议的规则。安卓的websocket库应该也要遵守这个规则,看下是否有设置binaryType的接口
ws = new WebSocket("ws://...."); ws.binaryType = "arraybuffer"; .....
同样,服务端如果要向客户端通过websocket发送二进制数据,需要设置服务端的binaryType,浏览器才能正常解析。不设置默认是utf8文本格式传输。
use \Workerman\Protocols\Websocket; // 默认值是 Websocket::BINARY_TYPE_BLOB; 也就是以utf8传输,根据需要可设置成二进制:BINARY_TYPE_ARRAYBUFFER $connection->websocketType = Websocket::BINARY_TYPE_ARRAYBUFFER;
我客户端用的是atudobahn库,里面没有binaryType的属性,有sendBinaryMessage()的方法。下面是源代码:
android客户端:
mConnection.connect(wsuri, new WebSocketHandler() { @Override public void onOpen() { Log.d(TAG, "Status: Connected to " + wsuri); InputStream is = null; try { is = new FileInputStream(_file); } catch (FileNotFoundException e) { e.printStackTrace(); } byte[] bytes = new byte; int len = 0; try { while((len=is.read(bytes))!=-1) { Log.d(TAG, "senBinaryMessage: " + bytes); mConnection.sendBinaryMessage(bytes); } is.close(); } catch (IOException e) { e.printStackTrace(); } }
服务器端:
$worker->onMessage = function($connection, $data) { echo "$data\n\n\n"; $filePath="/Users/myname/Desktop/php/"; if (!file_exists($filePath)){ mkdir($filePath , 0777); } $name=$filePath.'voice'.'.amr'; $fp = fopen ($name,"a"); if (fwrite ($fp,$data)){ echo "写入成功"; } else { fclose ($fp); echo "写入失败!"; } };
传txt文件没问题(我把$name=$filePath.'voice'.'.amr';改成$name=$filePath.'voice'.'.txt';)
但是传amr的时候会出现文件损坏无法打开的问题。
服务端要以追加的方式写文件。不然数据就写乱了
简单的方法是用 file_put_contents 写数据
现在可以传音频文件了。但是传图片的话,图片不压缩会传不了,连接会被关闭,websocket的send方法有限制传输二进制流的大小吗?
服务器代码:
Bitmap btp = BitmapFactory.decodeStream(inputStream); ByteArrayOutputStream baos = new ByteArrayOutputStream(); btp.compress(Bitmap.CompressFormat.JPEG, 100, baos); mConnection.sendBinaryMessage(baos.toByteArray());
客户端代码:
$worker->onConnect = function($connection) { echo "new connection from ip " . $connection->getRemoteIp() . "\n"; }; $worker->onMessage = function($connection, $data) { var_dump($data); file_put_contents("/Users/myname/Desktop/php/test.jpg",$data); $connection->send('receive success'); }; $worker->onClose = function($connection) { echo "connection closed\n"; };
服务器还是会返回:
new connection from ip 192.168.0.3 connection closed
但是我把客户端的压缩率改一下 btp.compress(Bitmap.CompressFormat.JPEG, 100, baos); 把100改成0-3的值,手机拍摄的照片就能传,大于3就传不了图片。。结果图片严重失真。
另外十分感谢您之前能够耐心回答我的问题!谢谢!
图片多少字节?
图片1M左右的,网上找了一个不错的压缩图片的方法,把图片压缩到100kb以内就很好传啦~
websocket向服务端传输二进制时,需要在js中设置binaryType属性为arraybuffer。这个是浏览器websocket协议的规则。安卓的websocket库应该也要遵守这个规则,看下是否有设置binaryType的接口
ws = new WebSocket("ws://....");
ws.binaryType = "arraybuffer";
.....
同样,服务端如果要向客户端通过websocket发送二进制数据,需要设置服务端的binaryType,浏览器才能正常解析。不设置默认是utf8文本格式传输。
use \Workerman\Protocols\Websocket;
// 默认值是 Websocket::BINARY_TYPE_BLOB; 也就是以utf8传输,根据需要可设置成二进制:BINARY_TYPE_ARRAYBUFFER
$connection->websocketType = Websocket::BINARY_TYPE_ARRAYBUFFER;
我客户端用的是atudobahn库,里面没有binaryType的属性,有sendBinaryMessage()的方法。下面是源代码:
android客户端:
服务器端:
传txt文件没问题(我把$name=$filePath.'voice'.'.amr';改成$name=$filePath.'voice'.'.txt';)
但是传amr的时候会出现文件损坏无法打开的问题。
服务端要以追加的方式写文件。不然数据就写乱了
简单的方法是用 file_put_contents 写数据
现在可以传音频文件了。但是传图片的话,图片不压缩会传不了,连接会被关闭,websocket的send方法有限制传输二进制流的大小吗?
服务器代码:
客户端代码:
服务器还是会返回:
但是我把客户端的压缩率改一下
btp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
把100改成0-3的值,手机拍摄的照片就能传,大于3就传不了图片。。结果图片严重失真。
另外十分感谢您之前能够耐心回答我的问题!谢谢!
图片多少字节?
图片1M左右的,网上找了一个不错的压缩图片的方法,把图片压缩到100kb以内就很好传啦~