android与workerman 数据传输问题

ycsi

我在android客户端通过inputstream读取音频文件,通过websocket发送二进制流,请问服务器端的同样websocket协议的workerman服务端怎么将接受到的数据转化为音频文件呢?

阅读 6742
6个回答

walkor

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;

  • 暂无评论
ycsi

我客户端用的是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的时候会出现文件损坏无法打开的问题。

  • 暂无评论
walkor

服务端要以追加的方式写文件。不然数据就写乱了

简单的方法是用 file_put_contents 写数据

  • 暂无评论
ycsi

现在可以传音频文件了。但是传图片的话,图片不压缩会传不了,连接会被关闭,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就传不了图片。。结果图片严重失真。

另外十分感谢您之前能够耐心回答我的问题!谢谢!

  • 暂无评论
walkor

图片多少字节?

  • 暂无评论
ycsi

图片1M左右的,网上找了一个不错的压缩图片的方法,把图片压缩到100kb以内就很好传啦~

  • 暂无评论