FileReceiverDemo.php 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. require_once WORKERMAN_ROOT_DIR . 'Core/SocketWorker.php';
  3. /**
  4. * 二进制协议,接收文件demo
  5. * @author walkor <worker-man@qq.com>
  6. */
  7. class FileReceiverDemo extends Man\Core\SocketWorker
  8. {
  9. /**
  10. * message_type 到 后缀名的映射
  11. * @var array
  12. */
  13. protected static $fileTypeMap = array(
  14. 1 => 'jpg',
  15. 2 => 'png',
  16. 3 => 'gif',
  17. 4 => 'mp3',
  18. );
  19. /**
  20. * 确定包是否完整
  21. * 二进制协议
  22. * buffer
  23. * {
  24. * unsigned int message_len; // 整个包的长度
  25. * unsigned char message_type; // 消息类型 自己定义 如:1图片数据 2声音数据....
  26. * char[message_len - 5] message_body; // 这部分是文件原始二进制数据
  27. * }
  28. * @see Worker::dealInput()
  29. */
  30. public function dealInput($buffer)
  31. {
  32. // 已经接收到的数据的长度
  33. $recv_len = strlen($buffer);
  34. // unsigned int + unsigned char 共5字节
  35. $head_len = 5;
  36. // 数据头没接收全?,继续接收
  37. if($recv_len < $head_len)
  38. {
  39. return $head_len - $recv_len;
  40. }
  41. // 根据message_len判断当前数据是否接收完毕
  42. $message_data = unpack("Nmessage_len/Cmessage_type", $buffer);
  43. $message_len = $message_data['message_len'];
  44. if($message_len > 102400)
  45. {
  46. return false;
  47. }
  48. $message_type = $message_data['message_type'];
  49. // 数据没接收完,继续接收$message_len - $recv_len 字节
  50. if($message_len > $recv_len)
  51. {
  52. return $message_len - $recv_len;
  53. }
  54. // 数据接收完毕
  55. return 0;
  56. }
  57. /**
  58. * 处理业务
  59. * @see Worker::dealProcess()
  60. */
  61. public function dealProcess($buffer)
  62. {
  63. // unsigned int + unsigned char 共5字节
  64. $head_len = 5;
  65. // 解包
  66. $message_data = unpack("Nmessage_len/Cmessage_type", $buffer);
  67. $message_len = $message_data['message_len'];
  68. $message_type = $message_data['message_type'];
  69. // 获得文件二进制数据
  70. $file_bin_buffer = substr($buffer, $head_len, $message_len - $head_len);
  71. // 保存数据到/tmp/workerman.recv.xxxxx
  72. $file_path = '/tmp/workerman.recv.'.time().'.'.self::getExt($message_type);
  73. file_put_contents($file_path, $file_bin_buffer);
  74. // 回复客户端 成功
  75. $response_message_body = "上传成功 位置:$file_path";
  76. // 255表示回包
  77. $response_message_type = 255;
  78. $this->sendToClient(pack("NC", $head_len+strlen($response_message_body), $response_message_type).$response_message_body);
  79. }
  80. /**
  81. * 根据message_type获得文件后缀
  82. * @param int $message_type
  83. * @return string 如:jpg gif ...
  84. */
  85. protected static function getExt($message_type)
  86. {
  87. return isset(self::$fileTypeMap[$message_type]) ? self::$fileTypeMap[$message_type] : 'unknown';
  88. }
  89. }