FileReceiverDemo.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. require_once WORKERMAN_ROOT_DIR . 'man/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. $message_type = $message_data['message_type'];
  45. // 数据没接收完,继续接收$message_len - $recv_len 字节
  46. if($message_len > $recv_len)
  47. {
  48. return $message_len - $recv_len;
  49. }
  50. // 数据接收完毕
  51. return 0;
  52. }
  53. /**
  54. * 处理业务
  55. * @see Worker::dealProcess()
  56. */
  57. public function dealProcess($buffer)
  58. {
  59. // unsigned int + unsigned char 共5字节
  60. $head_len = 5;
  61. // 解包
  62. $message_data = unpack("Nmessage_len/Cmessage_type", $buffer);
  63. $message_len = $message_data['message_len'];
  64. $message_type = $message_data['message_type'];
  65. // 获得文件二进制数据
  66. $file_bin_buffer = substr($buffer, $head_len, $message_len - $head_len);
  67. // 保存数据到/tmp/workerman.recv.xxxxx
  68. file_put_contents('/tmp/workerman.recv.'.time().'.'.self::getExt($message_type), $file_bin_buffer);
  69. // 回复客户端 成功
  70. $response_message_body = "上传成功";
  71. // 255表示回包
  72. $response_message_type = 255;
  73. $this->sendToClient(pack("NC", $head_len+strlen($response_message_body), $response_message_type).$response_message_body);
  74. }
  75. /**
  76. * 根据message_type获得文件后缀
  77. * @param int $message_type
  78. * @return string 如:jpg gif ...
  79. */
  80. protected static function getExt($message_type)
  81. {
  82. return isset(self::$fileTypeMap[$message_type]) ? self::$fileTypeMap[$message_type] : 'unknown';
  83. }
  84. }