FileReceiverDemo.php 2.9 KB

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